1bd389b36SDavid du Colombier /* 2bd389b36SDavid du Colombier * old (V6 and before) PDP-11 Unix filesystem 3bd389b36SDavid du Colombier */ 4bd389b36SDavid du Colombier #include <u.h> 5bd389b36SDavid du Colombier #include <libc.h> 6*219b2ee8SDavid du Colombier #include <auth.h> 7bd389b36SDavid du Colombier #include <fcall.h> 8bd389b36SDavid du Colombier #include "tapefs.h" 9bd389b36SDavid du Colombier 10bd389b36SDavid du Colombier /* 11bd389b36SDavid du Colombier * v6 disk inode 12bd389b36SDavid du Colombier */ 13bd389b36SDavid du Colombier #define V6NADDR 8 14bd389b36SDavid du Colombier #define V6FMT 0160000 15bd389b36SDavid du Colombier #define V6IFREG 0100000 16bd389b36SDavid du Colombier #define V6IFDIR 0140000 17bd389b36SDavid du Colombier #define V6IFCHR 0120000 18bd389b36SDavid du Colombier #define V6IFBLK 0160000 19bd389b36SDavid du Colombier #define V6MODE 0777 20bd389b36SDavid du Colombier #define V6LARGE 010000 21bd389b36SDavid du Colombier #define V6SUPERB 1 22bd389b36SDavid du Colombier #define V6ROOT 1 /* root inode */ 23bd389b36SDavid du Colombier #define V6NAMELEN 14 24bd389b36SDavid du Colombier #define BLSIZE 512 25bd389b36SDavid du Colombier #define LINOPB (BLSIZE/sizeof(struct v6dinode)) 26bd389b36SDavid du Colombier #define LNINDIR (BLSIZE/sizeof(unsigned short)) 27bd389b36SDavid du Colombier 28bd389b36SDavid du Colombier struct v6dinode { 29bd389b36SDavid du Colombier unsigned char flags[2]; 30bd389b36SDavid du Colombier unsigned char nlinks; 31bd389b36SDavid du Colombier unsigned char uid; 32bd389b36SDavid du Colombier unsigned char gid; 33bd389b36SDavid du Colombier unsigned char hisize; 34bd389b36SDavid du Colombier unsigned char losize[2]; 35bd389b36SDavid du Colombier unsigned char addr[V6NADDR][2]; 36bd389b36SDavid du Colombier unsigned char atime[4]; /* pdp-11 order */ 37bd389b36SDavid du Colombier unsigned char mtime[4]; /* pdp-11 order */ 38bd389b36SDavid du Colombier }; 39bd389b36SDavid du Colombier 40bd389b36SDavid du Colombier struct v6dir { 41bd389b36SDavid du Colombier uchar ino[2]; 42bd389b36SDavid du Colombier char name[V6NAMELEN]; 43bd389b36SDavid du Colombier }; 44bd389b36SDavid du Colombier 45bd389b36SDavid du Colombier int tapefile; 46bd389b36SDavid du Colombier Fileinf iget(int ino); 47bd389b36SDavid du Colombier long bmap(Ram *r, long bno); 48bd389b36SDavid du Colombier void getblk(Ram *r, long bno, char *buf); 49bd389b36SDavid du Colombier 50bd389b36SDavid du Colombier void 51bd389b36SDavid du Colombier populate(char *name) 52bd389b36SDavid du Colombier { 53bd389b36SDavid du Colombier Fileinf f; 54bd389b36SDavid du Colombier 55bd389b36SDavid du Colombier replete = 0; 56bd389b36SDavid du Colombier tapefile = open(name, OREAD); 57bd389b36SDavid du Colombier if (tapefile<0) 58bd389b36SDavid du Colombier error("Can't open argument file"); 59bd389b36SDavid du Colombier f = iget(V6ROOT); 60bd389b36SDavid du Colombier ram->perm = f.mode; 61bd389b36SDavid du Colombier ram->mtime = f.mdate; 62bd389b36SDavid du Colombier ram->data = f.addr; 63bd389b36SDavid du Colombier ram->ndata = f.size; 64bd389b36SDavid du Colombier } 65bd389b36SDavid du Colombier 66bd389b36SDavid du Colombier void 67bd389b36SDavid du Colombier popdir(Ram *r) 68bd389b36SDavid du Colombier { 69bd389b36SDavid du Colombier int i, ino; 70bd389b36SDavid du Colombier char *cp; 71bd389b36SDavid du Colombier struct v6dir *dp; 72bd389b36SDavid du Colombier Fileinf f; 73bd389b36SDavid du Colombier char name[V6NAMELEN+1]; 74bd389b36SDavid du Colombier 75bd389b36SDavid du Colombier for (i=0; i<r->ndata; i+=sizeof(struct v6dir)) { 76bd389b36SDavid du Colombier if (i%BLSIZE==0) 77bd389b36SDavid du Colombier cp = doread(r, i, BLSIZE); 78bd389b36SDavid du Colombier dp = (struct v6dir *)(cp+i%BLSIZE); 79bd389b36SDavid du Colombier ino = dp->ino[0] + (dp->ino[1]<<8); 80bd389b36SDavid du Colombier if (strcmp(dp->name, ".")==0 || strcmp(dp->name, "..")==0) 81bd389b36SDavid du Colombier continue; 82bd389b36SDavid du Colombier if (ino==0) 83bd389b36SDavid du Colombier continue; 84bd389b36SDavid du Colombier f = iget(ino); 85bd389b36SDavid du Colombier strncpy(name, dp->name, V6NAMELEN); 86bd389b36SDavid du Colombier name[V6NAMELEN+1] = '\0'; 87bd389b36SDavid du Colombier f.name = name; 88bd389b36SDavid du Colombier popfile(r, f); 89bd389b36SDavid du Colombier } 90bd389b36SDavid du Colombier r->replete = 1; 91bd389b36SDavid du Colombier } 92bd389b36SDavid du Colombier 93bd389b36SDavid du Colombier void 94bd389b36SDavid du Colombier dotrunc(Ram *r) 95bd389b36SDavid du Colombier { 96bd389b36SDavid du Colombier USED(r); 97bd389b36SDavid du Colombier } 98bd389b36SDavid du Colombier 99bd389b36SDavid du Colombier void 100bd389b36SDavid du Colombier docreate(Ram *r) 101bd389b36SDavid du Colombier { 102bd389b36SDavid du Colombier USED(r); 103bd389b36SDavid du Colombier } 104bd389b36SDavid du Colombier 105bd389b36SDavid du Colombier char * 106bd389b36SDavid du Colombier doread(Ram *r, long off, long cnt) 107bd389b36SDavid du Colombier { 108bd389b36SDavid du Colombier static char buf[MAXFDATA+BLSIZE]; 109bd389b36SDavid du Colombier int bno, i; 110bd389b36SDavid du Colombier 111bd389b36SDavid du Colombier bno = off/BLSIZE; 112bd389b36SDavid du Colombier off -= bno*BLSIZE; 113bd389b36SDavid du Colombier if (cnt>MAXFDATA) 114bd389b36SDavid du Colombier error("count too large"); 115bd389b36SDavid du Colombier if (off) 116bd389b36SDavid du Colombier cnt += BLSIZE-off; 117bd389b36SDavid du Colombier i = 0; 118bd389b36SDavid du Colombier while (cnt>0) { 119bd389b36SDavid du Colombier getblk(r, bno, &buf[i*BLSIZE]); 120bd389b36SDavid du Colombier cnt -= BLSIZE; 121bd389b36SDavid du Colombier bno++; 122bd389b36SDavid du Colombier i++; 123bd389b36SDavid du Colombier } 124bd389b36SDavid du Colombier return buf; 125bd389b36SDavid du Colombier } 126bd389b36SDavid du Colombier 127bd389b36SDavid du Colombier void 128bd389b36SDavid du Colombier dowrite(Ram *r, char *buf, long off, long cnt) 129bd389b36SDavid du Colombier { 130bd389b36SDavid du Colombier USED(r); USED(buf); USED(off); USED(cnt); 131bd389b36SDavid du Colombier } 132bd389b36SDavid du Colombier 133bd389b36SDavid du Colombier int 134bd389b36SDavid du Colombier dopermw(Ram *r) 135bd389b36SDavid du Colombier { 136bd389b36SDavid du Colombier USED(r); 137bd389b36SDavid du Colombier return 0; 138bd389b36SDavid du Colombier } 139bd389b36SDavid du Colombier 140bd389b36SDavid du Colombier /* 141bd389b36SDavid du Colombier * fetch an i-node 142bd389b36SDavid du Colombier * -- no sanity check for now 143bd389b36SDavid du Colombier * -- magic inode-to-disk-block stuff here 144bd389b36SDavid du Colombier */ 145bd389b36SDavid du Colombier 146bd389b36SDavid du Colombier Fileinf 147bd389b36SDavid du Colombier iget(int ino) 148bd389b36SDavid du Colombier { 149bd389b36SDavid du Colombier char buf[BLSIZE]; 150bd389b36SDavid du Colombier struct v6dinode *dp; 151bd389b36SDavid du Colombier long flags, i; 152bd389b36SDavid du Colombier Fileinf f; 153bd389b36SDavid du Colombier 154bd389b36SDavid du Colombier seek(tapefile, BLSIZE*((ino-1)/LINOPB + V6SUPERB + 1), 0); 155bd389b36SDavid du Colombier if (read(tapefile, buf, BLSIZE) != BLSIZE) 156bd389b36SDavid du Colombier error("Can't read inode"); 157bd389b36SDavid du Colombier dp = ((struct v6dinode *)buf) + ((ino-1)%LINOPB); 158bd389b36SDavid du Colombier flags = (dp->flags[1]<<8) + dp->flags[0]; 159bd389b36SDavid du Colombier f.size = (dp->hisize << 16) + (dp->losize[1]<<8) + dp->losize[0]; 160bd389b36SDavid du Colombier if ((flags&V6FMT)==V6IFCHR || (flags&V6FMT)==V6IFBLK) 161bd389b36SDavid du Colombier f.size = 0; 162bd389b36SDavid du Colombier f.addr = emalloc(V6NADDR*sizeof(ushort)); 163bd389b36SDavid du Colombier for (i = 0; i < V6NADDR; i++) 164bd389b36SDavid du Colombier ((ushort*)f.addr)[i] = (dp->addr[i][1]<<8) + dp->addr[i][0]; 165bd389b36SDavid du Colombier f.mode = flags & V6MODE; 166bd389b36SDavid du Colombier if ((flags&V6FMT)==V6IFDIR) 167bd389b36SDavid du Colombier f.mode |= CHDIR; 168bd389b36SDavid du Colombier f.uid = dp->uid; 169bd389b36SDavid du Colombier f.gid = dp->gid; 170bd389b36SDavid du Colombier f.mdate = (dp->mtime[2]<<0) + (dp->mtime[3]<<8) 171bd389b36SDavid du Colombier +(dp->mtime[0]<<16) + (dp->mtime[1]<<24); 172bd389b36SDavid du Colombier return f; 173bd389b36SDavid du Colombier } 174bd389b36SDavid du Colombier 175bd389b36SDavid du Colombier void 176bd389b36SDavid du Colombier getblk(Ram *r, long bno, char *buf) 177bd389b36SDavid du Colombier { 178bd389b36SDavid du Colombier long dbno; 179bd389b36SDavid du Colombier 180bd389b36SDavid du Colombier if ((dbno = bmap(r, bno)) == 0) { 181bd389b36SDavid du Colombier memset(buf, 0, BLSIZE); 182bd389b36SDavid du Colombier return; 183bd389b36SDavid du Colombier } 184bd389b36SDavid du Colombier seek(tapefile, dbno*BLSIZE, 0); 185bd389b36SDavid du Colombier if (read(tapefile, buf, BLSIZE) != BLSIZE) 186bd389b36SDavid du Colombier error("bad read"); 187bd389b36SDavid du Colombier } 188bd389b36SDavid du Colombier 189bd389b36SDavid du Colombier /* 190bd389b36SDavid du Colombier * logical to physical block 191bd389b36SDavid du Colombier * only singly-indirect files for now 192bd389b36SDavid du Colombier */ 193bd389b36SDavid du Colombier 194bd389b36SDavid du Colombier long 195bd389b36SDavid du Colombier bmap(Ram *r, long bno) 196bd389b36SDavid du Colombier { 197bd389b36SDavid du Colombier unsigned char indbuf[LNINDIR][2]; 198bd389b36SDavid du Colombier 199bd389b36SDavid du Colombier if (r->ndata < V6NADDR*BLSIZE) { /* assume size predicts largeness of file */ 200bd389b36SDavid du Colombier if (bno < V6NADDR) 201bd389b36SDavid du Colombier return ((ushort*)r->data)[bno]; 202bd389b36SDavid du Colombier return 0; 203bd389b36SDavid du Colombier } 204bd389b36SDavid du Colombier if (bno < V6NADDR*LNINDIR) { 205bd389b36SDavid du Colombier seek(tapefile, ((ushort *)r->data)[bno/LNINDIR]*BLSIZE, 0); 206bd389b36SDavid du Colombier if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE) 207bd389b36SDavid du Colombier return 0; 208bd389b36SDavid du Colombier return ((indbuf[bno%LNINDIR][1]<<8) + indbuf[bno%LNINDIR][0]); 209bd389b36SDavid du Colombier } 210bd389b36SDavid du Colombier return 0; 211bd389b36SDavid du Colombier } 212