/* * read the header for the next archive member */ Armember * getdir(Biobuf *b) { Armember *bp; char *cp; static char name[ARNAMESIZE+1]; bp = newmember(); if(HEADER_IO(Bread, b, bp->hdr)) { free(bp); return 0; } if(strncmp(bp->hdr.fmag, ARFMAG, sizeof(bp->hdr.fmag)) != 0) phaseerr(Boffset(b)); strncpy(name, bp->hdr.name, sizeof(bp->hdr.name)); cp = name+sizeof(name)-1; *cp = '\0'; /* skip trailing spaces and (gnu-produced) slashes */ while(*--cp == ' ' || *cp == '/') ; cp[1] = '\0'; file = name; bp->date = strtol(bp->hdr.date, 0, 0); bp->size = strtol(bp->hdr.size, 0, 0); return bp; }
void qcmd(char *arname, int count, char **files) { int fd, i; Armember *bp; Biobuf *bfile; if(aflag || bflag) { fprint(2, "ar: abi not allowed with q\n"); exits("error"); } fd = openar(arname, ORDWR, 1); if (fd < 0) { if(!cflag) fprint(2, "ar: creating %s\n", arname); fd = arcreate(arname); } Binit(&bar, fd, OREAD); Bseek(&bar,seek(fd,0,1), 1); /* leave note group behind when writing archive; i.e. sidestep interrupts */ rfork(RFNOTEG); Bseek(&bar, 0, 2); bp = newmember(); for(i=0; i<count && files[i]; i++) { file = files[i]; files[i] = 0; bfile = Bopen(file, OREAD); if(!bfile) fprint(2, "ar: %s cannot open\n", file); else { mesg('q', file); armove(bfile, 0, bp); if (!arwrite(fd, bp)) wrerr(); free(bp->member); bp->member = 0; Bterm(bfile); } } free(bp); close(fd); }
/* * read the header for the next archive member */ Armember * getdir(Biobuf *b) { Armember *bp; char *cp; static char name[ARNAMESIZE+1]; bp = newmember(); if(HEADER_IO(Bread, b, bp->hdr)) { free(bp); return 0; } if(strncmp(bp->hdr.fmag, ARFMAG, sizeof(bp->hdr.fmag))) phaseerr(Boffset(b)); strncpy(name, bp->hdr.name, sizeof(bp->hdr.name)); cp = name+sizeof(name)-1; while(*--cp==' ') ; cp[1] = '\0'; file = name; bp->date = atol(bp->hdr.date); bp->size = atol(bp->hdr.size); return bp; }
/* * perform the 'r' and 'u' commands */ void arcmd(char *arname, int count, char **files) { int fd; int i; Arfile *ap; Armember *bp; Dir *d; Biobuf *bfile; fd = openar(arname, ORDWR, 1); if (fd >= 0) { Binit(&bar, fd, OREAD); Bseek(&bar,seek(fd,0,1), 1); } astart = newtempfile(artemp); ap = astart; aend = 0; for(i = 0; fd >= 0; i++) { bp = getdir(&bar); if (!bp) break; if (bamatch(file, poname)) { /* check for pivot */ aend = newtempfile(tailtemp); ap = aend; } /* pitch symdef file */ if (i == 0 && strcmp(file, symdef) == 0) { skip(&bar, bp->size); continue; } if (count && !match(count, files)) { scanobj(&bar, ap, bp->size); arcopy(&bar, ap, bp); continue; } bfile = Bopen(file, OREAD); if (!bfile) { if (count != 0) fprint(2, "ar: cannot open %s\n", file); scanobj(&bar, ap, bp->size); arcopy(&bar, ap, bp); continue; } d = dirfstat(Bfildes(bfile)); if (d == nil) fprint(2, "ar: cannot stat %s: %r\n", file); if (uflag && (d == nil || d->mtime <= bp->date)) { scanobj(&bar, ap, bp->size); arcopy(&bar, ap, bp); Bterm(bfile); free(d); continue; } mesg('r', file); skip(&bar, bp->size); scanobj(bfile, ap, d->length); free(d); armove(bfile, ap, bp); Bterm(bfile); } if(fd >= 0) close(fd); /* copy in remaining files named on command line */ for (i = 0; i < count; i++) { file = files[i]; if(file == 0) continue; files[i] = 0; bfile = Bopen(file, OREAD); if (!bfile) fprint(2, "ar: %s cannot open\n", file); else { mesg('a', file); d = dirfstat(Bfildes(bfile)); if (d == nil) fprint(2, "ar: can't stat %s: %r\n", file); else { scanobj(bfile, astart, d->length); armove(bfile, astart, newmember()); free(d); } Bterm(bfile); } } if(fd < 0 && !cflag) install(arname, astart, 0, aend, 1); /* issue 'creating' msg */ else install(arname, astart, 0, aend, 0); }
int main(int argc, char ** argv) { char * fn; int ix; if (3 > argc) return fprintf(stderr, "Specify library file name and copy file name(s).\n"), 1; if (openout(argv[1])) return 16; if (getdir(cards * 80)) return 20; for (ix = 2; argv[ix]; ix++) { char * dot; char * slash; char * name; int namelen; int ismacro = 1; /* Assume file is macro */ char * s; fn = argv[ix]; f = fopen(fn, "r"); if (!f) return fprintf(stderr, "Cannot open %s: %s\n", fn, strerror(errno)), 16; slash = strrchr(fn, '/'); name = slash ? slash + 1 : fn; namelen = strlen(name); dot = strrchr(name, '.'); if (dot) { namelen = dot - name; if (!strcmp(dot + 1, "copy")) ismacro = 0; } s = gline(); if (!s) continue; if (!ismacro && memcmp(s, "*COPY ", 6)) ismacro = 1; /* Not stacked copy */ if (ismacro) { loadname(name, namelen); if (doline(line)) return 20; } else if (newmember(s)) return 20; for (;;) { s = gline(); if (!s) break; if (!ismacro && !memcmp(s, "*COPY ", 6)) { if (eom()) return 20; if (newmember(s)) return 20; continue; } if (doline(line)) return 20; } if (eom()) return 20; } if (wrapup(dirs, dir)) return 16; printf("%s %d files %d members.\n", fno, ix - 2, members); return 0; }