/* v6-- accesses version 6 filesystems and copies files to */ /* version 7 filesystems */ /* Mike Karels, University of California Berkeley */ /* Molecular Biology Department */ /* (mail to virus.mike @BERKELEY) */ /* (415) 642-7359 */ #include "inode.h" #include "filsys.h" #include #include #define BLKSIZE 512 #define MAXLINE 80 /* maximum input line length */ #define NARG 3 /* maximum number of arguments */ #define MAXARG 30 /* maximum size of input args */ #define MAXSIZE BLKSIZE/sizeof(struct direct)*8 /* max number of * directory entries */ #define DIRSIZE 14 struct filsys sb; /* superblock */ struct inode dinode, finode; /* current dir, file inodes */ struct direct { int d_ino; char d_name[DIRSIZE]; } dir[MAXSIZE], cur_dir, root = { 1, "/" }; int dir_sz, fd, fo, imax; char *cmd[] = { "ls", "cd", "cp", "cat", "?", "", "q", "cpdir" }; main(argc,argv) int argc; char *argv[]; { extern struct direct dir[], root, cur_dir; extern struct inode dinode; extern int fd; extern char *cmd[]; char linein[MAXLINE], arg[NARG][MAXARG]; int i, count, null(); if (argc != 2) { fprintf(stderr,"Usage: v6 file, where file is block special\n"); exit(1); } if ((fd=open(argv[1],0)) < 0) { fprintf(stderr,"can't open %s\n",argv[1]); exit(1); } if ((lseek(fd,(long)BLKSIZE,0) < 0) || (read(fd,&sb,BLKSIZE) < BLKSIZE)) { fprintf(stderr,"can't read superblock\n"); exit(1); } imax = BLKSIZE / sizeof(struct inode) * (sb.isize-1); if (readdir(&root) < 0) exit(1); cur_dir.d_ino = root.d_ino; strcpy(cur_dir.d_name,root.d_name); signal(SIGINT,SIG_IGN); while(1) { printf("* "); if (getline(linein) == EOF) exit(0); for (i=0; i= 0) { if (i==0) { readdir(&root); name++; } if (name[0]=='\0') { cur_dir.d_ino = root.d_ino; strcpy(cur_dir.d_name,root.d_name); return(0); } if (*((c=rindex(name,'/'))+1) == '\0') *c = '\0'; /* removes trailing '/' if present */ while ((i=iindex(name,'/')) != -1) { name[i] = '\0'; if ((pdir=find(name)) == NULL) { fprintf(stderr,"can't find %s\n",name); readdir(&cur_dir); return(-1); } if (readdir(pdir) < 0) return(-1); name += i+1; } } if ((pdir=find(name))==NULL) { fprintf(stderr,"can't find %s\n",name); readdir(&cur_dir); return(-1); } ino = pdir->d_ino; if (readdir(pdir) >= 0) { cur_dir.d_ino = ino; strcpy(cur_dir.d_name,name); return(0); } else return(-1); } iindex(s,c) char *s, c; { int i; for (i=0; ; i++) { if (s[i] == c) return(i); if (s[i] == NULL) return(-1); } } struct direct *find(name) /* returns pointer to "name" entry */ char *name; { /* in dir[], NULL if not found */ extern struct direct dir[]; int i; extern int dir_sz; for (i=0; id_ino,&finode) < 0) goto quit; if (finode.flags & (IFCHR | IFBLK)) { /* is special file or directory */ fprintf(stderr,"cp: %s not a regular file\n"); goto quit; } size = finode.size1 + ((long)(finode.size0 & 0377) << 8); if (finode.flags & IFLRG) /* file is large */ for (blk=0; size>0; blk++) { if (blk == 7) { fprintf(stderr,"%s is huge file, cp incomplete\n", ifile); goto quit; } if (readblk(finode.addr[blk],indir) < BLKSIZE) goto quit; for (i=0; ((i 0)); i++) { if (indir[i]==0) for (j=0; j0 && blk<8; blk++) { if (finode.addr[blk]==0) for (j=0; jd_inode into dinode, then */ struct direct *pdir; /* reads corresponding directory into dir */ { /* reads cur_dir on error, then returns -1 */ extern struct inode dinode; extern struct direct dir[], cur_dir; extern int dir_sz, fd; char buf[BLKSIZE]; int blk, sz, i, n; long size; if (pdir->d_ino == 0) return(-1); if (readi(pdir->d_ino,&dinode) < 0) return(-1); if (!(dinode.flags & IFDIR)) { /* not a directory */ fprintf(stderr,"%s not a directory\n",pdir->d_name); readdir(&cur_dir); return(-1); } if (dinode.flags & IFLRG) { /* file is large */ fprintf(stderr,"Ouch, %s is large\n",pdir->d_name); readdir(&cur_dir); return(-1); } size = dinode.size1 + (long)(dinode.size0 & 0377) << 8; sz = 0; n = BLKSIZE/sizeof(struct direct); for (blk=0; size>0 && blk<8; blk++) if (dinode.addr[blk] > 0) { if (readblk(dinode.addr[blk],&dir[sz]) imax) { fprintf(stderr,"bad inode number, %d\n",inum); return(-1); } if ((lseek(fd,((long)2*BLKSIZE + (long)(inum-1)*(sizeof(struct inode))),0) < 0) || (read(fd,pinode,sizeof(struct inode)) < 0)) { fprintf(stderr,"can't read inode %d\n",inum); return(-1); } return(0); } readblk(blk,buf) /* reads block blk into buf */ int blk; char *buf; { extern struct filsys sb; extern int fd; int n; if ((blk < sb.isize-1) || (blk >= sb.fsize)) { fprintf(stderr,"bad block number %d\n",blk); return(-1); } if (lseek(fd,(long)(BLKSIZE)*(long)(blk),0) < 0) { fprintf(stderr,"seek error, block %d\n",blk); return(-1); } if ((n=read(fd,buf,BLKSIZE)) != BLKSIZE) fprintf(stderr,"read error, block %d\n",blk); return(n); } cat(ifile) /* prints ifile on terminal, using cp */ char *ifile; { int flush(); signal(SIGINT,flush); cp(ifile,NULL,0); /* mode 0 signals print on tty */ signal(SIGINT,SIG_IGN); } flush() { /* closes fo to terminate a cat() */ extern int fo; close(fo); return; } msg() { printf("commands:\n"); printf("\t ls [dir]: list directory contents, current dir default\n"); printf("\t cd name: change to (v6) directory 'name'\n"); printf("\t cat name: print (v6) file 'name' on terminal\n"); printf("\t cp name1 name2: copy (v6) 'name1' to (v7) file 'name2'\n"); printf("\t cpdir: copy all files in current v6 directory\n"); printf("\t\tto current v7 directory\n"); printf("\t q or ^d: quit\n"); }