int build(void) { CF cf; int afd, tfd; int current_mid; off_t size; current_mid = -1; afd = open_archive(O_RDWR); fp = fdopen(afd, "r+"); tfd = tmp(); SETCF(afd, archive, tfd, tname, RPAD|WPAD); /* Read through the archive, creating list of symbols. */ symcnt = tsymlen = 0; pnext = &rhead; while(get_arobj(afd)) { int new_mid; if (!strcmp(chdr.name, RANLIBMAG)) { skip_arobj(afd); continue; } new_mid = rexec(afd, tfd); if (new_mid != -1) { if (current_mid == -1) current_mid = new_mid; else if (new_mid != current_mid) errx(1, "Mixed object format archive: %d / %d", new_mid, current_mid); } put_arobj(&cf, (struct stat *)NULL); } *pnext = NULL; /* Create the symbol table. Endianess the same as last mid seen */ symobj(current_mid); /* Copy the saved objects into the archive. */ size = lseek(tfd, (off_t)0, SEEK_CUR); (void)lseek(tfd, (off_t)0, SEEK_SET); SETCF(tfd, tname, afd, archive, NOPAD); copy_ar(&cf, size); (void)ftruncate(afd, lseek(afd, (off_t)0, SEEK_CUR)); (void)close(tfd); /* Set the time. */ settime(afd); close_archive(afd); return(0); }
int touch() { int afd; afd = open_archive(O_RDWR); if (!get_arobj(afd) || strncmp(RANLIBMAG, chdr.name, sizeof(RANLIBMAG) - 1)) { (void)fprintf(stderr, "ranlib: %s: no symbol table.\n", archive); return(1); } settime(afd); close_archive(afd); return(0); }
int touch(void) { FILE *afp; afp = open_archive(O_RDWR); if (!get_arobj(afp) || (strncmp(RANLIBMAG, chdr.name, sizeof(RANLIBMAG) - 1) && strncmp(RANLIBMAG2, chdr.name, sizeof(RANLIBMAG2) - 1))) { warnx("%s: no symbol table.", archive); return(1); } settime(afp); close_archive(afp); return(0); }
/* * print -- * Prints archive members on stdout - if member names given only * print those members, otherwise print all members. */ int print(char **argv) { off_t size; CF cf; FILE *afp; char *file; int all; afp = open_archive(O_RDONLY); /* Read from an archive, write to stdout; pad on read. */ SETCF(afp, archive, stdout, "stdout", 0); for (all = !*argv; get_arobj(afp);) { if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) { size = ftello(afp); get_namtab(afp); (void)fseeko(afp, size, SEEK_SET); skip_arobj(afp); continue; } if (all) file = chdr.name; else if (!(file = files(argv))) { skip_arobj(afp); continue; } if (options & AR_V) { (void)printf("\n<%s>\n\n", file); (void)fflush(stdout); } copy_ar(&cf, chdr.size); if (!all && !*argv) break; } close_archive(afp); if (*argv) { orphans(argv); return (1); } return (0); }
build() { CF cf; int afd, tfd; off_t size; afd = open_archive(O_RDWR); fp = fdopen(afd, "r+"); tfd = tmp(); SETCF(afd, archive, tfd, tname, RPAD|WPAD); /* Read through the archive, creating list of symbols. */ pnext = &rhead; while(get_arobj(afd)) { if (!strcmp(chdr.name, RANLIBMAG)) { skip_arobj(afd); continue; } rexec(afd, tfd); put_arobj(&cf, (struct stat *)NULL); } *pnext = NULL; /* Create the symbol table. */ symobj(); /* Copy the saved objects into the archive. */ size = lseek(tfd, (off_t)0, SEEK_CUR); (void)lseek(tfd, (off_t)0, SEEK_SET); SETCF(tfd, tname, afd, archive, RPAD|WPAD); copy_ar(&cf, size); (void)ftruncate(afd, lseek(afd, (off_t)0, SEEK_CUR)); (void)close(tfd); /* Set the time. */ settime(afd); close_archive(afd); return(0); }
int do_ranlib(void) { CF cf; off_t size; FILE *afp, *tfp; long symcnt; /* symbol count */ long tsymlen; /* total string length */ int i, current_mid; current_mid = -1; afp = open_archive(O_RDWR); tfp = tmp(); SETCF(afp, archive, tfp, tname, 0); /* Read through the archive, creating list of symbols. */ symcnt = tsymlen = 0; ntsize = 0; r_fuzz = SARMAG; pnext = &rhead; while(get_arobj(afp)) { int new_mid; if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) { size = ftello(afp); get_namtab(afp); ntsize = chdr.size + sizeof(struct ar_hdr); (void)fseeko(afp, size, SEEK_SET); r_fuzz += skip_arobj(afp); continue; } if (!strncmp(chdr.name, RANLIBMAG, sizeof(RANLIBMAG) - 1) || !strncmp(chdr.name, RANLIBMAG2, sizeof(RANLIBMAG2) - 1)) { r_fuzz += skip_arobj(afp); continue; } new_mid = read_exec(afp, tfp, &symcnt, &tsymlen); if (new_mid != -1) { if (current_mid == -1) current_mid = new_mid; else if (new_mid != current_mid) errx(1, "mixed object format archive: %x / %x", new_mid, current_mid); } put_arobj(&cf, NULL); } *pnext = NULL; SETCF(tfp, tname, afp, archive, NOPAD); /* Create the symbol table. Endianess the same as last mid seen */ symobj(afp, current_mid, symcnt, tsymlen); put_nametab(&cf); /* Copy the saved objects into the archive. */ size = ftello(tfp); rewind(tfp); copy_ar(&cf, size); fflush(afp); (void)ftruncate(fileno(afp), ftello(afp)); (void)fclose(tfp); /* Set the time. */ settime(afp); close_archive(afp); return(0); }
/* * replace -- * Replace or add named members to archive. Entries already in the * archive are swapped in place. Others are added before or after * the key entry, based on the a, b and i options. If the u option * is specified, modification dates select for replacement. */ int replace(char **argv) { char *file; int afd, curfd, errflg, exists, mods, sfd, tfd1, tfd2; struct stat sb; CF cf; off_t size, tsize; errflg = 0; /* * If doesn't exist, simply append to the archive. There's * a race here, but it's pretty short, and not worth fixing. */ exists = !stat(archive, &sb); afd = open_archive(O_CREAT|O_RDWR); if (!exists) { tfd1 = -1; tfd2 = tmp(); goto append; } tfd1 = tmp(); /* Files before key file. */ tfd2 = tmp(); /* Files after key file. */ /* * Break archive into two parts -- entries before and after the key * entry. If positioning before the key, place the key at the * beginning of the after key entries and if positioning after the * key, place the key at the end of the before key entries. Put it * all back together at the end. */ mods = (options & (AR_A|AR_B)); for (curfd = tfd1; get_arobj(afd);) { if (*argv && (file = files(argv))) { if ((sfd = open(file, O_RDONLY)) < 0) { errflg = 1; warn("%s", file); goto useold; } (void)fstat(sfd, &sb); if (options & AR_U && sb.st_mtime <= chdr.date) { close(sfd); goto useold; } if (options & AR_V) (void)printf("r - %s\n", file); /* Read from disk, write to an archive; pad on write */ SETCF(sfd, file, curfd, tname, WPAD); put_arobj(&cf, &sb); (void)close(sfd); skip_arobj(afd); continue; } if (mods && compare(posname)) { mods = 0; if (options & AR_B) curfd = tfd2; /* Read and write to an archive; pad on both. */ SETCF(afd, archive, curfd, tname, RPAD|WPAD); put_arobj(&cf, NULL); if (options & AR_A) curfd = tfd2; } else { /* Read and write to an archive; pad on both. */ useold: SETCF(afd, archive, curfd, tname, RPAD|WPAD); put_arobj(&cf, NULL); } } if (mods) { warnx("%s: archive member not found", posarg); close_archive(afd); return (1); } /* Append any left-over arguments to the end of the after file. */ append: while ((file = *argv++)) { if (options & AR_V) (void)printf("a - %s\n", file); if ((sfd = open(file, O_RDONLY)) < 0) { errflg = 1; warn("%s", file); continue; } (void)fstat(sfd, &sb); /* Read from disk, write to an archive; pad on write. */ SETCF(sfd, file, options & (AR_A|AR_B) ? tfd1 : tfd2, tname, WPAD); put_arobj(&cf, &sb); (void)close(sfd); } (void)lseek(afd, (off_t)SARMAG, SEEK_SET); SETCF(tfd1, tname, afd, archive, NOPAD); if (tfd1 != -1) { tsize = size = lseek(tfd1, (off_t)0, SEEK_CUR); (void)lseek(tfd1, (off_t)0, SEEK_SET); copy_ar(&cf, size); } else tsize = 0; tsize += size = lseek(tfd2, (off_t)0, SEEK_CUR); (void)lseek(tfd2, (off_t)0, SEEK_SET); cf.rfd = tfd2; copy_ar(&cf, size); (void)ftruncate(afd, tsize + SARMAG); close_archive(afd); return (errflg); }
/* * extract -- * Extract files from the named archive - if member names given only * extract those members otherwise extract all members. If 'o' option * selected modify date of newly created file to be same as archive * members date otherwise date is time of extraction. Does not modify * archive. */ int extract(char **argv) { struct timeval tv[2]; struct stat sb; CF cf; off_t size; FILE *afp; char *file; int all, eval, tfd; eval = 0; tv[0].tv_usec = tv[1].tv_usec = 0; afp = open_archive(O_RDONLY); /* Read from an archive, write to disk; pad on read. */ SETCF(afp, archive, 0, 0, 0); for (all = !*argv; get_arobj(afp);) { if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) { size = ftello(afp); get_namtab(afp); (void)fseeko(afp, size, SEEK_SET); skip_arobj(afp); continue; } if (all) file = chdr.name; else if (!(file = files(argv))) { skip_arobj(afp); continue; } if (options & AR_U && !stat(file, &sb) && sb.st_mtime > chdr.date) continue; if (options & AR_CC) { /* -C means do not overwrite existing files */ if ((tfd = open(file, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR)) < 0) { skip_arobj(afp); eval = 1; continue; } } else { if ((tfd = open(file, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR)) < 0) { warn("open: %s", file); skip_arobj(afp); eval = 1; continue; } } if (options & AR_V) (void)printf("x - %s\n", file); if (!(cf.wfp = fdopen(tfd, "w"))) err(1, "fdopen: %s", file); cf.wname = file; copy_ar(&cf, chdr.size); if (fchmod(tfd, (mode_t)chdr.mode)) { warn("chmod: %s", file); eval = 1; } if (options & AR_O) { tv[0].tv_sec = tv[1].tv_sec = chdr.date; if (futimes(tfd, tv)) { warn("utimes: %s", file); eval = 1; } } (void)fclose(cf.wfp); if (!all && !*argv) break; } close_archive(afp); if (*argv) { orphans(argv); return (1); } return (0); }