1: /* v6-- accesses version 6 filesystems and copies files to	*/
   2: /*	version 7 filesystems					*/
   3: /*	Mike Karels, University of California Berkeley		*/
   4: /*			Molecular Biology Department		*/
   5: /*			(mail to virus.mike @BERKELEY)		*/
   6: /*			(415) 642-7359				*/
   7: 
   8: #include "inode.h"
   9: #include "filsys.h"
  10: #include <signal.h>
  11: #include <stdio.h>
  12: 
  13: #define BLKSIZE 512
  14: #define MAXLINE 80      /* maximum input line length */
  15: #define NARG    3   /* maximum number of arguments */
  16: #define MAXARG  30  /* maximum size of input args */
  17: #define MAXSIZE	BLKSIZE/sizeof(struct direct)*8	/* max number of
  18:                     * directory entries */
  19: #define DIRSIZE 14
  20: 
  21: struct filsys sb;   /* superblock */
  22: struct inode dinode, finode;    /* current dir, file inodes */
  23: struct direct
  24: {
  25:     int d_ino;
  26:     char    d_name[DIRSIZE];
  27: } dir[MAXSIZE], cur_dir, root = { 1, "/" };
  28: int dir_sz, fd, fo, imax;
  29: char    *cmd[] = { "ls", "cd", "cp", "cat", "?", "", "q", "cpdir" };
  30: 
  31: 
  32: 
  33: 
  34: main(argc,argv)
  35: int argc;
  36: char *argv[];
  37: {
  38:     extern struct direct dir[], root, cur_dir;
  39:     extern struct inode dinode;
  40:     extern int fd;
  41: 	extern char *cmd[];
  42:     char linein[MAXLINE], arg[NARG][MAXARG];
  43:     int i, count, null();
  44: 
  45:     if (argc != 2) {
  46:         fprintf(stderr,"Usage: v6 file, where file is block special\n");
  47:         exit(1);
  48:     }
  49:     if ((fd=open(argv[1],0)) < 0) {
  50:         fprintf(stderr,"can't open %s\n",argv[1]);
  51:         exit(1);
  52:     }
  53:     if ((lseek(fd,(long)BLKSIZE,0) < 0) ||
  54:        (read(fd,&sb,BLKSIZE) < BLKSIZE)) {
  55:         fprintf(stderr,"can't read superblock\n");
  56:         exit(1);
  57:        }
  58:     imax = BLKSIZE / sizeof(struct inode) * (sb.isize-1);
  59:     if (readdir(&root) < 0) exit(1);
  60:     cur_dir.d_ino = root.d_ino;
  61:     strcpy(cur_dir.d_name,root.d_name);
  62:     signal(SIGINT,SIG_IGN);
  63: 
  64:     while(1) {
  65:         printf("* ");
  66:         if (getline(linein) == EOF) exit(0);
  67:         for (i=0; i<NARG; i++) arg[i][0] = '\0';
  68:         sscanf(linein,"%s %s %s",arg[0],arg[1],arg[2]);
  69:         for (i = 0; (i<8) && (strcmp(arg[0],cmd[i])); i++)  ;
  70:         switch(i) {
  71:             case 0: ls(arg[1]);
  72:                 break;
  73:             case 1: cd(arg[1]);
  74:                 break;
  75:             case 2: cp(arg[1],arg[2],1);
  76:                 break;
  77:             case 3: cat(arg[1]);
  78:                 break;
  79:             case 4: msg();
  80:                 break;
  81:             case 5: break;
  82:             case 6: exit(0);
  83:             case 7: cpdir(arg[1]);
  84:                 break;
  85:             case 8: if (*arg[0] == '!') {
  86:                     signal(SIGINT,null);
  87:                     system(linein+1);
  88:                     signal(SIGINT,SIG_IGN);
  89:                 }
  90:                 else fprintf(stderr,"invalid command\n");
  91:                 break;
  92:         }
  93:     }
  94: }
  95: 
  96: getline(linein)     /* reads input line into linein */
  97: char linein[]; {
  98:     int i, c;
  99: 
 100:     for (i=0; i<MAXLINE-1 && (c=getchar()) != '\n' && c != EOF;
 101:         i++) linein[i] = c;
 102:     if (c == '\n') {
 103:         linein[i] = '\0';
 104:         return(i);
 105:     }
 106:     else if (c == EOF) return(EOF);
 107:     else {
 108:         fprintf(stderr,"input line too long\n");
 109:         fflush(stdin);
 110:         linein[0] = '\0';
 111:         return(0);
 112:     }
 113: }
 114: 
 115: null() {}       /* trap here on interrupt during system() */
 116: 
 117: ls(name)    /* list directory 'name', current dir if no name */
 118: char *name; {
 119:     int i, j, flag;
 120:     extern struct direct dir[], cur_dir;
 121:     extern int dir_sz;
 122:     struct direct save_dir;
 123: 
 124:     flag = 0;
 125:     if (name[0] != '\0') {
 126:         flag = 1;
 127:         save_dir.d_ino = cur_dir.d_ino;
 128:         strcpy(save_dir.d_name,cur_dir.d_name);
 129:         if (cd(name) < 0) return;
 130:     }
 131:     j=0;
 132:     for (i=0; i<dir_sz; i++)
 133:         if (dir[i].d_ino != 0 )
 134:             printf("%-14s%c", dir[i].d_name,
 135:                 ++j%4 ? '\t':'\n');
 136:     if (j%4) putchar('\n');
 137:     if (flag) {
 138:         readdir(&save_dir);
 139:         cur_dir.d_ino = save_dir.d_ino;
 140:         strcpy(cur_dir.d_name,save_dir.d_name);
 141:     }
 142: }
 143: cpdir(arg)  /* copy contents of current directory */
 144: char *arg; {
 145:     int i;
 146:     extern struct direct dir[];
 147:     extern int dir_sz;
 148: 
 149:     if (arg[0] != '\0') {
 150:         fprintf(stderr,"no arguments allowed for cpdir\n");
 151:         return(-1);
 152:     }
 153:     for (i=0; i<dir_sz; i++)
 154:         if ((dir[i].d_ino != 0) && (dir[i].d_name[0] != '.'))
 155:             cp(dir[i].d_name,dir[i].d_name,1);
 156:     return(0);
 157: }
 158: 
 159: cd(name)        /* returns 0 if successful, else -1 */
 160: char *name; {   /* returns to previous directory if unsuccesssful */
 161:     extern struct inode dinode;
 162:     extern struct direct dir[], cur_dir, root;
 163:     extern int dir_sz;
 164:     int i, ino;
 165:     char *c, *rindex();
 166:     struct direct *pdir, *find(), save_dir;
 167: 
 168:     if ((i=iindex(name,'/')) >= 0) {
 169:         if (i==0) {
 170:             readdir(&root);
 171:             name++;
 172:         }
 173:         if (name[0]=='\0') {
 174:             cur_dir.d_ino = root.d_ino;
 175:             strcpy(cur_dir.d_name,root.d_name);
 176:             return(0);
 177:         }
 178:         if (*((c=rindex(name,'/'))+1) == '\0') *c = '\0';
 179:             /* removes trailing '/' if present */
 180:         while ((i=iindex(name,'/')) != -1) {
 181:             name[i] = '\0';
 182:             if ((pdir=find(name)) == NULL) {
 183:                 fprintf(stderr,"can't find %s\n",name);
 184:                 readdir(&cur_dir);
 185:                 return(-1);
 186:             }
 187:             if (readdir(pdir) < 0) return(-1);
 188:             name += i+1;
 189:         }
 190:     }
 191:     if ((pdir=find(name))==NULL) {
 192:         fprintf(stderr,"can't find %s\n",name);
 193:         readdir(&cur_dir);
 194:         return(-1);
 195:     }
 196:     ino = pdir->d_ino;
 197:     if (readdir(pdir) >= 0) {
 198:         cur_dir.d_ino = ino;
 199:         strcpy(cur_dir.d_name,name);
 200:         return(0);
 201:     }
 202:     else return(-1);
 203: }
 204: 
 205: iindex(s,c)
 206: char *s, c; {
 207:     int i;
 208: 
 209:     for (i=0; ; i++) {
 210:         if (s[i] == c) return(i);
 211:         if (s[i] == NULL) return(-1);
 212:     }
 213: }
 214: 
 215: struct direct *find(name)   /* returns pointer to "name" entry */
 216: char *name; {           /* in dir[], NULL if not found */
 217:     extern struct direct dir[];
 218:     int i;
 219:     extern int dir_sz;
 220: 
 221:     for (i=0; i<dir_sz; i++)
 222:         if ((strcmp(dir[i].d_name,name) == 0) &&
 223:             (dir[i].d_ino != 0))
 224:             break;
 225:     if (i==dir_sz) return(NULL);
 226:     return(&(dir[i]));
 227: }
 228: 
 229: #define MODE 0644
 230: #define STDOUT 1
 231: 
 232: cp(ifile,ofile,mode)    /* copies v6 ifile to v7 ofile if mode 1 */
 233: char *ifile, *ofile;    /* cats ifile if mode 0 */
 234: int mode; {
 235: 
 236:     extern struct inode finode;
 237:     extern struct direct dir[], cur_dir;
 238:     extern int fd,fo;
 239:     int n, i, j, blk, flag, indir[BLKSIZE/2];
 240:     long size;
 241:     char buf[BLKSIZE], *tname;
 242:     struct direct *pdir, save_dir;
 243: 
 244:     flag = 0;
 245:     if (ofile[0] == '\0' && mode == 1) {
 246:         fprintf(stderr,"Usage: cp v6file v7file\n");
 247:         goto quit;
 248:     }
 249:     if ((mode==1) && ((fo=open(ofile,0) != -1))) {
 250:         fprintf(stderr,"%s already exists\n",ofile);
 251:         goto quit;
 252:     }
 253:     if (mode == 1)  {
 254:         if ((fo= creat(ofile,MODE)) < 0) {
 255:             fprintf(stderr,"can't create %s\n",ofile);
 256:             goto quit;
 257:         }
 258:     }
 259:     else fo = dup(STDOUT);
 260:     if (iindex(ifile,'/') != -1) {
 261:         flag = 1;
 262:         save_dir.d_ino = cur_dir.d_ino;
 263:         strcpy(save_dir.d_name,cur_dir.d_name);
 264:         tname = rindex(ifile,'/');
 265:         *tname = '\0';
 266:         if (cd(ifile) < 0) return;
 267:         ifile = tname + 1;
 268:     }
 269:     if ((pdir = find(ifile)) == NULL) {
 270:         fprintf(stderr,"can't find %s\n",ifile);
 271:         goto quit;
 272:     }
 273:     if (readi(pdir->d_ino,&finode) < 0) goto quit;
 274:     if (finode.flags & (IFCHR | IFBLK)) {
 275:         /* is special file or directory */
 276:         fprintf(stderr,"cp: %s not a regular file\n");
 277:         goto quit;
 278:     }
 279:     size = finode.size1 + ((long)(finode.size0 & 0377) << 8);
 280:     if (finode.flags & IFLRG)   /* file is large */
 281:        for (blk=0; size>0; blk++) {
 282:         if (blk == 7) {
 283:             fprintf(stderr,"%s is huge file, cp incomplete\n",
 284:                 ifile);
 285:             goto quit;
 286:         }
 287:         if (readblk(finode.addr[blk],indir) < BLKSIZE)
 288:             goto quit;
 289:         for (i=0; ((i<BLKSIZE/2) && (size > 0)); i++) {
 290:             if (indir[i]==0)
 291:                 for (j=0; j<BLKSIZE/2; j++)
 292:                 buf[j] = 0;
 293:             else if (readblk(indir[i],buf) < BLKSIZE)
 294:                 goto quit;
 295:             n = (size < BLKSIZE) ? size : BLKSIZE;
 296:             if (write(fo,buf,n) != n) {
 297:                 if (mode == 1)
 298:                     fprintf(stderr,"write error\n");
 299:                 else putchar('\n');
 300:                 goto quit;
 301:             }
 302:             size -= BLKSIZE;
 303:         }
 304:        }
 305:     else for (blk=0; size>0 && blk<8; blk++) {
 306:         if (finode.addr[blk]==0)
 307:             for (j=0; j<BLKSIZE/2; j++)
 308:             buf[j] = 0;
 309:         else if (readblk(finode.addr[blk],buf) < BLKSIZE)
 310:             goto quit;
 311:         n = (size<BLKSIZE) ? size : BLKSIZE;
 312:         if (write(fo,buf,n) != n) {
 313:             if (mode == 1) fprintf(stderr,"write error\n");
 314:             else putchar('\n');
 315:             goto quit;
 316:         }
 317:     size -= BLKSIZE;
 318:     }
 319: quit:   if (fo != STDOUT) close(fo);
 320:     if (flag) {
 321:         readdir(&save_dir);
 322:         cur_dir.d_ino = save_dir.d_ino;
 323:         strcpy(cur_dir.d_name,save_dir.d_name);
 324:     }
 325: }
 326: 
 327: readdir(pdir)       /* reads pdir->d_inode into dinode, then */
 328: struct direct *pdir;    /* reads corresponding directory into dir */
 329: {           /* reads cur_dir on error, then returns -1 */
 330:     extern struct inode dinode;
 331:     extern struct direct dir[], cur_dir;
 332:     extern int dir_sz, fd;
 333:     char buf[BLKSIZE];
 334:     int blk, sz, i, n;
 335:     long size;
 336: 
 337:     if (pdir->d_ino == 0) return(-1);
 338:     if (readi(pdir->d_ino,&dinode) < 0) return(-1);
 339:     if (!(dinode.flags & IFDIR)) {  /* not a directory */
 340:         fprintf(stderr,"%s not a directory\n",pdir->d_name);
 341:         readdir(&cur_dir);
 342:         return(-1);
 343:     }
 344:     if (dinode.flags & IFLRG) { /* file is large */
 345:         fprintf(stderr,"Ouch, %s is large\n",pdir->d_name);
 346:         readdir(&cur_dir);
 347:         return(-1);
 348:     }
 349:     size = dinode.size1 + (long)(dinode.size0 & 0377) << 8;
 350:     sz = 0;
 351:     n = BLKSIZE/sizeof(struct direct);
 352:     for (blk=0; size>0 && blk<8; blk++)
 353:         if (dinode.addr[blk] > 0) {
 354:             if (readblk(dinode.addr[blk],&dir[sz])<BLKSIZE)
 355:                 return(-1);
 356:             sz += (size<BLKSIZE ? size : BLKSIZE)
 357:                 /sizeof(struct direct);
 358:             size -= BLKSIZE;
 359:         }
 360:     dir_sz = sz;
 361:     return(dir_sz);
 362: }
 363: 
 364: readi(inum,pinode)  /* reads inode inum into *pinode */
 365: int inum;
 366: struct inode *pinode; {
 367:     extern int fd, imax;
 368: 
 369:     if (inum < 1 || inum > imax) {
 370:         fprintf(stderr,"bad inode number, %d\n",inum);
 371:         return(-1);
 372:     }
 373:     if ((lseek(fd,((long)2*BLKSIZE +
 374:         (long)(inum-1)*(sizeof(struct inode))),0) < 0) ||
 375:     (read(fd,pinode,sizeof(struct inode)) < 0)) {
 376:         fprintf(stderr,"can't read inode %d\n",inum);
 377:         return(-1);
 378:     }
 379:     return(0);
 380: }
 381: 
 382: readblk(blk,buf)    /* reads block blk into buf */
 383: int blk;
 384: char *buf; {
 385:     extern struct filsys sb;
 386:     extern int fd;
 387:     int n;
 388: 
 389:     if ((blk < sb.isize-1) || (blk >= sb.fsize)) {
 390:         fprintf(stderr,"bad block number %d\n",blk);
 391:         return(-1);
 392:     }
 393:     if (lseek(fd,(long)(BLKSIZE)*(long)(blk),0) < 0) {
 394:         fprintf(stderr,"seek error, block %d\n",blk);
 395:         return(-1);
 396:     }
 397:     if ((n=read(fd,buf,BLKSIZE)) != BLKSIZE)
 398:         fprintf(stderr,"read error, block %d\n",blk);
 399:     return(n);
 400: }
 401: 
 402: cat(ifile)      /* prints ifile on terminal, using cp */
 403: char *ifile; {
 404: 
 405:     int flush();
 406:     signal(SIGINT,flush);
 407:     cp(ifile,NULL,0);   /* mode 0 signals print on tty */
 408:     signal(SIGINT,SIG_IGN);
 409: }
 410: 
 411: flush() {       /* closes fo to terminate a cat() */
 412:     extern int fo;
 413:     close(fo);
 414:     return;
 415: }
 416: 
 417: msg() {
 418:     printf("commands:\n");
 419:     printf("\t ls [dir]: list directory contents, current dir default\n");
 420:     printf("\t cd name: change to (v6) directory 'name'\n");
 421:     printf("\t cat name: print (v6) file 'name' on terminal\n");
 422:     printf("\t cp name1 name2: copy (v6) 'name1' to (v7) file 'name2'\n");
 423:     printf("\t cpdir: copy all files in current v6 directory\n");
 424:     printf("\t\tto current v7 directory\n");
 425:     printf("\t q or ^d: quit\n");
 426: }

Defined functions

cat defined in line 402; used 1 times
  • in line 77
cd defined in line 159; used 3 times
cp defined in line 232; used 3 times
cpdir defined in line 143; used 1 times
  • in line 83
find defined in line 215; used 4 times
flush defined in line 411; used 2 times
getline defined in line 96; used 1 times
  • in line 66
iindex defined in line 205; used 3 times
ls defined in line 117; used 1 times
  • in line 71
main defined in line 34; never used
msg defined in line 417; used 1 times
  • in line 79
null defined in line 115; used 2 times
readblk defined in line 382; used 4 times
readdir defined in line 327; used 10 times
readi defined in line 364; used 2 times

Defined variables

cmd defined in line 29; used 1 times
  • in line 69
cur_dir defined in line 27; used 23 times
dinode defined in line 22; used 10 times
dir defined in line 27; used 17 times
dir_sz defined in line 28; used 11 times
fd defined in line 28; used 12 times
finode defined in line 22; used 9 times
fo defined in line 28; used 10 times
imax defined in line 28; used 3 times
root defined in line 27; used 8 times
sb defined in line 21; used 5 times

Defined struct's

direct defined in line 23; used 28 times

Defined macros

BLKSIZE defined in line 13; used 28 times
DIRSIZE defined in line 19; used 1 times
  • in line 26
MAXARG defined in line 16; used 1 times
  • in line 42
MAXLINE defined in line 14; used 2 times
MAXSIZE defined in line 17; used 1 times
  • in line 27
MODE defined in line 229; used 1 times
NARG defined in line 15; used 2 times
STDOUT defined in line 230; used 2 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1597
Valid CSS Valid XHTML 1.0 Strict