#!/bin/rc # # command: /bin/boddle /sys/src/cmd/tapefs tapefs # srcdir: /sys/src/cmd/tapefs # version: 811368396 # date: Sun Sep 17 21:06:36 BST 1995 # myname=$0 doextract=no fn usage{ echo $myname: usage: $myname '[-X] [src-directory]' >[1=2] exit usage } fn sigint{ rm -rf 811368396 exit interrupt } while(~ $1 -*){ switch($1){ case -X doextract=yes case -* usage } shift } switch($#*){ case 0 srcdir=/sys/src/cmd/tapefs case 1 srcdir=$1 case * usage } if(! ~ $doextract yes){ echo This shell file contains a bundle of diffs representing changes echo to original source files in the Plan 9 distribution. It will run echo against the files in echo ' ' $srcdir echo '(unless overridden by the optional source directory argument)' echo and create a directory 811368396 containing the updated files. echo It will NOT automatically update the original files. echo echo Invoke with argument -X to perform the actual extraction. exit 0 } rm -rf 811368396 mkdir 811368396 target=811368396/fs.c echo -n '811368396/fs.c: ' if(! test -f $srcdir/fs.c || ! test -r $srcdir/fs.c){ echo $srcdir/fs.c unreadable exit unreadable } sum=`{sum < $srcdir/fs.c} if(! ~ 07c323789051 $sum(1)^$sum(2)){ echo $srcdir/fs.c is not the original distribution file exit original } cp $srcdir/fs.c 811368396/fs.c ed 811368396/fs.c >/dev/null >[2=1] <<'//GO.SYSIN DD VADIM fs.c' 463a buf[0] = '\0'; . wq //GO.SYSIN DD VADIM fs.c sum=`{sum < 811368396/fs.c} if(~ ce8b16119067 $sum(1)^$sum(2)) echo if not{ echo 811368396/fs.c checksum error creating updated file exit checksum } target=811368396/mkfile echo -n '811368396/mkfile: ' if(! test -f $srcdir/mkfile || ! test -r $srcdir/mkfile){ echo $srcdir/mkfile unreadable exit unreadable } sum=`{sum < $srcdir/mkfile} if(! ~ dd3ed50b180 $sum(1)^$sum(2)){ echo $srcdir/mkfile is not the original distribution file exit original } cp $srcdir/mkfile 811368396/mkfile ed 811368396/mkfile >/dev/null >[2=1] <<'//GO.SYSIN DD VADIM mkfile' 5c TARG=tarfs tpfs v6fs 32vfs cpiofs tapfs v10fs ext2fs . wq //GO.SYSIN DD VADIM mkfile sum=`{sum < 811368396/mkfile} if(~ 82a1d279187 $sum(1)^$sum(2)) echo if not{ echo 811368396/mkfile checksum error creating updated file exit checksum } target=811368396/ext2fs.c echo -n '811368396/ext2fs.c (new): ' cat > 811368396/ext2fs.c >[2]/dev/null <<'//GO.SYSIN DD VADIM tapefs' /* * Linux ext2fs */ #include #include #include #include #include "tapefs.h" /* * super block */ #define EXT2MAGIC 0xEF53 #define EXT2SUPERB 1024 /* bytes */ #define VSUPERB 1 /* blocks */ #define EXT2_MIN_FRAG_SIZE 1024 #define EXT2_MAX_FRAG_SIZE 4096 #define EXT2_MIN_BLOCK_SIZE 1024 #define EXT2_MAX_BLOCK_SIZE 4096 struct ext2superb { uchar ninode[4]; uchar nblock[4]; uchar nrblock[4]; /* Reserved blocks count */ uchar nfree[4]; /* Free blocks count */ uchar nifree[4]; /* Free inodes count */ uchar datab[4]; /* first data block */ uchar log_block_size[4]; /* log2(blocksize/MIN_BLOCK_SIZE) */ uchar log_frag_size[4]; /* log2(fragsize/MIN_FRAG_SIZE) */ uchar blockpg[4]; /* # Blocks per group */ uchar fragpg[4]; /* # Fragments per group */ uchar inopg[4]; /* # Inodes per group */ uchar mtime[4]; /* Mount time */ uchar wtime[4]; /* Write time */ uchar mnt_count[2]; /* Mount count */ uchar max_mnt_count[2]; /* Maximal mount count */ uchar magic[2]; /* Magic signature */ uchar state[2]; /* File system state */ uchar errors[2]; /* Behaviour when detecting errors */ uchar pad[2]; uchar lastcheck[4]; /* time of last check */ uchar checkinterval[4]; /* max. time between checks */ uchar creator_os[4]; /* OS */ uchar rev_level[4]; /* Revision level */ uchar def_resuid[2]; /* Default uid for reserved blocks */ uchar def_resgid[2]; /* Default gid for reserved blocks */ uchar reserved[235][4]; /* Padding to the end of the block */ }; /* * ext2fs group descriptor */ struct ext2group { uchar blockmap[4]; uchar inodemap[4]; uchar inodetab[4]; /* address of inode table */ uchar nfree[2]; uchar nifree[2]; uchar ndir[2]; uchar pad[2]; uchar reserved[3][4]; }; #define DESCPERBLK (blocksize/sizeof(struct ext2group)) #define EXT2_INODES_PER_GROUP(s) inopg /* * ext2fs disk inode */ #define VFMT 0170000 #define VIFSOCK 0140000 #define VIFLNK 0120000 #define VIFREG 0100000 #define VIFDIR 0040000 #define VIFCHR 0020000 #define VIFBLK 0060000 #define VIFIFO 0010000 #define VISUID 0004000 #define VISGID 0002000 #define VISVTX 0001000 #define VMODE 0777 #define VROOT 2 /* root inode */ #define VNAMELEN 255 #define MAXBLSIZE 16384 #define BLSIZE blocksize #define LINOPB (BLSIZE/sizeof(struct ext2dinode)) #define LNINDIR (BLSIZE/4) #define NDIRBLOCKS 12 #define INDBLOCK NDIRBLOCKS #define IND2BLOCK (INDBLOCK+1) #define IND3BLOCK (IND2BLOCK+1) #define VNBLOCKS (IND3BLOCK+1) #define VNADDR VNBLOCKS struct ext2dinode { uchar mode[2]; /* File mode */ uchar uid[2]; /* Owner Uid */ uchar size[4]; /* Size in bytes */ uchar atime[4]; /* Access time */ uchar ctime[4]; /* Creation time */ uchar mtime[4]; /* Modification time */ uchar dtime[4]; /* Deletion Time */ uchar gid[2]; /* Group Id */ uchar nlinks[2]; uchar blocks[4]; /* Blocks count */ uchar flags[4]; /* File flags */ uchar reserved1[4]; /* O/S dependent */ uchar block[VNBLOCKS][4];/* Pointers to blocks */ uchar version[4]; /* File version (for NFS) */ uchar file_acl[4]; /* File ACL */ uchar dir_acl[4]; /* Directory ACL */ uchar faddr[4]; /* Fragment address */ uchar frag; /* fragment number */ uchar fsize; /* fragment size */ ushort pad1; uchar reserved2[2][4]; }; struct ext2dir { uchar ino[4]; uchar reclen[2]; uchar namelen[2]; char name[VNAMELEN]; }; int tapefile; int chatty = 0; static struct ext2superb superb; static int blocksize; static int fragsize; static int inopb; static int inopg; /* inodes per group */ static int ngroups; static int *inotab; Fileinf iget(int ino); long bmap(Ram *r, long bno); void getblk(Ram *r, long bno, char *buf); void populate(char *name) { Fileinf f; char *buf; struct ext2group *gp; int bpg, i, j; replete = 0; tapefile = open(name, OREAD); if (tapefile<0) error("Can't open argument file"); seek(tapefile, EXT2SUPERB, 0); if(read(tapefile, &superb, sizeof(superb)) != sizeof(superb)) error("can't read super block"); if(g2byte(superb.magic) != EXT2MAGIC){ werrstr("bad magic number #%ux", g2byte(superb.magic)); error("not a linux ext2fs"); } blocksize = EXT2_MIN_BLOCK_SIZE << g4byte(superb.log_block_size); fragsize = EXT2_MIN_FRAG_SIZE << g4byte(superb.log_frag_size); inopb = blocksize/sizeof(struct ext2dinode); inopg = g4byte(superb.inopg); bpg = g4byte(superb.blockpg); ngroups = (g4byte(superb.nblock) - g4byte(superb.datab) + bpg - 1)/bpg; if(chatty) { fprint(2, "blocksize=%ld bytes, fragsize = %ld bytes, inopb = %ld\n", blocksize, fragsize, inopb); fprint(2, "bpg = %d, ngroups = %d\n", bpg, ngroups); fprint(2, "descperblock = %d\n", DESCPERBLK); } inotab = malloc(ngroups*sizeof(*inotab)); buf = malloc(blocksize); if(buf == 0 || inotab == 0) error("out of memory"); for(i=0; iinodetab); } free(buf); if(chatty) { for(i=0; iperm = f.mode; ram->mtime = f.mdate; ram->data = f.addr; ram->ndata = f.size; } void popdir(Ram *r) { int i, ino, rlen, nlen; char *cp; struct ext2dir *dp; Fileinf f; char name[VNAMELEN+1]; cp = 0; for (i=0; indata; i+=rlen) { if (i%BLSIZE==0) cp = doread(r, i, BLSIZE); dp = (struct ext2dir *)(cp+i%BLSIZE); rlen = g2byte(dp->reclen); ino = g4byte(dp->ino); nlen = g2byte(dp->namelen); if (ino==0 || nlen<=0) continue; if (strcmp(dp->name, ".")==0 || strcmp(dp->name, "..")==0) continue; f = iget(ino); if(nlen > VNAMELEN) nlen = VNAMELEN; strncpy(name, dp->name, nlen); name[nlen] = '\0'; f.name = name; popfile(r, f); } r->replete = 1; } void dotrunc(Ram *r) { USED(r); } void docreate(Ram *r) { USED(r); } char * doread(Ram *r, long off, long cnt) { static char buf[MAXFDATA+MAXBLSIZE]; int bno, i; if (r->perm & CHEXCL) { /* short symbolic link contents are in the inode */ memmove(buf, r->data, VNADDR*4); return buf+off; } bno = off/BLSIZE; off -= bno*BLSIZE; if (cnt>MAXFDATA) error("count too large"); if (off) cnt += BLSIZE-off; i = 0; while (cnt>0) { getblk(r, bno, &buf[i*BLSIZE]); cnt -= BLSIZE; bno++; i++; } return buf+off; } void dowrite(Ram *r, char *buf, long off, long cnt) { USED(r); USED(buf); USED(off); USED(cnt); } int dopermw(Ram *r) { USED(r); return 0; } /* * fetch an i-node * -- no sanity check for now * -- magic inode-to-disk-block stuff here */ Fileinf iget(int ino) { char buf[MAXBLSIZE]; struct ext2dinode *dp; long mode, i, g, bno; Fileinf f; g = (ino-1)/inopg; if(g < 0 || g >= ngroups) { werrstr("group too big, ino %ld\n", ino); error("inconsistency"); } bno = inotab[g] + ((ino-1)%inopg)/LINOPB; seek(tapefile, bno*blocksize, 0); if (read(tapefile, buf, blocksize) != blocksize) error("Can't read inode"); dp = ((struct ext2dinode *)buf) + ((ino-1)%LINOPB); mode = g2byte(dp->mode); f.size = g4byte(dp->size); f.addr = emalloc(VNADDR*sizeof(long)); for (i = 0; i < VNADDR; i++) ((long*)f.addr)[i] = g4byte(dp->block[i]); f.mode = mode & VMODE; switch(mode&VFMT) { case VIFDIR: f.mode |= CHDIR; break; case VIFCHR: case VIFBLK: case VIFSOCK: case VIFIFO: f.size = 0; break; case VIFLNK: /* a symbolic link will show its contents */ f.mode &= ~0111; if(g4byte(dp->blocks) == 0) f.mode |= CHEXCL; /* flag to doread: f.addr has the link's contents */ break; } f.uid = g2byte(dp->uid); f.gid = g2byte(dp->gid); f.mdate = g4byte(dp->mtime); if(chatty) fprint(2, "ino=%d group=%d bno=%d mode = %luo size = %ld uid=%d gid=%d\n", ino, g, bno, mode, f.size, f.uid, f.gid); return f; } void getblk(Ram *r, long bno, char *buf) { long dbno; if ((dbno = bmap(r, bno)) == 0) { memset(buf, 0, BLSIZE); return; } seek(tapefile, dbno*BLSIZE, 0); if (read(tapefile, buf, BLSIZE) != BLSIZE) error("bad read"); } /* * logical to physical block * only singly-indirect files for now */ long bmap(Ram *r, long bno) { static uchar indbuf[MAXBLSIZE/sizeof(long)][sizeof(long)]; ulong a; static ulong lasta = ~0; if (bno < VNADDR-3) return ((long*)r->data)[bno]; if (bno < VNADDR*LNINDIR) { a = ((long *)r->data)[(bno-(VNADDR-3))/LNINDIR+(VNADDR-3)]*BLSIZE; if(a != lasta) { seek(tapefile, a, 0); if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE) return 0; lasta = a; } return ((indbuf[(bno-(VNADDR-3))%LNINDIR][2]<<16) + (indbuf[(bno-(VNADDR-3))%LNINDIR][1]<<8) + indbuf[(bno-(VNADDR-3))%LNINDIR][0]); } return 0; } //GO.SYSIN DD VADIM tapefs sum=`{sum < 811368396/ext2fs.c} if(~ a7f8718c9990 $sum(1)^$sum(2)) echo if not{ echo 811368396/ext2fs.c checksum error extracting new file exit checksum }