#include #include #include #include struct th { char *name; ulong perm; ulong size; char type; char *user, *group; }; static char *sndup(char* s, ulong n) { char *d, *p; p = memchr(s, 0, n); if(p) n = p-s; d = malloc(n+1); memcpy(d,s,n); d[n] = 0; return d; } int readheader(int fd, struct th* th) { int i; char b[512]; if(readn(fd, b, 512) != 512) return -1; // Check for end of archive for(i=0; i<512; i++) { if(b[i]!=0) goto rhok; } if(readn(fd, b, 512) != 512) return -1; for(i=0; i<512; i++) { if(b[i]!=0) return -1; } return 0; rhok: th->name = sndup(b, 100); th->perm = strtoul(b+100, nil, 8); th->size = strtoul(b+124, nil, 8); th->type = b[156]; th->user = sndup(b+265, 32); th->group= sndup(b+297, 32); return 1; } int main(void) { while(1) { struct th th; ulong off; uchar b[512]; DigestState *s; int wfd; int r = readheader(0, &th); if(r <= 0) return r; switch(th.type) { case '5': create(th.name, OREAD, DMDIR|th.perm); break; case '0': case 0: print("A %s\n", th.name); r = access(th.name, 0); if(r == 0) { print("File already exists: %s\n", th.name); return -1; } if((wfd = create(th.name, OWRITE, th.perm)) < 0) { print("Create failed: %s\n", th.name); return -1; } s = nil; for(off=0; off