#include #include "detar.h" #include #define isodigit(x) (isdigit(x) && ((x)<'8')) void tooct(); extern int verbos, xtract; void bcopy(src,dest,n)char *src,*dest;int n; { while(n--) *dest++ = *src++; } void lcopy(src,dest,n)long *src,*dest;int n; { while(n--) *dest++ = *src++; } long from_oct(digs,where)int digs;char *where; { long ans=0; while(isspace(*where) && digs) digs--,where++; if(!digs) return 0L; while(isodigit(*where) && digs) { ans = ans *8 +(*where++ - '0'); digs--; } return ans; } int chec_chksum(tar_rec) union record *tar_rec; { long sum,recsum; int i; char *p; p=tar_rec->charptr; recsum=from_oct(8,tar_rec->header.chksum); sum=0L; for(i=sizeof(*tar_rec);--i>=0;) sum = sum + (*p++ & 0xff); for(i=sizeof(tar_rec->header.chksum);--i>=0;) sum = sum - (0xff & tar_rec->header.chksum[i]); sum = sum +' '*sizeof(tar_rec->header.chksum); if(sum==recsum) return 1; if(sum==8*' ') return 2; return 0; } void Makedirs(name)char *name; { struct stat stbuf; char *p,*q,*index(); int makeit; p=name; while(q=index(p,'\\')) { *q='\0'; makeit=0; if(stat(name,&stbuf)) makeit=1; else if((stbuf.st_mode & S_IFMT) != S_IFDIR) makeit=1; if(makeit && xtract) mkdir(name); *q='\\'; p=q+1; } } void bzero(p,n)char *p;int n; { while(n--) *p++='\0'; } void lzero(p,n)long *p;int n; { while(n--) *p++=0L; } void calc_chksum(header) register union record *header; { register int i, sum; register char *p; bcopy(CHKBLANKS, header->header.chksum, sizeof(header->header.chksum)); sum = 0; p = header->charptr; for (i = sizeof(*header); --i >= 0; ) { /* * We can't use unsigned char here because of old compilers, * e.g. V7. */ sum += 0xFF & *p++; } /* * Fill in the checksum field. It's formatted differently * from the other fields: it has [6] digits, a null, then a * space -- rather than digits, a space, then a null. * We use tooct then write the null in over tooct's space. * The final space is already there, from checksumming, and * tooct doesn't modify it. * * This is a fast way to do: * (void) sprintf(header->header.chksum, "%6o", sum); */ tooct((long) sum, 8, header->header.chksum); header->header.chksum[6] = '\0'; /* Zap the space */ } void tooct(value, digs, where) register long value; register int digs; register char *where; { --digs; /* Trailing null slot is left alone */ where[--digs] = ' '; /* Put in the space, though */ /* Produce the digits -- at least one */ do { where[--digs] = '0' + (char)(value & 7); /* one octal digit */ value >>= 3; } while (digs > 0 && value != 0); /* Leading spaces, if necessary */ while (digs > 0) where[--digs] = ' '; } char *tounix(name) register char *name; { static char punix[100]; register char *p; bzero(punix,100); for(p=punix;*name;name++,p++) switch(*name) { case '\\': *p='/'; break; default: if(*name >= 'A' && *name <= 'Z') *p = *name | '\40'; else *p = *name; break; } return punix; } extern char *rindex(),*index(); static char *do_one(s)char *s; { static char work[16]; char *p,*q; bzero(work,16); if(p=rindex(s,'.')) { *p='\0'; strncpy(work,s,8); for(q=work;*q;q++) if(*q=='.') *q='_'; *p='.'; strncat(work,p,4); }else strncpy(work,s,8); return work; } char *to_gem(punix) char *punix; { static char gem[100]; char *p,*q; bzero(gem,100); p=punix; while(q=index(p,'/')) { *q='\0'; strcat(gem,do_one(p)); strcat(gem,"\\"); *q='/'; p=q+1; } strcat(gem,do_one(p)); } ptime(raw) long raw; { char tstr[48]; extern char *ctime(); sprintf(tstr, "%s", ctime(&raw)); tstr[strlen(tstr)-1] = '\0'; printf("%s", tstr); } vtype(mode, fsize, mtime, name) int mode; long fsize, mtime; char *name; { if(verbos) { if(mode & 0x100) putchar('r'); else putchar('-'); if(mode & 0x80) putchar('w'); else putchar('-'); if(mode & 0x40) putchar('x'); else putchar('-'); if(mode & 0x20) putchar('r'); else putchar('-'); if(mode & 0x10) putchar('w'); else putchar('-'); if(mode & 0x08) putchar('x'); else putchar('-'); if(mode & 0x04) putchar('r'); else putchar('-'); if(mode & 0x02) putchar('w'); else putchar('-'); if(mode & 0x01) putchar('x'); else putchar('-'); printf(" %7ld ", fsize); ptime(mtime); } printf(" %s\n", name); } char *lcase(name) register char *name; { static char punix[100]; register char *p; bzero(punix,100); for(p=punix;*name;name++,p++) { if(*name >= 'A' && *name <= 'Z') *p = *name | '\100'; else *p = *name; } return punix; }