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); }
/* * append -- * Append files to the archive - modifies original archive or creates * a new archive if named archive does not exist. */ int append(char **argv) { struct stat sb; CF cf; FILE *afp; char *file; int eval, ntsz; afp = open_archive(O_CREAT|O_RDWR); if (fseeko(afp, 0, SEEK_END) == (off_t)-1) err(1, "lseek: %s", archive); /* Read from disk, write to an archive; pad on write. */ SETCF(0, 0, afp, archive, 0); if (options & AR_C) { /* ain't no need for a.out but a small price to pay */ if ((ntsz = mknametab(argv)) == 0) ; /* build and write the symdef, also need a mid! */ /* mkranlib(argv); if (mid & ELF) */ { options |= AR_S5; /* write out the nametab */ if (ntsz) put_nametab(&cf); } } for (eval = 0; (file = *argv++);) { if (!(cf.rfp = fopen(file, "r"))) { warn("fopen: %s", file); eval = 1; continue; } if (options & AR_V) (void)printf("q - %s\n", file); cf.rname = file; put_arobj(&cf, &sb); (void)fclose(cf.rfp); } close_archive(afp); return (eval); }
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); }