/* mytar.c - just read tar tapes for now */ #include #include #include #include #include #define EFN 1 #define LUN 6 #define BUFSIZ 16384 extern int $$ferr; struct header BEGIN char name[100]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char chksum[8]; char linkflag; char linkname[100]; END; char buffer[BUFSIZ]; /* magtape record */ char *bufptr; /* where in buffer to get next 512-byte block */ long blk512; /* ordinal of block recently read into block */ int leftinbuf; /* number of bytes left in buffer */ /* excludes BLKSIZ bytes @ bufptr */ #define BLKSIZ 512 /* number of bytes in a tar block */ #define NUMDIR 30 /* number of directory levels expected */ char dir[100][NUMDIR]; /* directory names of last file */ int dirchr[NUMDIR]; /* how we encode each directory name into chars */ char *where[NUMDIR]; /* where each directory name begins in names */ char names[100]; /* the file name, broken up into directory names*/ char **w; /* tracks where[] */ char *d; /* tracks dir[][] */ int j; /* */ int number; /* */ int letter; /* */ char app[4]; /* code for this directory name */ char temp[100]; /* */ main() BEGIN int i; char rsxnam[42]; FILE * rsxfil; /* used to write disk files */ int dsw; long thesize; /* number of blocks left in this file */ int filnum; /* file number on tape */ struct header *hdrptr; int csum; /* the tape's checksum */ int mycsum; /* my checksum */ char *p; /* */ char *en; /* end of a buffer segment */ int blox; /* number of unix blocks in this file */ int dicsum; /* difference in checksums */ dsw = alun(LUN,'MT',0); /* assume mt0: is device */ IF (dsw!=IS_SUC) THEN error("alun dsw=%oo\7",dsw); FI; blk512 = -1; leftinbuf = 0; /* kickstart nxtblk() */ FOR (i=0; isize,"%lo",&thesize); sscanf(hdrptr->chksum,"%o",&csum); mycsum = 0; en = (char *) hdrptr->chksum; FOR (p=(char*)hdrptr; plinkname[100]; FOR (p=(char*)&hdrptr->linkflag; plinkflag=='1') THEN blox = 0; /* no actual data in linked file */ ELSE blox = (int) ((thesize+(long)(BLKSIZ-1))/BLKSIZ); FI; strcpy(rsxnam,"ta:"); strcpy(names,hdrptr->name); FOR (i=0,where[0]=p=names; *p; p++) DO IF (*p=='/') THEN *p=0; where[++i]=p+1; FI; OD; where[++i] = 0; FOR (w=where,i=0; *w; w++,i++) DO /* i indexs dir[i][] */ d = dir[i]; IF (!streq(d,*w)) THEN dirchr[i]++; strcpy(dir[i],where[i]); FOR (j=i+1; where[j]; j++) DO dirchr[j] = 0; strcpy(dir[j],where[j]); OD; FOR (; j9) THEN strcpy(temp,rsxnam+9); strcpy(rsxnam+9,"."); strcat(rsxnam,temp); FI; IF ( ! (rsxfil=fopen(rsxnam,"w"))) THEN error("$$ferr=%oo rsxnam=%s\tblk512=%loo\7",$$ferr,rsxnam,blk512); FI; printf("%12lo %18s\t%12ld %s\n",blk512,rsxnam,thesize,hdrptr->name); WHILE (blox--) DO IF (!nxtblk()) THEN error("unexpected end: blox=%d. blk512=%loo\7",blox,blk512); ELSE en = bufptr+(blox?BLKSIZ:(int)(thesize%(long)BLKSIZ)); FOR (p=bufptr; p