Annotation of 42BSD/undoc/copyout.c, revision 1.1.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.