/* * 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(); } }
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); }
/* * Spill a member to a disk copy of a temp file */ int page(Arfile *ap) { Armember *bp; bp = ap->head; if (!ap->paged) { /* not yet paged - create file */ ap->fname = mktemp(ap->fname); ap->fd = create(ap->fname, ORDWR|ORCLOSE, 0600); if (ap->fd < 0) { fprint(2,"ar: can't create temp file\n"); return 0; } ap->paged = 1; } if (!arwrite(ap->fd, bp)) /* write member and free buffer block */ return 0; ap->head = bp->next; if (ap->tail == bp) ap->tail = bp->next; free(bp->member); free(bp); return 1; }