# # initially generated by c2l # dolong: int; atimeof(force: int, name: array of byte): int { sym: ref Symtab; t: int; archive, member: array of byte; buf := array[512] of byte; (archive, member) = split(name); if(archive == nil) Exit(); t = mtime(archive); sym = symlooki(archive, S_AGG, 0); if(sym != nil){ if(force || t > sym.ivalue){ atimes(archive); sym.ivalue = t; } } else{ atimes(archive); # mark the aggegate as having been done symlooks(libc0->strdup(archive), S_AGG, libc0->s2ab("")).ivalue = t; } # truncate long member name to sizeof of name field in archive header if(dolong) stob(buf, sys->sprint("%s(%s)", libc0->ab2s(archive), libc0->ab2s(member))); else stob(buf, sys->sprint("%s(%.*s)", libc0->ab2s(archive), SARNAME, libc0->ab2s(member))); sym = symlooki(buf, S_TIME, 0); if(sym != nil) return sym.ivalue; # uggh return 0; } atouch(name: array of byte) { archive, member: array of byte; fd: ref Sys->FD; i: int; # h: ar_hdr; t: int; (archive, member) = split(name); if(archive == nil) Exit(); fd = sys->open(libc0->ab2s(archive), Sys->ORDWR); if(fd == nil){ fd = sys->create(libc0->ab2s(archive), Sys->OWRITE, 8r666); if(fd == nil){ perror(archive); Exit(); } sys->write(fd, libc0->s2ab(ARMAG), SARMAG); } if(symlooki(name, S_TIME, 0) != nil){ # hoon off and change it in situ sys->seek(fd, SARMAG, 0); buf := array[SAR_HDR] of byte; while(sys->read(fd, buf, SAR_HDR) == SAR_HDR){ name = buf[0: SARNAME]; for(i = SARNAME-1; i > 0 && name[i] == byte ' '; i--) ; name[i+1] = byte 0; if(libc0->strcmp(member, name) == 0){ t = SARNAME-SAR_HDR; # ughgghh sys->seek(fd, t, 1); sys->fprint(fd, "%-12d", daytime->now()); break; } t = int string buf[48: 58]; if(t&8r1) t++; sys->seek(fd, t, 1); } } fd = nil; } atimes(ar: array of byte) { # h: ar_hdr; t: int; fd: ref Sys->FD; i: int; buf := array[BIGBLOCK] of byte; n: array of byte; name := array[SARNAME+1] of byte; fd = sys->open(libc0->ab2s(ar), Sys->OREAD); if(fd == nil) return; if(sys->read(fd, buf, SARMAG) != SARMAG){ fd = nil; return; } b := array[SAR_HDR] of byte; while(sys->read(fd, b, SAR_HDR) == SAR_HDR){ t = int string b[16: 28]; if(t == 0) # as it sometimes happens; thanks ken t = 1; hname := b[0: SARNAME]; libc0->strncpy(name, hname, SARNAME); for(i = SARNAME-1; i > 0 && name[i] == byte ' '; i--) ; if(name[i] == byte '/') # system V bug i--; name[i+1] = byte 0; n = membername(name, fd, int string b[48: 58]); if(n == nil){ dolong = 1; continue; } stob(buf, sys->sprint("%s(%s)", libc0->ab2s(ar), libc0->ab2s(n))); symlooki(libc0->strdup(buf), S_TIME, t).ivalue = t; t = int string b[48: 58]; if(t&8r1) t++; sys->seek(fd, t, 1); } fd = nil; } typex(file: array of byte): int { fd: ref Sys->FD; buf := array[SARMAG] of byte; fd = sys->open(libc0->ab2s(file), Sys->OREAD); if(fd == nil){ if(symlooki(file, S_BITCH, 0) == nil){ bout.puts(sys->sprint("%s doesn't exist: assuming it will be an archive\n", libc0->ab2s(file))); symlooks(file, S_BITCH, file); } return 1; } if(sys->read(fd, buf, SARMAG) != SARMAG){ fd = nil; return 0; } fd = nil; return !libc0->strncmp(libc0->s2ab(ARMAG), buf, SARMAG); } split(name: array of byte): (array of byte, array of byte) { member: array of byte; p, q: array of byte; p = libc0->strdup(name); q = libc0->strchr(p, '('); if(q != nil){ q[0] = byte 0; q = q[1: ]; member = q; q = libc0->strchr(q, ')'); if(q != nil) q[0] = byte 0; if(typex(p)) return (p, member); p = nil; sys->fprint(sys->fildes(2), "mk: '%s' is not an archive\n", libc0->ab2s(name)); } return (nil, member); }