static void test_linkify_old_cpio(void) { struct archive_entry *entry, *e2; struct archive_entry_linkresolver *resolver; /* Initialize the resolver. */ assert(NULL != (resolver = archive_entry_linkresolver_new())); archive_entry_linkresolver_set_strategy(resolver, ARCHIVE_FORMAT_CPIO_POSIX); /* Create an entry with 2 link and try to linkify it. */ assert(NULL != (entry = archive_entry_new())); archive_entry_set_pathname(entry, "test1"); archive_entry_set_ino(entry, 1); archive_entry_set_dev(entry, 2); archive_entry_set_nlink(entry, 2); archive_entry_set_size(entry, 10); archive_entry_linkify(resolver, &entry, &e2); /* Shouldn't have been changed. */ assert(e2 == NULL); assertEqualInt(10, archive_entry_size(entry)); assertEqualString("test1", archive_entry_pathname(entry)); /* Still shouldn't be matched. */ archive_entry_linkify(resolver, &entry, &e2); assert(e2 == NULL); assertEqualString("test1", archive_entry_pathname(entry)); assertEqualString(NULL, archive_entry_hardlink(entry)); assertEqualInt(10, archive_entry_size(entry)); archive_entry_free(entry); archive_entry_linkresolver_free(resolver); }
static int cleanup(struct archive_read *a) { struct mtree *mtree; struct mtree_entry *p, *q; mtree = (struct mtree *)(a->format->data); p = mtree->entries; while (p != NULL) { q = p->next; free(p->name); free_options(p->options); free(p); p = q; } archive_string_free(&mtree->line); archive_string_free(&mtree->current_dir); archive_string_free(&mtree->contents_name); archive_entry_linkresolver_free(mtree->resolver); free(mtree->buff); free(mtree); (a->format->data) = NULL; return (ARCHIVE_OK); }
static void mode_pass(struct cpio *cpio, const char *destdir) { struct lafe_line_reader *lr; const char *p; int r; /* Ensure target dir has a trailing '/' to simplify path surgery. */ cpio->destdir = malloc(strlen(destdir) + 8); strcpy(cpio->destdir, destdir); if (destdir[strlen(destdir) - 1] != '/') strcat(cpio->destdir, "/"); cpio->archive = archive_write_disk_new(); if (cpio->archive == NULL) lafe_errc(1, 0, "Failed to allocate archive object"); r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags); if (r != ARCHIVE_OK) lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); cpio->linkresolver = archive_entry_linkresolver_new(); archive_write_disk_set_standard_lookup(cpio->archive); cpio->archive_read_disk = archive_read_disk_new(); if (cpio->archive_read_disk == NULL) lafe_errc(1, 0, "Failed to allocate archive object"); if (cpio->option_follow_links) archive_read_disk_set_symlink_logical(cpio->archive_read_disk); else archive_read_disk_set_symlink_physical(cpio->archive_read_disk); archive_read_disk_set_standard_lookup(cpio->archive_read_disk); lr = lafe_line_reader("-", cpio->option_null); while ((p = lafe_line_reader_next(lr)) != NULL) file_to_archive(cpio, p); lafe_line_reader_free(lr); archive_entry_linkresolver_free(cpio->linkresolver); r = archive_write_close(cpio->archive); if (cpio->dot) fprintf(stderr, "\n"); if (r != ARCHIVE_OK) lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); if (!cpio->quiet) { int64_t blocks = (archive_filter_bytes(cpio->archive, 0) + 511) / 512; fprintf(stderr, "%lu %s\n", (unsigned long)blocks, blocks == 1 ? "block" : "blocks"); } archive_write_free(cpio->archive); }
static void mode_pass(struct cpio *cpio, const char *destdir) { unsigned long blocks; struct line_reader *lr; const char *p; int r; /* Ensure target dir has a trailing '/' to simplify path surgery. */ cpio->destdir = malloc(strlen(destdir) + 8); strcpy(cpio->destdir, destdir); if (destdir[strlen(destdir) - 1] != '/') strcat(cpio->destdir, "/"); cpio->archive = archive_write_disk_new(); if (cpio->archive == NULL) cpio_errc(1, 0, "Failed to allocate archive object"); r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags); if (r != ARCHIVE_OK) cpio_errc(1, 0, archive_error_string(cpio->archive)); cpio->linkresolver = archive_entry_linkresolver_new(); archive_write_disk_set_standard_lookup(cpio->archive); lr = process_lines_init("-", cpio->line_separator); while ((p = process_lines_next(lr)) != NULL) file_to_archive(cpio, p); process_lines_free(lr); archive_entry_linkresolver_free(cpio->linkresolver); r = archive_write_close(cpio->archive); if (r != ARCHIVE_OK) cpio_errc(1, 0, archive_error_string(cpio->archive)); if (!cpio->quiet) { blocks = (archive_position_uncompressed(cpio->archive) + 511) / 512; fprintf(stderr, "%lu %s\n", blocks, blocks == 1 ? "block" : "blocks"); } archive_write_finish(cpio->archive); }
static void make_dist(const char *pkg, const char *suffix, const package_t *plist) { char *archive_name; const char *owner, *group; const plist_t *p; struct archive *archive; struct archive_entry *entry, *sparse_entry; struct archive_entry_linkresolver *resolver; char *initial_cwd; archive = archive_write_new(); archive_write_set_format_pax_restricted(archive); if ((resolver = archive_entry_linkresolver_new()) == NULL) errx(2, "cannot create link resolver"); archive_entry_linkresolver_set_strategy(resolver, archive_format(archive)); if (CompressionType == NULL) { if (strcmp(suffix, "tbz") == 0 || strcmp(suffix, "tar.bz2") == 0) CompressionType = "bzip2"; else if (strcmp(suffix, "tgz") == 0 || strcmp(suffix, "tar.gz") == 0) CompressionType = "gzip"; else CompressionType = "none"; } if (strcmp(CompressionType, "bzip2") == 0) archive_write_set_compression_bzip2(archive); else if (strcmp(CompressionType, "gzip") == 0) archive_write_set_compression_gzip(archive); else if (strcmp(CompressionType, "xz") == 0) archive_write_set_compression_xz(archive); else if (strcmp(CompressionType, "none") == 0) archive_write_set_compression_none(archive); else errx(1, "Unspported compression type for -F: %s", CompressionType); archive_name = xasprintf("%s.%s", pkg, suffix); if (archive_write_open_file(archive, archive_name)) errx(2, "cannot create archive: %s", archive_error_string(archive)); free(archive_name); owner = DefaultOwner; group = DefaultGroup; write_meta_file(contents_file, archive); write_meta_file(comment_file, archive); write_meta_file(desc_file, archive); if (Install) write_meta_file(install_file, archive); if (DeInstall) write_meta_file(deinstall_file, archive); if (Display) write_meta_file(display_file, archive); if (BuildVersion) write_meta_file(build_version_file, archive); if (BuildInfo) write_meta_file(build_info_file, archive); if (SizePkg) write_meta_file(size_pkg_file, archive); if (SizeAll) write_meta_file(size_all_file, archive); if (Preserve) write_meta_file(preserve_file, archive); if (create_views) write_meta_file(views_file, archive); initial_cwd = getcwd(NULL, 0); for (p = plist->head; p; p = p->next) { if (p->type == PLIST_FILE) { write_normal_file(p->name, archive, resolver, owner, group); } else if (p->type == PLIST_CWD) { chdir(p->name); } else if (p->type == PLIST_IGNORE) { p = p->next; } else if (p->type == PLIST_CHOWN) { if (p->name != NULL) owner = p->name; else owner = DefaultOwner; } else if (p->type == PLIST_CHGRP) { if (p->name != NULL) group = p->name; else group = DefaultGroup; } } entry = NULL; archive_entry_linkify(resolver, &entry, &sparse_entry); while (entry != NULL) { write_entry(archive, entry); entry = NULL; archive_entry_linkify(resolver, &entry, &sparse_entry); } archive_entry_linkresolver_free(resolver); if (archive_write_close(archive)) errx(2, "cannot finish archive: %s", archive_error_string(archive)); archive_write_finish(archive); free(initial_cwd); }
/* * Write user-specified files/dirs to opened archive. */ static void write_archive(struct archive *a, struct bsdtar *bsdtar) { const char *arg; struct archive_entry *entry, *sparse_entry; /* Choose a suitable copy buffer size */ bsdtar->buff_size = 64 * 1024; while (bsdtar->buff_size < (size_t)bsdtar->bytes_per_block) bsdtar->buff_size *= 2; /* Try to compensate for space we'll lose to alignment. */ bsdtar->buff_size += 16 * 1024; /* Allocate a buffer for file data. */ if ((bsdtar->buff = malloc(bsdtar->buff_size)) == NULL) lafe_errc(1, 0, "cannot allocate memory"); if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) lafe_errc(1, 0, "cannot create link resolver"); archive_entry_linkresolver_set_strategy(bsdtar->resolver, archive_format(a)); /* Create a read_disk object. */ if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) lafe_errc(1, 0, "Cannot create read_disk object"); /* Tell the read_disk how handle symlink. */ switch (bsdtar->symlink_mode) { case 'H': archive_read_disk_set_symlink_hybrid(bsdtar->diskreader); break; case 'L': archive_read_disk_set_symlink_logical(bsdtar->diskreader); break; default: archive_read_disk_set_symlink_physical(bsdtar->diskreader); break; } /* Register entry filters. */ archive_read_disk_set_matching(bsdtar->diskreader, bsdtar->matching, excluded_callback, bsdtar); archive_read_disk_set_metadata_filter_callback( bsdtar->diskreader, metadata_filter, bsdtar); /* Set the behavior of archive_read_disk. */ archive_read_disk_set_behavior(bsdtar->diskreader, bsdtar->readdisk_flags); archive_read_disk_set_standard_lookup(bsdtar->diskreader); if (bsdtar->names_from_file != NULL) archive_names_from_file(bsdtar, a); while (*bsdtar->argv) { arg = *bsdtar->argv; if (arg[0] == '-' && arg[1] == 'C') { arg += 2; if (*arg == '\0') { bsdtar->argv++; arg = *bsdtar->argv; if (arg == NULL) { lafe_warnc(0, "%s", "Missing argument for -C"); bsdtar->return_value = 1; goto cleanup; } if (*arg == '\0') { lafe_warnc(0, "Meaningless argument for -C: ''"); bsdtar->return_value = 1; goto cleanup; } } set_chdir(bsdtar, arg); } else { if (*arg != '/' && (arg[0] != '@' || arg[1] != '/')) do_chdir(bsdtar); /* Handle a deferred -C */ if (*arg == '@') { if (append_archive_filename(bsdtar, a, arg + 1) != 0) break; } else write_hierarchy(bsdtar, a, arg); } bsdtar->argv++; } archive_read_disk_set_matching(bsdtar->diskreader, NULL, NULL, NULL); archive_read_disk_set_metadata_filter_callback( bsdtar->diskreader, NULL, NULL); entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); while (entry != NULL) { int r; struct archive_entry *entry2; struct archive *disk = bsdtar->diskreader; /* * This tricky code here is to correctly read the cotents * of the entry because the disk reader bsdtar->diskreader * is pointing at does not have any information about the * entry by this time and using archive_read_data_block() * with the disk reader consequently must fail. And we * have to re-open the entry to read the contents. */ /* TODO: Work with -C option as well. */ r = archive_read_disk_open(disk, archive_entry_sourcepath(entry)); if (r != ARCHIVE_OK) { lafe_warnc(archive_errno(disk), "%s", archive_error_string(disk)); bsdtar->return_value = 1; archive_entry_free(entry); continue; } /* * Invoke archive_read_next_header2() to work * archive_read_data_block(), which is called via write_file(), * without failure. */ entry2 = archive_entry_new(); r = archive_read_next_header2(disk, entry2); archive_entry_free(entry2); if (r != ARCHIVE_OK) { lafe_warnc(archive_errno(disk), "%s", archive_error_string(disk)); if (r == ARCHIVE_FATAL) bsdtar->return_value = 1; else archive_read_close(disk); archive_entry_free(entry); continue; } write_file(bsdtar, a, entry); archive_entry_free(entry); archive_read_close(disk); entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); } if (archive_write_close(a)) { lafe_warnc(0, "%s", archive_error_string(a)); bsdtar->return_value = 1; } cleanup: /* Free file data buffer. */ free(bsdtar->buff); archive_entry_linkresolver_free(bsdtar->resolver); bsdtar->resolver = NULL; archive_read_free(bsdtar->diskreader); bsdtar->diskreader = NULL; if (bsdtar->option_totals) { fprintf(stderr, "Total bytes written: %s\n", tar_i64toa(archive_filter_bytes(a, -1))); } archive_write_free(a); }
static void test_linkify_tar(void) { struct archive_entry *entry, *e2; struct archive_entry_linkresolver *resolver; /* Initialize the resolver. */ assert(NULL != (resolver = archive_entry_linkresolver_new())); archive_entry_linkresolver_set_strategy(resolver, ARCHIVE_FORMAT_TAR_USTAR); /* Create an entry with only 1 link and try to linkify it. */ assert(NULL != (entry = archive_entry_new())); archive_entry_set_pathname(entry, "test1"); archive_entry_set_ino(entry, 1); archive_entry_set_dev(entry, 2); archive_entry_set_nlink(entry, 1); archive_entry_set_size(entry, 10); archive_entry_linkify(resolver, &entry, &e2); /* Shouldn't have been changed. */ assert(e2 == NULL); assertEqualInt(10, archive_entry_size(entry)); assertEqualString("test1", archive_entry_pathname(entry)); /* Now, try again with an entry that has 2 links. */ archive_entry_set_pathname(entry, "test2"); archive_entry_set_nlink(entry, 2); archive_entry_set_ino(entry, 2); archive_entry_linkify(resolver, &entry, &e2); /* Shouldn't be altered, since it wasn't seen before. */ assert(e2 == NULL); assertEqualString("test2", archive_entry_pathname(entry)); assertEqualString(NULL, archive_entry_hardlink(entry)); assertEqualInt(10, archive_entry_size(entry)); /* Match again and make sure it does get altered. */ archive_entry_linkify(resolver, &entry, &e2); assert(e2 == NULL); assertEqualString("test2", archive_entry_pathname(entry)); assertEqualString("test2", archive_entry_hardlink(entry)); assertEqualInt(0, archive_entry_size(entry)); /* Dirs should never be matched as hardlinks, regardless. */ archive_entry_set_pathname(entry, "test3"); archive_entry_set_nlink(entry, 2); archive_entry_set_filetype(entry, AE_IFDIR); archive_entry_set_ino(entry, 3); archive_entry_set_hardlink(entry, NULL); archive_entry_linkify(resolver, &entry, &e2); /* Shouldn't be altered, since it wasn't seen before. */ assert(e2 == NULL); assertEqualString("test3", archive_entry_pathname(entry)); assertEqualString(NULL, archive_entry_hardlink(entry)); /* Dir, so it shouldn't get matched. */ archive_entry_linkify(resolver, &entry, &e2); assert(e2 == NULL); assertEqualString("test3", archive_entry_pathname(entry)); assertEqualString(NULL, archive_entry_hardlink(entry)); archive_entry_free(entry); archive_entry_linkresolver_free(resolver); }
static void test_linkify_new_cpio(void) { struct archive_entry *entry, *e2; struct archive_entry_linkresolver *resolver; /* Initialize the resolver. */ assert(NULL != (resolver = archive_entry_linkresolver_new())); archive_entry_linkresolver_set_strategy(resolver, ARCHIVE_FORMAT_CPIO_SVR4_NOCRC); /* Create an entry with only 1 link and try to linkify it. */ assert(NULL != (entry = archive_entry_new())); archive_entry_set_pathname(entry, "test1"); archive_entry_set_ino(entry, 1); archive_entry_set_dev(entry, 2); archive_entry_set_nlink(entry, 1); archive_entry_set_size(entry, 10); archive_entry_linkify(resolver, &entry, &e2); /* Shouldn't have been changed. */ assert(e2 == NULL); assertEqualInt(10, archive_entry_size(entry)); assertEqualString("test1", archive_entry_pathname(entry)); /* Now, try again with an entry that has 3 links. */ archive_entry_set_pathname(entry, "test2"); archive_entry_set_nlink(entry, 3); archive_entry_set_ino(entry, 2); archive_entry_linkify(resolver, &entry, &e2); /* First time, it just gets swallowed. */ assert(entry == NULL); assert(e2 == NULL); /* Match again. */ assert(NULL != (entry = archive_entry_new())); archive_entry_set_pathname(entry, "test3"); archive_entry_set_ino(entry, 2); archive_entry_set_dev(entry, 2); archive_entry_set_nlink(entry, 2); archive_entry_set_size(entry, 10); archive_entry_linkify(resolver, &entry, &e2); /* Should get back "test2" and nothing else. */ assertEqualString("test2", archive_entry_pathname(entry)); assertEqualInt(0, archive_entry_size(entry)); archive_entry_free(entry); assert(NULL == e2); archive_entry_free(e2); /* This should be a no-op. */ /* Match a third time. */ assert(NULL != (entry = archive_entry_new())); archive_entry_set_pathname(entry, "test4"); archive_entry_set_ino(entry, 2); archive_entry_set_dev(entry, 2); archive_entry_set_nlink(entry, 3); archive_entry_set_size(entry, 10); archive_entry_linkify(resolver, &entry, &e2); /* Should get back "test3". */ assertEqualString("test3", archive_entry_pathname(entry)); assertEqualInt(0, archive_entry_size(entry)); /* Since "test4" was the last link, should get it back also. */ assertEqualString("test4", archive_entry_pathname(e2)); assertEqualInt(10, archive_entry_size(e2)); archive_entry_free(entry); archive_entry_free(e2); archive_entry_linkresolver_free(resolver); }
/* * Write user-specified files/dirs to opened archive. */ static void write_archive(struct archive *a, struct bsdtar *bsdtar) { const char *arg; struct archive_entry *entry, *sparse_entry; /* Choose a suitable copy buffer size */ bsdtar->buff_size = 64 * 1024; while (bsdtar->buff_size < (size_t)bsdtar->bytes_per_block) bsdtar->buff_size *= 2; /* Try to compensate for space we'll lose to alignment. */ bsdtar->buff_size += 16 * 1024; /* Allocate a buffer for file data. */ if ((bsdtar->buff = malloc(bsdtar->buff_size)) == NULL) lafe_errc(1, 0, "cannot allocate memory"); if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) lafe_errc(1, 0, "cannot create link resolver"); archive_entry_linkresolver_set_strategy(bsdtar->resolver, archive_format(a)); if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) lafe_errc(1, 0, "Cannot create read_disk object"); archive_read_disk_set_standard_lookup(bsdtar->diskreader); if (bsdtar->names_from_file != NULL) archive_names_from_file(bsdtar, a); while (*bsdtar->argv) { arg = *bsdtar->argv; if (arg[0] == '-' && arg[1] == 'C') { arg += 2; if (*arg == '\0') { bsdtar->argv++; arg = *bsdtar->argv; if (arg == NULL) { lafe_warnc(0, "%s", "Missing argument for -C"); bsdtar->return_value = 1; goto cleanup; } if (*arg == '\0') { lafe_warnc(0, "Meaningless argument for -C: ''"); bsdtar->return_value = 1; goto cleanup; } } set_chdir(bsdtar, arg); } else { if (*arg != '/' && (arg[0] != '@' || arg[1] != '/')) do_chdir(bsdtar); /* Handle a deferred -C */ if (*arg == '@') { if (append_archive_filename(bsdtar, a, arg + 1) != 0) break; } else write_hierarchy(bsdtar, a, arg); } bsdtar->argv++; } entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); while (entry != NULL) { write_file(bsdtar, a, entry); archive_entry_free(entry); entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); } if (archive_write_close(a)) { lafe_warnc(0, "%s", archive_error_string(a)); bsdtar->return_value = 1; } cleanup: /* Free file data buffer. */ free(bsdtar->buff); archive_entry_linkresolver_free(bsdtar->resolver); bsdtar->resolver = NULL; archive_read_free(bsdtar->diskreader); bsdtar->diskreader = NULL; if (bsdtar->option_totals) { fprintf(stderr, "Total bytes written: %s\n", tar_i64toa(archive_position_compressed(a))); } archive_write_free(a); }
/* * Write user-specified files/dirs to opened archive. */ static void write_archive(struct archive *a, struct bsdtar *bsdtar) { struct sigaction sa; const char *arg; struct archive_entry *entry, *sparse_entry; /* We want to catch SIGINFO and SIGUSR1. */ siginfo_init(bsdtar); /* We also want to catch SIGQUIT and ^Q. */ if (sigquit_init()) exit(1); /* And SIGUSR2, too. */ sa.sa_handler = sigusr2_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGUSR2, &sa, NULL)) bsdtar_errc(bsdtar, 1, 0, "cannot install signal handler"); /* Allocate a buffer for file data. */ if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL) bsdtar_errc(bsdtar, 1, 0, "cannot allocate memory"); if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) bsdtar_errc(bsdtar, 1, 0, "cannot create link resolver"); archive_entry_linkresolver_set_strategy(bsdtar->resolver, archive_format(a)); if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) bsdtar_errc(bsdtar, 1, 0, "Cannot create read_disk object"); archive_read_disk_set_standard_lookup(bsdtar->diskreader); if (bsdtar->names_from_file != NULL) archive_names_from_file(bsdtar, a); while (*bsdtar->argv) { if (truncate_archive(bsdtar)) break; if (checkpoint_archive(bsdtar, 0)) exit(1); arg = *bsdtar->argv; if (arg[0] == '-' && arg[1] == 'C') { arg += 2; if (*arg == '\0') { bsdtar->argv++; arg = *bsdtar->argv; if (arg == NULL) { bsdtar_warnc(bsdtar, 0, "Missing argument for -C"); bsdtar->return_value = 1; goto cleanup; } if (*arg == '\0') { bsdtar_warnc(bsdtar, 0, "Meaningless argument for -C: ''"); bsdtar->return_value = 1; goto cleanup; } } set_chdir(bsdtar, arg); } else { if (arg[0] != '/' && (arg[0] != '@' || arg[1] != '/') && (arg[0] != '@' || arg[1] != '@')) do_chdir(bsdtar); /* Handle a deferred -C */ if (arg[0] == '@' && arg[1] == '@') { if (append_archive_tarsnap(bsdtar, a, arg + 2) != 0) break; } else if (arg[0] == '@') { if (append_archive_filename(bsdtar, a, arg + 1) != 0) break; } else #if defined(_WIN32) && !defined(__CYGWIN__) write_hierarchy_win(bsdtar, a, arg, write_hierarchy); #else write_hierarchy(bsdtar, a, arg); #endif } bsdtar->argv++; } /* * This code belongs to bsdtar and is used when writing archives in * "new cpio" format. It has no effect in tarsnap, since tarsnap * doesn't write archives in this format; but I'm leaving it in to * make the diffs smaller. */ entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); while (entry != NULL) { write_entry_backend(bsdtar, a, entry, NULL, NULL); archive_entry_free(entry); entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); } if (archive_write_close(a)) { bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); bsdtar->return_value = 1; } cleanup: /* Free file data buffer. */ free(bsdtar->buff); archive_entry_linkresolver_free(bsdtar->resolver); bsdtar->resolver = NULL; archive_read_finish(bsdtar->diskreader); bsdtar->diskreader = NULL; if (bsdtar->option_totals && (bsdtar->return_value == 0)) { fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); } archive_write_finish(a); /* Restore old SIGINFO + SIGUSR1 handlers. */ siginfo_done(bsdtar); }
/* * Write user-specified files/dirs to opened archive. */ static void write_archive(struct archive *a, struct bsdtar *bsdtar) { const char *arg; struct archive_entry *entry, *sparse_entry; /* We want to catch SIGINFO and SIGUSR1. */ siginfo_init(bsdtar); /* Allocate a buffer for file data. */ if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL) bsdtar_errc(bsdtar, 1, 0, "cannot allocate memory"); if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) bsdtar_errc(bsdtar, 1, 0, "cannot create link resolver"); archive_entry_linkresolver_set_strategy(bsdtar->resolver, archive_format(a)); if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) bsdtar_errc(bsdtar, 1, 0, "Cannot create read_disk object"); archive_read_disk_set_standard_lookup(bsdtar->diskreader); if (bsdtar->names_from_file != NULL) archive_names_from_file(bsdtar, a); while (*bsdtar->argv) { arg = *bsdtar->argv; if (arg[0] == '-' && arg[1] == 'C') { arg += 2; if (*arg == '\0') { bsdtar->argv++; arg = *bsdtar->argv; if (arg == NULL) { bsdtar_warnc(bsdtar, 1, 0, "Missing argument for -C"); bsdtar->return_value = 1; goto cleanup; } } set_chdir(bsdtar, arg); } else { if (*arg != '/' && (arg[0] != '@' || arg[1] != '/')) do_chdir(bsdtar); /* Handle a deferred -C */ if (*arg == '@') { if (append_archive_filename(bsdtar, a, arg + 1) != 0) break; } else #if defined(_WIN32) && !defined(__CYGWIN__) write_hierarchy_win(bsdtar, a, arg, write_hierarchy); #else write_hierarchy(bsdtar, a, arg); #endif } bsdtar->argv++; } entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); while (entry != NULL) { write_entry_backend(bsdtar, a, entry); archive_entry_free(entry); entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); } if (archive_write_close(a)) { bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); bsdtar->return_value = 1; } cleanup: /* Free file data buffer. */ free(bsdtar->buff); archive_entry_linkresolver_free(bsdtar->resolver); bsdtar->resolver = NULL; archive_read_finish(bsdtar->diskreader); bsdtar->diskreader = NULL; if (bsdtar->option_totals) { fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); } archive_write_finish(a); /* Restore old SIGINFO + SIGUSR1 handlers. */ siginfo_done(bsdtar); }