Annotation of 43BSD/undoc/copyout.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <sys/param.h>
        !             3: #include <sys/systm.h>
        !             4: #include <sys/dir.h>
        !             5: #include <sys/user.h>
        !             6: #include <sys/vm.h>
        !             7: #include <sys/proc.h>
        !             8: #include <sys/pte.h>
        !             9: #include <sys/cmap.h>
        !            10: #include <sys/inode.h>
        !            11: #include <sys/buf.h>
        !            12: #include <sys/text.h>
        !            13: #include <sys/ino.h>
        !            14: 
        !            15: struct buf *bread();
        !            16: struct buf b;
        !            17: char   bc[BSIZE];
        !            18: int    bflag;
        !            19: 
        !            20: main(argc, argv)
        !            21:        char *argv[];
        !            22: {
        !            23:        struct dinode di;
        !            24:        struct inode i;
        !            25:        struct proc p;
        !            26:        struct user u;
        !            27:        struct text x;
        !            28:        struct pte *pte;
        !            29:        int j,k,l;
        !            30: 
        !            31:        if (argc > 1 && !strcmp(argv[1], "-b"))
        !            32:                argc--, argv++, bflag++;
        !            33:        if (argc != 3) {
        !            34:                fprintf(stderr, "usage: copyout [ -b ] inum disk\n");
        !            35:                exit(1);
        !            36:        }
        !            37:        close(0);
        !            38:        if (open(argv[2], 0) != 0) {
        !            39:                perror(argv[2]);
        !            40:                exit(1);
        !            41:        }
        !            42:        lseek(0, itod(atoi(argv[1])) * BSIZE + itoo(atoi(argv[1])) * sizeof (di), 0);
        !            43:        if (read(0, &di, sizeof (di)) != sizeof (di)) {
        !            44:                fprintf(stderr, "error reading inode ");
        !            45:                perror(argv[1]);
        !            46:                exit(1);
        !            47:        }
        !            48:        i.i_dev = 0;
        !            49:        i.i_number = atoi(argv[1]);
        !            50:        i.i_flag = ILOCK;
        !            51:        i.i_count = 1;
        !            52:        i.i_un.i_lastr = 0;
        !            53:        i.i_mode = di.di_mode;
        !            54:        i.i_nlink = di.di_nlink;
        !            55:        i.i_uid = di.di_uid;
        !            56:        i.i_size = di.di_size;
        !            57:        l3tol(i.i_un.i_addr, di.di_addr, NADDR);
        !            58:        p.p_textp = &x;
        !            59:        x.x_iptr = &i;
        !            60:        b.b_un.b_addr = bc;
        !            61:        pte = (struct pte *)calloc(btoc(i.i_size), sizeof (struct pte));
        !            62:        if (pte == NULL) {
        !            63:                fprintf(stderr, "Not enough core for block pointers\n");
        !            64:                exit(1);
        !            65:        }
        !            66:        vinizfod(&p, pte, 0, (btoc(i.i_size)+(CLSIZE-1)) / CLSIZE);
        !            67:        l = i.i_size;
        !            68:        for (j = 0; j < (btoc(i.i_size)+(CLSIZE-1)) / CLSIZE; j++)
        !            69:                if (bflag)
        !            70:                        printf("#%d: block %d\n", j, pte[j].pg_pfnum);
        !            71:                else {
        !            72:                        k = imin(l, BSIZE);
        !            73:                        write(1, bread(0, pte[j].pg_pfnum)->b_un.b_words, k);
        !            74:                        brelse(&b);
        !            75:                        l -= BSIZE;
        !            76:                }
        !            77:        exit(0);
        !            78: }
        !            79: 
        !            80: int    bused;
        !            81: 
        !            82: struct buf *
        !            83: bread(dev, blk)
        !            84: {
        !            85: 
        !            86:        if (bused)
        !            87:                abort();
        !            88:        bused = 1;
        !            89:        printf("getblk %x\n", blk);
        !            90:        lseek(0, blk * BSIZE, 0);
        !            91:        if (read(0, b.b_un.b_addr, BSIZE) != BSIZE) {
        !            92:                printf("block %d: ", blk);
        !            93:                perror("bread");
        !            94:        }
        !            95:        return (&b);
        !            96: }
        !            97: 
        !            98: brelse(bp)
        !            99: struct buf *bp;
        !           100: {
        !           101: 
        !           102:        if (bp != &b)
        !           103:                abort();
        !           104:        bused = 0;
        !           105: }
        !           106: 
        !           107: struct buf *vbmap();
        !           108: /*
        !           109:  * Initialize the page tables for paging from an inode,
        !           110:  * by scouring up the indirect blocks in order.
        !           111:  */
        !           112: vinizfod(p, pte, bstart, count)
        !           113:        struct proc *p;
        !           114:        register struct pte *pte;
        !           115:        daddr_t bstart;
        !           116:        int count;
        !           117: {
        !           118:        register struct inode *ip = p->p_textp->x_iptr;
        !           119:        register int i;
        !           120:        struct buf *bp;
        !           121:        int indx;
        !           122:        register daddr_t *pp;
        !           123: 
        !           124:        while (count > 0) {
        !           125:                if (bstart < NADDR - 3) {
        !           126:                        pte++->pg_pfnum = ip->i_un.i_addr[bstart];
        !           127:                        bstart++;
        !           128:                        count--;
        !           129:                } else {
        !           130:                        bp = vbmap(ip, bstart);
        !           131:                        indx = (bstart - (NADDR - 3)) % NINDIR;
        !           132:                        i = imin(NINDIR - indx, count);
        !           133:                        bstart += i;
        !           134:                        count -= i;
        !           135:                        if (bp) {
        !           136:                                pp = &bp->b_un.b_daddr[indx];
        !           137:                                do
        !           138:                                        pte++->pg_pfnum = *pp++;
        !           139:                                while (--i > 0);
        !           140:                                brelse(bp);
        !           141:                        } else
        !           142:                                pte += i;
        !           143:                }
        !           144:        }
        !           145: }
        !           146: 
        !           147: /*
        !           148:  * Vbmap returns a block full of indirect pointers for a given block offset
        !           149:  * in a file.  It returns 0 if a missing address block was encountered,
        !           150:  * in which case the pages can be normal zfod pages.
        !           151:  */
        !           152: struct buf *
        !           153: vbmap(ip, bn)
        !           154: register struct inode *ip;
        !           155: daddr_t bn;
        !           156: {
        !           157:        register i;
        !           158:        struct buf *bp;
        !           159:        int j, sh;
        !           160:        daddr_t nb;
        !           161:        dev_t dev = ip->i_dev;
        !           162: 
        !           163:        if (bn < NADDR-3)
        !           164:                panic("vbmap");
        !           165: 
        !           166:        /*
        !           167:         * addresses NADDR-3, NADDR-2, and NADDR-1
        !           168:         * have single, double, triple indirect blocks.
        !           169:         * the first step is to determine
        !           170:         * how many levels of indirection.
        !           171:         */
        !           172:        sh = 0;
        !           173:        nb = 1;
        !           174:        bn -= NADDR-3;
        !           175:        for (j = 3; j > 0; j--) {
        !           176:                sh += NSHIFT;
        !           177:                nb <<= NSHIFT;
        !           178:                if(bn < nb)
        !           179:                        break;
        !           180:                bn -= nb;
        !           181:        }
        !           182:        if (j == 0)
        !           183:                goto noblk;
        !           184: 
        !           185:        /*
        !           186:         * fetch the address from the inode
        !           187:         */
        !           188:        nb = ip->i_un.i_addr[NADDR-j];
        !           189: 
        !           190:        /*
        !           191:         * fetch through the indirect blocks
        !           192:         */
        !           193:        for (;;) {
        !           194:                if (nb == 0)
        !           195:                        return ((daddr_t)0);
        !           196:                bp = bread(dev, nb);
        !           197:                if (bp->b_flags & B_ERROR) {
        !           198:                        brelse(bp);
        !           199:                        goto noblk;
        !           200:                }
        !           201:                if (j == 3)
        !           202:                        break;
        !           203:                j++;
        !           204:                sh -= NSHIFT;
        !           205:                i = (bn>>sh) & NMASK;
        !           206:                nb = bp->b_un.b_daddr[i];
        !           207:                brelse(bp);
        !           208:                if (nb == 0)
        !           209:                        goto noblk;
        !           210:        }
        !           211:        return (bp);
        !           212: 
        !           213: noblk:
        !           214:        return ((struct buf *)0);
        !           215: }
        !           216: 
        !           217: imin(a,b)
        !           218: {
        !           219:        return (a<b?a:b);
        !           220: }
        !           221: 
        !           222: panic(cp)
        !           223: {
        !           224:        printf(cp);
        !           225:        abort();
        !           226: }
        !           227: 
        !           228: char vmmap[1];
        !           229: char version[1];

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.