/* * stream the members in a temp file to the file referenced by 'fd'. */ void arstream(int fd, Arfile *ap) { Armember *bp; int i; char buf[8192]; if (ap->paged) { /* copy from disk */ seek(ap->fd, 0, 0); for (;;) { i = read(ap->fd, buf, sizeof(buf)); if (i < 0) rderr(); if (i == 0) break; if (write(fd, buf, i) != i) wrerr(); } close(ap->fd); ap->paged = 0; } /* dump the in-core buffers */ for (bp = ap->head; bp; bp = bp->next) { if (!arwrite(fd, bp)) wrerr(); } }
/* * create an archive and set its header */ int arcreate(char *arname) { int fd; fd = create(arname, OWRITE, 0664); if(fd < 0) { fprint(2, "ar: cannot create %s: %r\n", arname); exits("error"); } if(write(fd, ARMAG, SARMAG) != SARMAG) wrerr(); return fd; }
/* * Write the defined symbols to the symdef file */ void wrsym(Biobuf *bp, int offset, Arsymref *as) { int off; while(as) { Bputc(bp, as->type); off = as->offset+offset; Bputc(bp, off); Bputc(bp, off>>8); Bputc(bp, off>>16); Bputc(bp, off>>24); if (Bwrite(bp, as->name, as->len+1) != as->len+1) wrerr(); as = as->next; } }
void rl(int fd) { Biobuf b; char *cp; struct ar_hdr a; long len; Binit(&b, fd, OWRITE); Bseek(&b,seek(fd,0,1), 0); len = symdefsize; if(len&01) len++; sprint(a.date, "%-12ld", time(0)); sprint(a.uid, "%-6d", 0); sprint(a.gid, "%-6d", 0); sprint(a.mode, "%-8o", 0644); sprint(a.size, "%-10ld", len); strncpy(a.fmag, ARFMAG, 2); strcpy(a.name, symdef); for (cp = strchr(a.name, 0); /* blank pad on right */ cp < a.name+sizeof(a.name); cp++) *cp = ' '; if(HEADER_IO(Bwrite, &b, a)) wrerr(); len += Boffset(&b); if (astart) { wrsym(&b, len, astart->sym); len += astart->size; } if(amiddle) { wrsym(&b, len, amiddle->sym); len += amiddle->size; } if(aend) wrsym(&b, len, aend->sym); if(symdefsize&0x01) Bputc(&b, 0); Bterm(&b); }
void xcmd(char *arname, int count, char **files) { int fd, f, mode, i; Armember *bp; Dir dx; fd = openar(arname, OREAD, 0); Binit(&bar, fd, OREAD); Bseek(&bar,seek(fd,0,1), 1); i = 0; while (bp = getdir(&bar)) { if(count == 0 || match(count, files)) { mode = strtoul(bp->hdr.mode, 0, 8) & 0777; f = create(file, OWRITE, mode); if(f < 0) { fprint(2, "ar: %s cannot create\n", file); skip(&bar, bp->size); } else { mesg('x', file); arcopy(&bar, 0, bp); if (write(f, bp->member, bp->size) < 0) wrerr(); if(oflag) { nulldir(&dx); dx.atime = bp->date; dx.mtime = bp->date; if(dirwstat(file, &dx) < 0) perror(file); } free(bp->member); close(f); } free(bp); if (count && ++i >= count) break; } else { skip(&bar, bp->size); free(bp); } } close(fd); }
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); }
void pcmd(char *arname, int count, char **files) { int fd; Armember *bp; fd = openar(arname, OREAD, 0); Binit(&bar, fd, OREAD); Bseek(&bar,seek(fd,0,1), 1); while(bp = getdir(&bar)) { if(count == 0 || match(count, files)) { if(vflag) print("\n<%s>\n\n", file); arcopy(&bar, 0, bp); if (write(1, bp->member, bp->size) < 0) wrerr(); } else skip(&bar, bp->size); free(bp); } close(fd); }