int main(int argc, char *argv[]) { assert(sizeof(Header) == 16); assert(sizeof(IndexEntry) == 24); parse_args(argc, argv); switch (arg_mode) { case LIST: open_archive(arg_archive); process_header(); list_entries(); close_archive(); break; case EXTRACT: open_archive(arg_archive); process_header(); extract_entries(); close_archive(); break; case CREATE: create_archive(arg_archive, (const char**)arg_files_begin, (const char**)arg_files_end, arg_com); break; } return 0; }
int open_archive(char *name, int mode) { unsigned short magic = 0; int fd; if (mode == CREATE) { if ((fd = creat(name, 0666)) < 0) error2(TRUE, "cannot creat %s\n", name); magic = MAGIC_NUMBER; wr_int2(fd, magic); return fd; } if ((fd = open(name, mode)) < 0) { if (mode == APPEND) { close(open_archive(name, CREATE)); if (!nocr_fl) error3(FALSE, "%s: creating %s\n", progname, name); return open_archive(name, APPEND); } error2(TRUE, "cannot open %s\n", name); } lseek(fd, 0L, 0); magic = rd_unsigned2(fd); if (magic != AALMAG && magic != ARMAG) error2(TRUE, "%s is not in ar format\n", name); return fd; }
static int gsf_list (int argc, char **argv) { int i; for (i = 0; i < argc; i++) { char const *filename = argv[i]; char *display_name; GsfInfile *infile = open_archive (filename); if (!infile) return 1; if (i > 0) g_print ("\n"); display_name = g_filename_display_name (filename); g_print ("%s:\n", display_name); g_free (display_name); ls_R (GSF_INPUT (infile), NULL); g_object_unref (infile); } return 0; }
static int gsf_list_props (int argc, char **argv) { GsfInfile *infile; GsfDocMetaData *meta_data; char const *filename; GSList *names = NULL; if (argc != 1) return 1; filename = argv[0]; infile = open_archive (filename); if (!infile) return 1; meta_data = get_meta_data (infile, filename); gsf_doc_meta_data_foreach (meta_data, cb_collect_names, &names); names = g_slist_sort (names, (GCompareFunc)strcmp); g_slist_foreach (names, (GFunc)cb_print_names, NULL); g_slist_free (names); g_object_unref (meta_data); g_object_unref (infile); return 0; }
void archive_impl::open(service_ptr_t<file> & p_out,const char * path,t_open_mode mode, abort_callback & p_abort) { if (mode != open_mode_read) throw exception_io_denied(); pfc::string8 archive,file; if (!g_parse_unpack_path(path,archive,file)) throw exception_io_not_found(); open_archive(p_out,archive,file,p_abort); }
void register_archive(const char *zipname) { struct archive *zip = open_archive(zipname); if (zip) { zip->next = zip_head; zip_head = zip; } }
// opens the various archive files. Guarantees that the timestamp // does not equal the previous timestamp // void open_all_archives() { int old_time=time_int; // make sure we get a NEW value of the file timestamp! // while (old_time == (time_int = (int)time(0))) { sleep(1); } // open all the archives. open_archive(WU_FILENAME_PREFIX, wu_stream); open_archive(RESULT_FILENAME_PREFIX, re_stream); open_archive(RESULT_INDEX_FILENAME_PREFIX, re_index_stream); open_archive(WU_INDEX_FILENAME_PREFIX, wu_index_stream); fprintf(wu_stream, "<archive>\n"); fprintf(re_stream, "<archive>\n"); return; }
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); }
void create_archive() { register char *p; open_archive(0); /* Open for writing */ while (p = name_next()) { dump_file(p, -1); } write_eot(); close_archive(); name_close(); }
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); }
/* * 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); }
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); }
void create_archive() { register char *p; char *name_from_list(); open_archive(0); /* Open for writing */ if(f_gnudump) { char buf[MAXNAMLEN],*q,*bufp; collect_and_sort_names(); while(p=name_from_list()) dump_file(p,-1); /* if(!f_dironly) { */ blank_name_list(); while(p=name_from_list()) { strcpy(buf,p); if(p[strlen(p)-1]!='/') strcat(buf,"/"); bufp=buf+strlen(buf); for(q=gnu_list_name->dir_contents;*q;q+=strlen(q)+1) { if(*q=='Y') { strcpy(bufp,q+1); dump_file(buf,-1); } } } /* } */ } else { while (p = name_next(1)) { dump_file(p, -1); } } write_eot(); close_archive(); name_close(); }
static int gsf_dump (int argc, char **argv, gboolean hex) { char const *filename; GsfInfile *infile; int i; int res = 0; if (argc < 2) return 1; filename = argv[0]; infile = open_archive (filename); if (!infile) return 1; for (i = 1; i < argc; i++) { char const *name = argv[i]; GsfInput *member = find_member (infile, name); if (!member) { char *display_name = g_filename_display_name (name); g_print ("%s: archive has no member %s\n", g_get_prgname (), display_name); g_free (display_name); res = 1; break; } if (hex) { char *display_name = g_filename_display_name (name); g_print ("%s:\n", display_name); g_free (display_name); } gsf_input_dump (member, hex); g_object_unref (member); } g_object_unref (infile); return res; }
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); }
static int gsf_dump_props (int argc, char **argv) { GsfInfile *infile; GsfDocMetaData *meta_data; char const *filename; int res = 0; int i; if (argc < 2) return 1; filename = argv[0]; infile = open_archive (filename); if (!infile) return 1; meta_data = get_meta_data (infile, filename); for (i = 1; i < argc; i++) { const char *name = argv[i]; GsfDocProp const *prop = gsf_doc_meta_data_lookup (meta_data, name); if (prop) { if (argc > 2) g_print ("%s: ", name); gsf_doc_prop_dump (prop); } else { g_printerr (_("No property named %s\n"), name); } } g_object_unref (meta_data); g_object_unref (infile); return res; }
int main(int argc, char *argv[]) { Boolean use_default_sfx = TRUE; Boolean show_basename_only = FALSE; char lsdir[MaxPathSize]; char sfx[MaxPathSize]; char *lsdirp = NULL; int ch; setprogname(argv[0]); if (argc < 2) usage(); while ((ch = getopt(argc, argv, Options)) != -1) switch (ch) { case 'C': config_file = optarg; break; case 'K': pkgdb_set_dir(optarg, 3); break; case 'S': sfx[0] = 0x0; use_default_sfx = FALSE; break; case 'V': show_version(); /* NOTREACHED */ case 'b': show_basename_only = TRUE; break; case 'd': (void) strlcpy(lsdir, optarg, sizeof(lsdir)); lsdirp = lsdir; break; case 'q': quiet = 1; break; case 's': (void) strlcpy(sfx, optarg, sizeof(sfx)); use_default_sfx = FALSE; break; case 'v': ++verbose; break; default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; if (argc <= 0) { usage(); } /* * config-var is reading the config file implicitly, * so skip it here. */ if (strcasecmp(argv[0], "config-var") != 0) pkg_install_config(); if (use_default_sfx) (void) strlcpy(sfx, DEFAULT_SFX, sizeof(sfx)); if (strcasecmp(argv[0], "pmatch") == 0) { char *pattern, *pkg; argv++; /* "pmatch" */ if (argv[0] == NULL || argv[1] == NULL) { usage(); } pattern = argv[0]; pkg = argv[1]; if (pkg_match(pattern, pkg)) { return 0; } else { return 1; } } else if (strcasecmp(argv[0], "rebuild") == 0) { rebuild(); printf("Done.\n"); } else if (strcasecmp(argv[0], "rebuild-tree") == 0) { rebuild_tree(); printf("Done.\n"); } else if (strcasecmp(argv[0], "check") == 0) { argv++; /* "check" */ check(argv); if (!quiet) { printf("Done.\n"); } } else if (strcasecmp(argv[0], "lsall") == 0) { argv++; /* "lsall" */ while (*argv != NULL) { /* args specified */ int rc; const char *basep, *dir; dir = lsdirp ? lsdirp : dirname_of(*argv); basep = basename_of(*argv); if (show_basename_only) rc = match_local_files(dir, use_default_sfx, 1, basep, lsbasepattern, NULL); else rc = match_local_files(dir, use_default_sfx, 1, basep, lspattern, __UNCONST(dir)); if (rc == -1) errx(EXIT_FAILURE, "Error from match_local_files(\"%s\", \"%s\", ...)", dir, basep); argv++; } } else if (strcasecmp(argv[0], "lsbest") == 0) { argv++; /* "lsbest" */ while (*argv != NULL) { /* args specified */ const char *basep, *dir; char *p; dir = lsdirp ? lsdirp : dirname_of(*argv); basep = basename_of(*argv); p = find_best_matching_file(dir, basep, use_default_sfx, 1); if (p) { if (show_basename_only) printf("%s\n", p); else printf("%s/%s\n", dir, p); free(p); } argv++; } } else if (strcasecmp(argv[0], "list") == 0 || strcasecmp(argv[0], "dump") == 0) { pkgdb_dump(); } else if (strcasecmp(argv[0], "add") == 0) { struct pkgdb_count count; count.files = 0; count.directories = 0; count.packages = 0; for (++argv; *argv != NULL; ++argv) add_pkg(*argv, &count); } else if (strcasecmp(argv[0], "set") == 0) { argv++; /* "set" */ set_unset_variable(argv, FALSE); } else if (strcasecmp(argv[0], "unset") == 0) { argv++; /* "unset" */ set_unset_variable(argv, TRUE); } else if (strcasecmp(argv[0], "config-var") == 0) { argv++; if (argv == NULL || argv[1] != NULL) errx(EXIT_FAILURE, "config-var takes exactly one argument"); pkg_install_show_variable(argv[0]); } else if (strcasecmp(argv[0], "check-license") == 0) { if (argv[1] == NULL) errx(EXIT_FAILURE, "check-license takes exactly one argument"); load_license_lists(); switch (acceptable_pkg_license(argv[1])) { case 0: puts("no"); return 0; case 1: puts("yes"); return 0; case -1: errx(EXIT_FAILURE, "invalid license condition"); } } else if (strcasecmp(argv[0], "check-single-license") == 0) { if (argv[1] == NULL) errx(EXIT_FAILURE, "check-license takes exactly one argument"); load_license_lists(); switch (acceptable_license(argv[1])) { case 0: puts("no"); return 0; case 1: puts("yes"); return 0; case -1: errx(EXIT_FAILURE, "invalid license"); } } #ifndef BOOTSTRAP else if (strcasecmp(argv[0], "findbest") == 0) { struct url *url; char *output; int rc; process_pkg_path(); rc = 0; for (++argv; *argv != NULL; ++argv) { url = find_best_package(NULL, *argv, 1); if (url == NULL) { rc = 1; continue; } output = fetchStringifyURL(url); puts(output); fetchFreeURL(url); free(output); } return rc; } else if (strcasecmp(argv[0], "fetch-pkg-vulnerabilities") == 0) { fetch_pkg_vulnerabilities(--argc, ++argv); } else if (strcasecmp(argv[0], "check-pkg-vulnerabilities") == 0) { check_pkg_vulnerabilities(--argc, ++argv); } else if (strcasecmp(argv[0], "audit") == 0) { audit_pkgdb(--argc, ++argv); } else if (strcasecmp(argv[0], "audit-pkg") == 0) { audit_pkg(--argc, ++argv); } else if (strcasecmp(argv[0], "audit-batch") == 0) { audit_batch(--argc, ++argv); } else if (strcasecmp(argv[0], "audit-history") == 0) { audit_history(--argc, ++argv); } else if (strcasecmp(argv[0], "check-signature") == 0) { struct archive *pkg; int rc; rc = 0; for (--argc, ++argv; argc > 0; --argc, ++argv) { char *archive_name; pkg = open_archive(*argv, &archive_name); if (pkg == NULL) { warnx("%s could not be opened", *argv); continue; } if (pkg_full_signature_check(archive_name, &pkg)) rc = 1; free(archive_name); if (!pkg) archive_read_finish(pkg); } return rc; } else if (strcasecmp(argv[0], "x509-sign-package") == 0) { #ifdef HAVE_SSL --argc; ++argv; if (argc != 4) errx(EXIT_FAILURE, "x509-sign-package takes exactly four arguments"); pkg_sign_x509(argv[0], argv[1], argv[2], argv[3]); #else errx(EXIT_FAILURE, "OpenSSL support is not included"); #endif } else if (strcasecmp(argv[0], "gpg-sign-package") == 0) { --argc; ++argv; if (argc != 2) errx(EXIT_FAILURE, "gpg-sign-package takes exactly two arguments"); pkg_sign_gpg(argv[0], argv[1]); } #endif else { usage(); } return 0; }
#include "extern.h" #include "pathnames.h" /*- * delete -- * Deletes named members from the archive. */ int delete(char **argv) { CF cf; off_t size; int afd, tfd; char *file; afd = open_archive(O_RDWR); tfd = tmp(); /* Read and write to an archive; pad on both. */ SETCF(afd, archive, tfd, tname, RPAD|WPAD); while (get_arobj(afd)) { if (*argv && (file = files(argv))) { if (options & AR_V) (void)printf("d - %s\n", file); skip_arobj(afd); continue; } put_arobj(&cf, NULL); } size = lseek(tfd, (off_t)0, SEEK_CUR);
void archivebits(double *x, UL q, UL n, UL totalbits, UL b, UL c, double hi, double lo, const char *version_info, FILE *outfp, FILE *dupfp) { FILE *archfp = NULL; archfp = open_archive(); if (is_zero(x, n, 0, 0)) { if (outfp != NULL && !ferror(outfp)) fprintf(outfp, "M( " PRINTF_FMT_UL " )P, n = " PRINTF_FMT_UL ", %s\n", q, n, version_info); if (dupfp != NULL && !ferror(dupfp)) fprintf(dupfp, "M( " PRINTF_FMT_UL " )P, n = " PRINTF_FMT_UL ", %s\n", q, n, version_info); if (archfp != NULL) fprintf(archfp, "M( " PRINTF_FMT_UL " )P, n = " PRINTF_FMT_UL ", %s\n", q, n, version_info); if (archfp != NULL) close_archive(archfp, outfp, dupfp); return; } if (outfp != NULL && !ferror(outfp)) fprintf(outfp, "M( " PRINTF_FMT_UL " )C", q); if (dupfp != NULL && !ferror(dupfp)) fprintf(dupfp, "M( " PRINTF_FMT_UL " )C", q); if (archfp != NULL) fprintf(archfp, "M( " PRINTF_FMT_UL " )C", q); balancedtostdrep(x, n, b, c, hi, lo, 0, 0); static UL *hex = NULL; static UL prior_hex = 0; if (hex != NULL && totalbits/BITS_IN_LONG + 1 > prior_hex) { free(hex); hex = NULL; prior_hex = totalbits/BITS_IN_LONG + 1; } if (hex == NULL && (hex = (UL *)calloc(totalbits/BITS_IN_LONG + 1, sizeof(UL))) == NULL) { perror(program_name); fprintf(stderr, "%s: cannot get memory for residue bits; calloc() errno %d\n", program_name, errno); exit(errno); } int i = 0; int j = 0; do { UL k = (long)(ceil((double)q*(j + 1)/n) - ceil((double)q*j/n)); if (k > totalbits) k = totalbits; totalbits -= k; int word = (long)x[j]; for (j++; k > 0; k--, i++) { if (i % BITS_IN_LONG == 0) hex[i/BITS_IN_LONG] = 0L; hex[i/BITS_IN_LONG] |= ((word & 0x1) << (i % BITS_IN_LONG)); word >>= 1; } } while(totalbits > 0); if (outfp != NULL && !ferror(outfp)) fputs(", 0x", outfp); if (dupfp != NULL && !ferror(dupfp)) fputs(", 0x", dupfp); if (archfp != NULL) fputs(", 0x", archfp); static char bits_fmt[16] = "\0"; /* "%%0%ulx" -> "%08lx" or "%016lx" depending on sizeof(UL) */ if (bits_fmt[0] != '%') sprintf(bits_fmt, "%%0" PRINTF_FMT_UL "%s", (UL)(BITS_IN_LONG/4), "lx"); /* 4 bits per hex 'digit' */ for (j = (i - 1)/BITS_IN_LONG; j >= 0; j--) { if (outfp != NULL && !ferror(outfp)) fprintf(outfp, bits_fmt, hex[j]); if (dupfp != NULL && !ferror(dupfp)) fprintf(dupfp, bits_fmt, hex[j]); if (archfp != NULL) fprintf(archfp, bits_fmt, hex[j]); } if (outfp != NULL && !ferror(outfp)) { fprintf(outfp, ", n = " PRINTF_FMT_UL ", %s", n, version_info); fprintf(outfp, "\n"); fflush(outfp); } if (dupfp != NULL && !ferror(dupfp)) fprintf(dupfp, ", n = " PRINTF_FMT_UL ", %s\n", n, version_info); if (archfp != NULL) { fprintf(archfp, ", n = " PRINTF_FMT_UL ", %s\n", n, version_info); close_archive(archfp, outfp, dupfp); } return; }
static void create_archive (const char *archivefname, struct locarhandle *ah) { int fd; char fname[strlen (archivefname) + sizeof (".XXXXXX")]; struct locarhead head; void *p; size_t total; strcpy (stpcpy (fname, archivefname), ".XXXXXX"); /* Create a temporary file in the correct directory. */ fd = mkstemp (fname); if (fd == -1) error (EXIT_FAILURE, errno, _("cannot create temporary file")); /* Create the initial content of the archive. */ head.magic = AR_MAGIC; head.serial = 0; head.namehash_offset = sizeof (struct locarhead); head.namehash_used = 0; head.namehash_size = next_prime (INITIAL_NUM_NAMES); head.string_offset = (head.namehash_offset + head.namehash_size * sizeof (struct namehashent)); head.string_used = 0; head.string_size = INITIAL_SIZE_STRINGS; head.locrectab_offset = head.string_offset + head.string_size; head.locrectab_used = 0; head.locrectab_size = INITIAL_NUM_LOCREC; head.sumhash_offset = (head.locrectab_offset + head.locrectab_size * sizeof (struct locrecent)); head.sumhash_used = 0; head.sumhash_size = next_prime (INITIAL_NUM_SUMS); total = head.sumhash_offset + head.sumhash_size * sizeof (struct sumhashent); /* Write out the header and create room for the other data structures. */ if (TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head))) != sizeof (head)) { int errval = errno; unlink (fname); error (EXIT_FAILURE, errval, _("cannot initialize archive file")); } if (ftruncate64 (fd, total) != 0) { int errval = errno; unlink (fname); error (EXIT_FAILURE, errval, _("cannot resize archive file")); } /* To prepare for enlargements of the mmaped area reserve some address space. */ size_t reserved = RESERVE_MMAP_SIZE; int xflags = 0; if (total < reserved && ((p = mmap64 (NULL, reserved, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0)) != MAP_FAILED)) xflags = MAP_FIXED; else { p = NULL; reserved = total; } /* Map the header and all the administration data structures. */ p = mmap64 (p, total, PROT_READ | PROT_WRITE, MAP_SHARED | xflags, fd, 0); if (p == MAP_FAILED) { int errval = errno; unlink (fname); error (EXIT_FAILURE, errval, _("cannot map archive header")); } /* Now try to rename it. We don't use the rename function since this would overwrite a file which has been created in parallel. */ if (link (fname, archivefname) == -1) { int errval = errno; /* We cannot use the just created file. */ close (fd); unlink (fname); if (errval == EEXIST) { /* There is already an archive. Must have been a localedef run which happened in parallel. Simply open this file then. */ open_archive (ah, false); return; } error (EXIT_FAILURE, errval, _("failed to create new locale archive")); } /* Remove the temporary name. */ unlink (fname); /* Make the file globally readable. */ if (fchmod (fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1) { int errval = errno; unlink (archivefname); error (EXIT_FAILURE, errval, _("cannot change mode of new locale archive")); } ah->fd = fd; ah->addr = p; ah->mmaped = total; ah->reserved = reserved; }
void delete_archive_members (void) { enum read_header logical_status = HEADER_STILL_UNREAD; enum read_header previous_status = HEADER_STILL_UNREAD; /* FIXME: Should clean the routine before cleaning these variables :-( */ struct name *name; off_t blocks_to_skip = 0; off_t blocks_to_keep = 0; int kept_blocks_in_record; name_gather (); open_archive (ACCESS_UPDATE); acting_as_filter = strcmp (archive_name_array[0], "-") == 0; do { enum read_header status = read_header (true); switch (status) { case HEADER_STILL_UNREAD: abort (); case HEADER_SUCCESS: if ((name = name_scan (current_stat_info.file_name)) == NULL) { skip_member (); break; } name->found_count++; if (!ISFOUND(name)) { skip_member (); break; } /* Fall through. */ case HEADER_SUCCESS_EXTENDED: logical_status = status; break; case HEADER_ZERO_BLOCK: if (ignore_zeros_option) { set_next_block_after (current_header); break; } /* Fall through. */ case HEADER_END_OF_FILE: logical_status = HEADER_END_OF_FILE; break; case HEADER_FAILURE: set_next_block_after (current_header); switch (previous_status) { case HEADER_STILL_UNREAD: WARN ((0, 0, _("This does not look like a tar archive"))); /* Fall through. */ case HEADER_SUCCESS: case HEADER_SUCCESS_EXTENDED: case HEADER_ZERO_BLOCK: ERROR ((0, 0, _("Skipping to next header"))); /* Fall through. */ case HEADER_FAILURE: break; case HEADER_END_OF_FILE: abort (); } break; } previous_status = status; } while (logical_status == HEADER_STILL_UNREAD); records_skipped = records_read - 1; new_record = xmalloc (record_size); if (logical_status == HEADER_SUCCESS || logical_status == HEADER_SUCCESS_EXTENDED) { write_archive_to_stdout = false; /* Save away blocks before this one in this record. */ new_blocks = current_block - record_start; if (new_blocks) memcpy (new_record, record_start, new_blocks * BLOCKSIZE); if (logical_status == HEADER_SUCCESS) { /* FIXME: Pheew! This is crufty code! */ logical_status = HEADER_STILL_UNREAD; goto flush_file; } /* FIXME: Solaris 2.4 Sun cc (the ANSI one, not the old K&R) says: "delete.c", line 223: warning: loop not entered at top Reported by Bruno Haible. */ while (1) { enum read_header status; /* Fill in a record. */ if (current_block == record_end) flush_archive (); status = read_header (false); xheader_decode (¤t_stat_info); if (status == HEADER_ZERO_BLOCK && ignore_zeros_option) { set_next_block_after (current_header); continue; } if (status == HEADER_END_OF_FILE || status == HEADER_ZERO_BLOCK) { logical_status = HEADER_END_OF_FILE; break; } if (status == HEADER_FAILURE) { ERROR ((0, 0, _("Deleting non-header from archive"))); set_next_block_after (current_header); continue; } /* Found another header. */ if ((name = name_scan (current_stat_info.file_name)) != NULL) { name->found_count++; if (ISFOUND(name)) { flush_file: set_next_block_after (current_header); blocks_to_skip = (current_stat_info.stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE; while (record_end - current_block <= blocks_to_skip) { blocks_to_skip -= (record_end - current_block); flush_archive (); } current_block += blocks_to_skip; blocks_to_skip = 0; continue; } } /* Copy header. */ if (extended_header.size) { write_recent_bytes (extended_header.buffer, extended_header.size); } else { write_recent_blocks (recent_long_name, recent_long_name_blocks); write_recent_blocks (recent_long_link, recent_long_link_blocks); } new_record[new_blocks] = *current_header; new_blocks++; blocks_to_keep = (current_stat_info.stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE; set_next_block_after (current_header); if (new_blocks == blocking_factor) write_record (1); /* Copy data. */ kept_blocks_in_record = record_end - current_block; if (kept_blocks_in_record > blocks_to_keep) kept_blocks_in_record = blocks_to_keep; while (blocks_to_keep) { int count; if (current_block == record_end) { flush_read (); current_block = record_start; kept_blocks_in_record = blocking_factor; if (kept_blocks_in_record > blocks_to_keep) kept_blocks_in_record = blocks_to_keep; } count = kept_blocks_in_record; if (blocking_factor - new_blocks < count) count = blocking_factor - new_blocks; if (! count) abort (); memcpy (new_record + new_blocks, current_block, count * BLOCKSIZE); new_blocks += count; current_block += count; blocks_to_keep -= count; kept_blocks_in_record -= count; if (new_blocks == blocking_factor) write_record (1); } } if (logical_status == HEADER_END_OF_FILE) { /* Write the end of tape. FIXME: we can't use write_eot here, as it gets confused when the input is at end of file. */ int total_zero_blocks = 0; do { int zero_blocks = blocking_factor - new_blocks; memset (new_record + new_blocks, 0, BLOCKSIZE * zero_blocks); total_zero_blocks += zero_blocks; write_record (total_zero_blocks < 2); } while (total_zero_blocks < 2); } if (! acting_as_filter && ! _isrmt (archive)) { if (sys_truncate (archive)) truncate_warn (archive_name_array[0]); } } free (new_record); close_archive (); names_notfound (); }
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); }
void read_and (void (*do_something) ()) { enum read_header status = HEADER_STILL_UNREAD; enum read_header prev_status; char save_typeflag; name_gather (); open_archive (ACCESS_READ); while (1) { prev_status = status; status = read_header (); switch (status) { case HEADER_STILL_UNREAD: abort (); case HEADER_SUCCESS: /* Valid header. We should decode next field (mode) first. Ensure incoming names are null terminated. */ /* FIXME: This is a quick kludge before 1.12 goes out. */ current_stat.st_mtime = from_oct (1 + 12, current_header->header.mtime); if (!name_match (current_file_name) || current_stat.st_mtime < newer_mtime_option || (exclude_option && check_exclude (current_file_name))) { int isextended = 0; if (current_header->header.typeflag == GNUTYPE_VOLHDR || current_header->header.typeflag == GNUTYPE_MULTIVOL || current_header->header.typeflag == GNUTYPE_NAMES) { (*do_something) (); continue; } if (show_omitted_dirs_option && current_header->header.typeflag == DIRTYPE) WARN ((0, 0, _("Omitting %s"), current_file_name)); /* Skip past it in the archive. */ if (current_header->oldgnu_header.isextended) isextended = 1; save_typeflag = current_header->header.typeflag; set_next_block_after (current_header); if (isextended) { #if 0 union block *exhdr; while (1) { exhdr = find_next_block (); if (!exhdr->sparse_header.isextended) { set_next_block_after (exhdr); break; } } set_next_block_after (exhdr); #endif skip_extended_headers (); } /* Skip to the next header on the archive. */ if (save_typeflag != DIRTYPE) skip_file ((long long) current_stat.st_size); continue; } (*do_something) (); continue; case HEADER_ZERO_BLOCK: if (block_number_option) fprintf (stdlis, _("block %10ld: ** Block of NULs **\n"), current_block_ordinal ()); set_next_block_after (current_header); status = prev_status; if (ignore_zeros_option) continue; break; case HEADER_END_OF_FILE: if (block_number_option) fprintf (stdlis, _("block %10ld: ** End of File **\n"), current_block_ordinal ()); break; case HEADER_FAILURE: /* If the previous header was good, tell them that we are skipping bad ones. */ set_next_block_after (current_header); switch (prev_status) { case HEADER_STILL_UNREAD: WARN ((0, 0, _("Could not extract file(s); file might not be a tar archive"))); /* Fall through. */ case HEADER_ZERO_BLOCK: case HEADER_SUCCESS: WARN ((0, 0, _("Skipping to next file header"))); break; case HEADER_END_OF_FILE: case HEADER_FAILURE: /* We are in the middle of a cascade of errors. */ break; } continue; } break; } apply_delayed_set_stat (); close_archive (); names_notfound (); /* print names not found */ }
void delete_archive_members (void) { enum read_header logical_status = HEADER_STILL_UNREAD; enum read_header previous_status = HEADER_STILL_UNREAD; /* FIXME: Should clean the routine before cleaning these variables :-( */ struct name *name; int blocks_to_skip = 0; int blocks_to_keep = 0; int kept_blocks_in_record; name_gather (); open_archive (ACCESS_UPDATE); while (logical_status == HEADER_STILL_UNREAD) { enum read_header status = read_header (); switch (status) { case HEADER_STILL_UNREAD: abort (); case HEADER_SUCCESS: if (name = name_scan (current_file_name), !name) { set_next_block_after (current_header); if (current_header->oldgnu_header.isextended) skip_extended_headers (); skip_file ((long) (current_stat.st_size)); break; } name->found = 1; logical_status = HEADER_SUCCESS; break; case HEADER_ZERO_BLOCK: case HEADER_END_OF_FILE: logical_status = HEADER_END_OF_FILE; break; case HEADER_FAILURE: set_next_block_after (current_header); switch (previous_status) { case HEADER_STILL_UNREAD: WARN ((0, 0, _("This does not look like a tar archive"))); /* Fall through. */ case HEADER_SUCCESS: case HEADER_ZERO_BLOCK: ERROR ((0, 0, _("Skipping to next header"))); /* Fall through. */ case HEADER_FAILURE: break; case HEADER_END_OF_FILE: abort (); } break; } previous_status = status; } if (logical_status != HEADER_SUCCESS) { write_eot (); close_archive (); names_notfound (); return; } write_archive_to_stdout = 0; new_record = (union block *) xmalloc ((size_t) record_size); /* Save away blocks before this one in this record. */ new_blocks = current_block - record_start; blocks_needed = blocking_factor - new_blocks; if (new_blocks) memcpy ((void *) new_record, (void *) record_start, (size_t) (new_blocks * BLOCKSIZE)); #if 0 /* FIXME: Old code, before the goto was inserted. To be redesigned. */ set_next_block_after (current_header); if (current_header->oldgnu_header.isextended) skip_extended_headers (); skip_file ((long) (current_stat.st_size)); #endif logical_status = HEADER_STILL_UNREAD; goto flush_file; /* FIXME: Solaris 2.4 Sun cc (the ANSI one, not the old K&R) says: "delete.c", line 223: warning: loop not entered at top Reported by Bruno Haible. */ while (1) { enum read_header status; /* Fill in a record. */ if (current_block == record_end) { flush_archive (); records_read++; } status = read_header (); if (status == HEADER_ZERO_BLOCK && ignore_zeros_option) { set_next_block_after (current_header); continue; } if (status == HEADER_END_OF_FILE || status == HEADER_ZERO_BLOCK) { logical_status = HEADER_END_OF_FILE; memset (new_record[new_blocks].buffer, 0, (size_t) (BLOCKSIZE * blocks_needed)); new_blocks += blocks_needed; blocks_needed = 0; write_record (0); break; } if (status == HEADER_FAILURE) { ERROR ((0, 0, _("Deleting non-header from archive"))); set_next_block_after (current_header); continue; } /* Found another header. */ if (name = name_scan (current_file_name), name) { name->found = 1; flush_file: set_next_block_after (current_header); blocks_to_skip = (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE; while (record_end - current_block <= blocks_to_skip) { blocks_to_skip -= (record_end - current_block); flush_archive (); records_read++; } current_block += blocks_to_skip; blocks_to_skip = 0; continue; } /* Copy header. */ new_record[new_blocks] = *current_header; new_blocks++; blocks_needed--; blocks_to_keep = (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE; set_next_block_after (current_header); if (blocks_needed == 0) write_record (1); /* Copy data. */ kept_blocks_in_record = record_end - current_block; if (kept_blocks_in_record > blocks_to_keep) kept_blocks_in_record = blocks_to_keep; while (blocks_to_keep) { int count; if (current_block == record_end) { flush_read (); records_read++; current_block = record_start; kept_blocks_in_record = blocking_factor; if (kept_blocks_in_record > blocks_to_keep) kept_blocks_in_record = blocks_to_keep; } count = kept_blocks_in_record; if (count > blocks_needed) count = blocks_needed; memcpy ((void *) (new_record + new_blocks), (void *) current_block, (size_t) (count * BLOCKSIZE)); new_blocks += count; blocks_needed -= count; current_block += count; blocks_to_keep -= count; kept_blocks_in_record -= count; if (blocks_needed == 0) write_record (1); } } write_eot (); close_archive (); names_notfound (); }
/* * 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); }
/* Implement the 'r' (add files to end of archive), and 'u' (add files to end of archive if they aren't there, or are more up to date than the version in the archive) commands. */ void update_archive (void) { enum read_header previous_status = HEADER_STILL_UNREAD; bool found_end = false; name_gather (); open_archive (ACCESS_UPDATE); xheader_write_global (); while (!found_end) { enum read_header status = read_header (false); switch (status) { case HEADER_STILL_UNREAD: case HEADER_SUCCESS_EXTENDED: abort (); case HEADER_SUCCESS: { struct name *name; decode_header (current_header, ¤t_stat_info, ¤t_format, 0); archive_format = current_format; if (subcommand_option == UPDATE_SUBCOMMAND && (name = name_scan (current_stat_info.file_name)) != NULL) { struct stat s; chdir_do (name->change_dir); if (deref_stat (dereference_option, current_stat_info.file_name, &s) == 0 && s.st_mtime <= current_stat_info.stat.st_mtime) add_avoided_name (current_stat_info.file_name); } skip_member (); break; } case HEADER_ZERO_BLOCK: current_block = current_header; found_end = true; break; case HEADER_END_OF_FILE: found_end = true; break; case HEADER_FAILURE: set_next_block_after (current_header); switch (previous_status) { case HEADER_STILL_UNREAD: WARN ((0, 0, _("This does not look like a tar archive"))); /* Fall through. */ case HEADER_SUCCESS: case HEADER_ZERO_BLOCK: ERROR ((0, 0, _("Skipping to next header"))); /* Fall through. */ case HEADER_FAILURE: break; case HEADER_END_OF_FILE: case HEADER_SUCCESS_EXTENDED: abort (); } break; } tar_stat_destroy (¤t_stat_info); xheader_destroy (&extended_header); previous_status = status; } reset_eof (); time_to_start_writing = true; output_start = current_block->buffer; { char *file_name; while ((file_name = name_from_list ()) != NULL) { if (excluded_name (file_name)) continue; if (interactive_option && !confirm ("add", file_name)) continue; if (subcommand_option == CAT_SUBCOMMAND) append_file (file_name); else dump_file (file_name, 1, (dev_t) 0); } } write_eot (); close_archive (); names_notfound (); }
void delete_archive_members (void) { enum read_header logical_status = HEADER_STILL_UNREAD; enum read_header previous_status = HEADER_STILL_UNREAD; /* FIXME: Should clean the routine before cleaning these variables :-( */ struct name *name; off_t blocks_to_skip = 0; off_t blocks_to_keep = 0; int kept_blocks_in_record; name_gather (); open_archive (ACCESS_UPDATE); acting_as_filter = strcmp (archive_name_array[0], "-") == 0; do { enum read_header status = read_header (); switch (status) { case HEADER_STILL_UNREAD: abort (); case HEADER_SUCCESS: if (name = name_scan (current_file_name), !name) { skip_member (); break; } name->found = 1; logical_status = HEADER_SUCCESS; break; case HEADER_ZERO_BLOCK: if (ignore_zeros_option) { set_next_block_after (current_header); break; } /* Fall through. */ case HEADER_END_OF_FILE: logical_status = HEADER_END_OF_FILE; break; case HEADER_FAILURE: set_next_block_after (current_header); switch (previous_status) { case HEADER_STILL_UNREAD: WARN ((0, 0, _("This does not look like a tar archive"))); /* Fall through. */ case HEADER_SUCCESS: case HEADER_ZERO_BLOCK: ERROR ((0, 0, _("Skipping to next header"))); /* Fall through. */ case HEADER_FAILURE: break; case HEADER_END_OF_FILE: abort (); } break; } previous_status = status; } while (logical_status == HEADER_STILL_UNREAD); new_record = xmalloc (record_size); if (logical_status == HEADER_SUCCESS) { write_archive_to_stdout = 0; /* Save away blocks before this one in this record. */ new_blocks = current_block - record_start; if (new_blocks) memcpy (new_record, record_start, new_blocks * BLOCKSIZE); #if 0 /* FIXME: Old code, before the goto was inserted. To be redesigned. */ skip_member (); #endif logical_status = HEADER_STILL_UNREAD; goto flush_file; /* FIXME: Solaris 2.4 Sun cc (the ANSI one, not the old K&R) says: "delete.c", line 223: warning: loop not entered at top Reported by Bruno Haible. */ while (1) { enum read_header status; /* Fill in a record. */ if (current_block == record_end) { flush_archive (); records_read++; } status = read_header (); if (status == HEADER_ZERO_BLOCK && ignore_zeros_option) { set_next_block_after (current_header); continue; } if (status == HEADER_END_OF_FILE || status == HEADER_ZERO_BLOCK) { logical_status = HEADER_END_OF_FILE; break; } if (status == HEADER_FAILURE) { ERROR ((0, 0, _("Deleting non-header from archive"))); set_next_block_after (current_header); continue; } /* Found another header. */ if (name = name_scan (current_file_name), name) { name->found = 1; flush_file: set_next_block_after (current_header); blocks_to_skip = (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE; while (record_end - current_block <= blocks_to_skip) { blocks_to_skip -= (record_end - current_block); flush_archive (); records_read++; } current_block += blocks_to_skip; blocks_to_skip = 0; continue; } /* Copy header. */ new_record[new_blocks] = *current_header; new_blocks++; blocks_to_keep = (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE; set_next_block_after (current_header); if (new_blocks == blocking_factor) write_record (1); /* Copy data. */ kept_blocks_in_record = record_end - current_block; if (kept_blocks_in_record > blocks_to_keep) kept_blocks_in_record = blocks_to_keep; while (blocks_to_keep) { int count; if (current_block == record_end) { flush_read (); records_read++; current_block = record_start; kept_blocks_in_record = blocking_factor; if (kept_blocks_in_record > blocks_to_keep) kept_blocks_in_record = blocks_to_keep; } count = kept_blocks_in_record; if (blocking_factor - new_blocks < count) count = blocking_factor - new_blocks; if (! count) abort (); memcpy (new_record + new_blocks, current_block, count * BLOCKSIZE); new_blocks += count; current_block += count; blocks_to_keep -= count; kept_blocks_in_record -= count; if (new_blocks == blocking_factor) write_record (1); } } } if (logical_status == HEADER_END_OF_FILE) { /* Write the end of tape. FIXME: we can't use write_eot here, as it gets confused when the input is at end of file. */ int total_zero_blocks = 0; do { int zero_blocks = blocking_factor - new_blocks; memset (new_record + new_blocks, 0, BLOCKSIZE * zero_blocks); total_zero_blocks += zero_blocks; write_record (total_zero_blocks < 2); } while (total_zero_blocks < 2); } free (new_record); if (! acting_as_filter && ! _isrmt (archive)) { #if MSDOS int status = write (archive, "", 0); #else off_t pos = lseek (archive, (off_t) 0, SEEK_CUR); int status = pos < 0 ? -1 : ftruncate (archive, pos); #endif if (status != 0) truncate_warn (archive_name_array[0]); } close_archive (); names_notfound (); }
int main(int argc, char** argv) { // Print an error if the user invokes Far with an incorrect number of // arguments. There should be at least "Far key archive" if (argc < 3) { ERROR("Usage: Far key archive [name]*"); return 1; } char* key = argv[1]; char* archive_name = argv[2]; int num_files = argc - 3; char** filenames = argv + 3; // Ignore trailing / in NAME arguments for (int i = 0; i < num_files; i++) strip_trailing_slash(filenames[i]); if (!strcmp(key, "r")) { member_list* members = make_list_recursive(filenames, num_files); archive_t* archive = open_archive(archive_name, true); member_list* processed_members = process_members(archive, members, replace_current_member); // Now that previously existing files have been deleted, add the // files to the end of the archive member_node* cur_member = members; while (cur_member) { add_member(archive, cur_member->filename); cur_member = cur_member->next; } delete_list(processed_members); close_archive(archive, true); delete_list(members); return 0; } else if (!strcmp(key, "x")) { member_list* members = make_list(filenames, num_files); archive_t* archive = open_archive(archive_name, false); member_list* processed_members = process_members(archive, members, extract_current_member); // Error handling for unprocessed NAME arguments for (int i = 0; i < num_files; i++) { char* name = filenames[i]; if (!find_member(name, processed_members)) { ERROR_CREATE(name); } } delete_list(processed_members); close_archive(archive, false); delete_list(members); return 0; } else if (!strcmp(key, "d")) { member_list* members = make_list(filenames, num_files); archive_t* archive = open_archive(archive_name, false); member_list* processed_members = process_members(archive, members, delete_current_member); // Error handling for unprocessed NAME arguments for (int i = 0; i < num_files; i++) { char* name = filenames[i]; if (!find_member(name, processed_members) && !find_child(name, processed_members)) { ERROR_FIND(name); } } delete_list(processed_members); close_archive(archive, true); delete_list(members); return 0; } else if (!strcmp(key, "t")) { archive_t* archive = open_archive(archive_name, false); member_list* processed_members = process_members(archive, NULL, print_current_member); delete_list(processed_members); close_archive(archive, false); return 0; } else { ERROR("Key options: 'r', 'x', 'd', 't'"); return 1; } }
///===================================================================================== Archive Archive::Archive(const Lib & lib, const ustring & path) { LogNoise(L"%p, '%s', 0x%Iu\n", &lib, path.c_str()); open_archive(lib, path); init_props(); }