1 1.1 joerg /*- 2 1.5 christos * SPDX-License-Identifier: BSD-2-Clause 3 1.5 christos * 4 1.1 joerg * Copyright (c) 2003-2007 Tim Kientzle 5 1.2 christos * Copyright (c) 2012 Michihiro NAKAJIMA 6 1.1 joerg * All rights reserved. 7 1.1 joerg */ 8 1.1 joerg 9 1.1 joerg #include "bsdtar_platform.h" 10 1.1 joerg 11 1.1 joerg #ifdef HAVE_SYS_TYPES_H 12 1.1 joerg #include <sys/types.h> 13 1.1 joerg #endif 14 1.1 joerg #ifdef HAVE_SYS_STAT_H 15 1.1 joerg #include <sys/stat.h> 16 1.1 joerg #endif 17 1.5 christos #if HAVE_SYS_XATTR_H 18 1.5 christos #include <sys/xattr.h> 19 1.5 christos #elif HAVE_ATTR_XATTR_H 20 1.1 joerg #include <attr/xattr.h> 21 1.1 joerg #endif 22 1.1 joerg #ifdef HAVE_ERRNO_H 23 1.1 joerg #include <errno.h> 24 1.1 joerg #endif 25 1.1 joerg #ifdef HAVE_FCNTL_H 26 1.1 joerg #include <fcntl.h> 27 1.1 joerg #endif 28 1.1 joerg #ifdef HAVE_GRP_H 29 1.1 joerg #include <grp.h> 30 1.1 joerg #endif 31 1.2 christos #ifdef HAVE_IO_H 32 1.2 christos #include <io.h> 33 1.2 christos #endif 34 1.2 christos #ifdef HAVE_LIBGEN_H 35 1.2 christos #include <libgen.h> 36 1.2 christos #endif 37 1.1 joerg #ifdef HAVE_LIMITS_H 38 1.1 joerg #include <limits.h> 39 1.1 joerg #endif 40 1.2 christos #ifdef HAVE_PATHS_H 41 1.2 christos #include <paths.h> 42 1.1 joerg #endif 43 1.1 joerg #ifdef HAVE_PWD_H 44 1.1 joerg #include <pwd.h> 45 1.1 joerg #endif 46 1.2 christos #ifdef HAVE_STDINT_H 47 1.2 christos #include <stdint.h> 48 1.2 christos #endif 49 1.1 joerg #include <stdio.h> 50 1.1 joerg #ifdef HAVE_STDLIB_H 51 1.1 joerg #include <stdlib.h> 52 1.1 joerg #endif 53 1.1 joerg #ifdef HAVE_STRING_H 54 1.1 joerg #include <string.h> 55 1.1 joerg #endif 56 1.1 joerg #ifdef HAVE_UNISTD_H 57 1.1 joerg #include <unistd.h> 58 1.1 joerg #endif 59 1.1 joerg 60 1.1 joerg #include "bsdtar.h" 61 1.6 christos #include "lafe_err.h" 62 1.2 christos #include "line_reader.h" 63 1.1 joerg 64 1.2 christos #ifndef O_BINARY 65 1.2 christos #define O_BINARY 0 66 1.2 christos #endif 67 1.1 joerg 68 1.1 joerg struct archive_dir_entry { 69 1.1 joerg struct archive_dir_entry *next; 70 1.1 joerg time_t mtime_sec; 71 1.1 joerg int mtime_nsec; 72 1.1 joerg char *name; 73 1.1 joerg }; 74 1.1 joerg 75 1.1 joerg struct archive_dir { 76 1.1 joerg struct archive_dir_entry *head, *tail; 77 1.1 joerg }; 78 1.1 joerg 79 1.1 joerg static int append_archive(struct bsdtar *, struct archive *, 80 1.1 joerg struct archive *ina); 81 1.1 joerg static int append_archive_filename(struct bsdtar *, 82 1.1 joerg struct archive *, const char *fname); 83 1.1 joerg static void archive_names_from_file(struct bsdtar *bsdtar, 84 1.1 joerg struct archive *a); 85 1.2 christos static int copy_file_data_block(struct bsdtar *, 86 1.2 christos struct archive *a, struct archive *, 87 1.2 christos struct archive_entry *); 88 1.2 christos static void excluded_callback(struct archive *, void *, 89 1.2 christos struct archive_entry *); 90 1.2 christos static void report_write(struct bsdtar *, struct archive *, 91 1.2 christos struct archive_entry *, int64_t progress); 92 1.1 joerg static void test_for_append(struct bsdtar *); 93 1.2 christos static int metadata_filter(struct archive *, void *, 94 1.2 christos struct archive_entry *); 95 1.1 joerg static void write_archive(struct archive *, struct bsdtar *); 96 1.1 joerg static void write_entry(struct bsdtar *, struct archive *, 97 1.2 christos struct archive_entry *); 98 1.2 christos static void write_file(struct bsdtar *, struct archive *, 99 1.2 christos struct archive_entry *); 100 1.1 joerg static void write_hierarchy(struct bsdtar *, struct archive *, 101 1.1 joerg const char *); 102 1.1 joerg 103 1.2 christos #if defined(_WIN32) && !defined(__CYGWIN__) 104 1.2 christos /* Not a full lseek() emulation, but enough for our needs here. */ 105 1.2 christos static int 106 1.2 christos seek_file(int fd, int64_t offset, int whence) 107 1.2 christos { 108 1.2 christos LARGE_INTEGER distance; 109 1.2 christos (void)whence; /* UNUSED */ 110 1.2 christos distance.QuadPart = offset; 111 1.2 christos return (SetFilePointerEx((HANDLE)_get_osfhandle(fd), 112 1.2 christos distance, NULL, FILE_BEGIN) ? 1 : -1); 113 1.2 christos } 114 1.6 christos 115 1.6 christos static int 116 1.6 christos _open_wrap_sopen(char const *const path, int const oflag, ...) 117 1.6 christos { 118 1.6 christos va_list ap; 119 1.6 christos int r, pmode; 120 1.6 christos 121 1.6 christos pmode = 0; 122 1.6 christos if (oflag & _O_CREAT) 123 1.6 christos { 124 1.6 christos va_start(ap, oflag); 125 1.6 christos pmode = va_arg(ap, int); 126 1.6 christos va_end(ap); 127 1.6 christos } 128 1.6 christos 129 1.6 christos _sopen_s(&r, path, oflag, _SH_DENYNO, pmode & 0600); 130 1.6 christos if (r < 0) 131 1.6 christos { 132 1.6 christos /* _sopen_s populates errno */ 133 1.6 christos return -1; 134 1.6 christos } 135 1.6 christos 136 1.6 christos return r; 137 1.6 christos } 138 1.6 christos 139 1.6 christos #define open _open_wrap_sopen 140 1.2 christos #define close _close 141 1.2 christos #define read _read 142 1.2 christos #ifdef lseek 143 1.2 christos #undef lseek 144 1.2 christos #endif 145 1.2 christos #define lseek seek_file 146 1.2 christos #endif 147 1.2 christos 148 1.2 christos static void 149 1.2 christos set_writer_options(struct bsdtar *bsdtar, struct archive *a) 150 1.2 christos { 151 1.2 christos const char *writer_options; 152 1.2 christos int r; 153 1.2 christos 154 1.2 christos writer_options = getenv(ENV_WRITER_OPTIONS); 155 1.2 christos if (writer_options != NULL) { 156 1.2 christos size_t module_len = sizeof(IGNORE_WRONG_MODULE_NAME) - 1; 157 1.2 christos size_t opt_len = strlen(writer_options) + 1; 158 1.2 christos char *p; 159 1.2 christos /* Set default write options. */ 160 1.2 christos if ((p = malloc(module_len + opt_len)) == NULL) 161 1.2 christos lafe_errc(1, errno, "Out of memory"); 162 1.2 christos /* Prepend magic code to ignore options for 163 1.2 christos * a format or filters which are not added to 164 1.2 christos * the archive write object. */ 165 1.2 christos memcpy(p, IGNORE_WRONG_MODULE_NAME, module_len); 166 1.6 christos memcpy(p + module_len, writer_options, opt_len); 167 1.2 christos r = archive_write_set_options(a, p); 168 1.2 christos free(p); 169 1.2 christos if (r < ARCHIVE_WARN) 170 1.2 christos lafe_errc(1, 0, "%s", archive_error_string(a)); 171 1.2 christos else 172 1.2 christos archive_clear_error(a); 173 1.2 christos } 174 1.2 christos if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options)) 175 1.2 christos lafe_errc(1, 0, "%s", archive_error_string(a)); 176 1.2 christos } 177 1.2 christos 178 1.2 christos static void 179 1.2 christos set_reader_options(struct bsdtar *bsdtar, struct archive *a) 180 1.2 christos { 181 1.2 christos const char *reader_options; 182 1.2 christos int r; 183 1.2 christos 184 1.2 christos (void)bsdtar; /* UNUSED */ 185 1.2 christos 186 1.2 christos reader_options = getenv(ENV_READER_OPTIONS); 187 1.2 christos if (reader_options != NULL) { 188 1.2 christos size_t module_len = sizeof(IGNORE_WRONG_MODULE_NAME) - 1; 189 1.2 christos size_t opt_len = strlen(reader_options) + 1; 190 1.2 christos char *p; 191 1.2 christos /* Set default write options. */ 192 1.2 christos if ((p = malloc(module_len + opt_len)) == NULL) 193 1.2 christos lafe_errc(1, errno, "Out of memory"); 194 1.2 christos /* Prepend magic code to ignore options for 195 1.2 christos * a format or filters which are not added to 196 1.2 christos * the archive write object. */ 197 1.2 christos memcpy(p, IGNORE_WRONG_MODULE_NAME, module_len); 198 1.6 christos memcpy(p + module_len, reader_options, opt_len); 199 1.2 christos r = archive_read_set_options(a, p); 200 1.2 christos free(p); 201 1.2 christos if (r < ARCHIVE_WARN) 202 1.2 christos lafe_errc(1, 0, "%s", archive_error_string(a)); 203 1.2 christos else 204 1.2 christos archive_clear_error(a); 205 1.2 christos } 206 1.4 christos if (bsdtar->flags & OPTFLAG_IGNORE_ZEROS) 207 1.4 christos if (archive_read_set_options(a, 208 1.4 christos "read_concatenated_archives") != ARCHIVE_OK) 209 1.4 christos lafe_errc(1, 0, "%s", archive_error_string(a)); 210 1.2 christos } 211 1.2 christos 212 1.1 joerg void 213 1.1 joerg tar_mode_c(struct bsdtar *bsdtar) 214 1.1 joerg { 215 1.1 joerg struct archive *a; 216 1.2 christos const void *filter_name; 217 1.1 joerg int r; 218 1.1 joerg 219 1.1 joerg if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) 220 1.2 christos lafe_errc(1, 0, "no files or directories specified"); 221 1.1 joerg 222 1.1 joerg a = archive_write_new(); 223 1.1 joerg 224 1.1 joerg /* Support any format that the library supports. */ 225 1.2 christos if (cset_get_format(bsdtar->cset) == NULL) { 226 1.1 joerg r = archive_write_set_format_pax_restricted(a); 227 1.2 christos cset_set_format(bsdtar->cset, "pax restricted"); 228 1.1 joerg } else { 229 1.2 christos r = archive_write_set_format_by_name(a, 230 1.2 christos cset_get_format(bsdtar->cset)); 231 1.1 joerg } 232 1.1 joerg if (r != ARCHIVE_OK) { 233 1.1 joerg fprintf(stderr, "Can't use format %s: %s\n", 234 1.2 christos cset_get_format(bsdtar->cset), 235 1.1 joerg archive_error_string(a)); 236 1.2 christos usage(); 237 1.1 joerg } 238 1.1 joerg 239 1.2 christos archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block); 240 1.2 christos archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block); 241 1.1 joerg 242 1.2 christos r = cset_write_add_filters(bsdtar->cset, a, &filter_name); 243 1.2 christos if (r < ARCHIVE_WARN) { 244 1.2 christos lafe_errc(1, 0, "Unsupported compression option --%s", 245 1.2 christos (const char *)filter_name); 246 1.1 joerg } 247 1.1 joerg 248 1.2 christos set_writer_options(bsdtar, a); 249 1.2 christos if (bsdtar->passphrase != NULL) 250 1.2 christos r = archive_write_set_passphrase(a, bsdtar->passphrase); 251 1.2 christos else 252 1.2 christos r = archive_write_set_passphrase_callback(a, bsdtar, 253 1.2 christos &passphrase_callback); 254 1.1 joerg if (r != ARCHIVE_OK) 255 1.2 christos lafe_errc(1, 0, "%s", archive_error_string(a)); 256 1.2 christos if (ARCHIVE_OK != archive_write_open_filename(a, bsdtar->filename)) 257 1.2 christos lafe_errc(1, 0, "%s", archive_error_string(a)); 258 1.1 joerg write_archive(a, bsdtar); 259 1.1 joerg } 260 1.1 joerg 261 1.1 joerg /* 262 1.1 joerg * Same as 'c', except we only support tar or empty formats in 263 1.1 joerg * uncompressed files on disk. 264 1.1 joerg */ 265 1.1 joerg void 266 1.1 joerg tar_mode_r(struct bsdtar *bsdtar) 267 1.1 joerg { 268 1.2 christos int64_t end_offset; 269 1.1 joerg int format; 270 1.1 joerg struct archive *a; 271 1.1 joerg struct archive_entry *entry; 272 1.1 joerg int r; 273 1.1 joerg 274 1.1 joerg /* Sanity-test some arguments and the file. */ 275 1.1 joerg test_for_append(bsdtar); 276 1.1 joerg 277 1.1 joerg format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; 278 1.1 joerg 279 1.2 christos #if defined(__BORLANDC__) 280 1.2 christos bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY); 281 1.2 christos #else 282 1.2 christos bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY, 0666); 283 1.2 christos #endif 284 1.1 joerg if (bsdtar->fd < 0) 285 1.2 christos lafe_errc(1, errno, 286 1.1 joerg "Cannot open %s", bsdtar->filename); 287 1.1 joerg 288 1.1 joerg a = archive_read_new(); 289 1.2 christos archive_read_support_filter_all(a); 290 1.2 christos archive_read_support_format_empty(a); 291 1.1 joerg archive_read_support_format_tar(a); 292 1.1 joerg archive_read_support_format_gnutar(a); 293 1.2 christos set_reader_options(bsdtar, a); 294 1.1 joerg r = archive_read_open_fd(a, bsdtar->fd, 10240); 295 1.1 joerg if (r != ARCHIVE_OK) 296 1.2 christos lafe_errc(1, archive_errno(a), 297 1.1 joerg "Can't read archive %s: %s", bsdtar->filename, 298 1.1 joerg archive_error_string(a)); 299 1.1 joerg while (0 == archive_read_next_header(a, &entry)) { 300 1.2 christos if (archive_filter_code(a, 0) != ARCHIVE_FILTER_NONE) { 301 1.2 christos archive_read_free(a); 302 1.1 joerg close(bsdtar->fd); 303 1.2 christos lafe_errc(1, 0, 304 1.7 christos "Cannot append to compressed archive"); 305 1.1 joerg } 306 1.1 joerg /* Keep going until we hit end-of-archive */ 307 1.1 joerg format = archive_format(a); 308 1.1 joerg } 309 1.1 joerg 310 1.1 joerg end_offset = archive_read_header_position(a); 311 1.2 christos archive_read_free(a); 312 1.1 joerg 313 1.1 joerg /* Re-open archive for writing */ 314 1.1 joerg a = archive_write_new(); 315 1.1 joerg /* 316 1.1 joerg * Set the format to be used for writing. To allow people to 317 1.1 joerg * extend empty files, we need to allow them to specify the format, 318 1.1 joerg * which opens the possibility that they will specify a format that 319 1.1 joerg * doesn't match the existing format. Hence, the following bit 320 1.1 joerg * of arcane ugliness. 321 1.1 joerg */ 322 1.1 joerg 323 1.2 christos if (cset_get_format(bsdtar->cset) != NULL) { 324 1.1 joerg /* If the user requested a format, use that, but ... */ 325 1.1 joerg archive_write_set_format_by_name(a, 326 1.2 christos cset_get_format(bsdtar->cset)); 327 1.1 joerg /* ... complain if it's not compatible. */ 328 1.1 joerg format &= ARCHIVE_FORMAT_BASE_MASK; 329 1.1 joerg if (format != (int)(archive_format(a) & ARCHIVE_FORMAT_BASE_MASK) 330 1.1 joerg && format != ARCHIVE_FORMAT_EMPTY) { 331 1.2 christos lafe_errc(1, 0, 332 1.7 christos "Format %s is incompatible with the archive %s", 333 1.2 christos cset_get_format(bsdtar->cset), bsdtar->filename); 334 1.1 joerg } 335 1.1 joerg } else { 336 1.1 joerg /* 337 1.1 joerg * Just preserve the current format, with a little care 338 1.1 joerg * for formats that libarchive can't write. 339 1.1 joerg */ 340 1.1 joerg if (format == ARCHIVE_FORMAT_EMPTY) 341 1.1 joerg format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; 342 1.1 joerg archive_write_set_format(a, format); 343 1.1 joerg } 344 1.2 christos if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0) 345 1.2 christos lafe_errc(1, errno, "Could not seek to archive end"); 346 1.2 christos set_writer_options(bsdtar, a); 347 1.2 christos if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd)) 348 1.2 christos lafe_errc(1, 0, "%s", archive_error_string(a)); 349 1.1 joerg 350 1.1 joerg write_archive(a, bsdtar); /* XXX check return val XXX */ 351 1.1 joerg 352 1.1 joerg close(bsdtar->fd); 353 1.1 joerg bsdtar->fd = -1; 354 1.1 joerg } 355 1.1 joerg 356 1.1 joerg void 357 1.1 joerg tar_mode_u(struct bsdtar *bsdtar) 358 1.1 joerg { 359 1.2 christos int64_t end_offset; 360 1.1 joerg struct archive *a; 361 1.1 joerg struct archive_entry *entry; 362 1.1 joerg int format; 363 1.1 joerg struct archive_dir_entry *p; 364 1.1 joerg struct archive_dir archive_dir; 365 1.1 joerg 366 1.1 joerg bsdtar->archive_dir = &archive_dir; 367 1.1 joerg memset(&archive_dir, 0, sizeof(archive_dir)); 368 1.1 joerg 369 1.1 joerg format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; 370 1.1 joerg 371 1.1 joerg /* Sanity-test some arguments and the file. */ 372 1.1 joerg test_for_append(bsdtar); 373 1.1 joerg 374 1.2 christos bsdtar->fd = open(bsdtar->filename, O_RDWR | O_BINARY); 375 1.1 joerg if (bsdtar->fd < 0) 376 1.2 christos lafe_errc(1, errno, 377 1.1 joerg "Cannot open %s", bsdtar->filename); 378 1.1 joerg 379 1.1 joerg a = archive_read_new(); 380 1.2 christos archive_read_support_filter_all(a); 381 1.1 joerg archive_read_support_format_tar(a); 382 1.1 joerg archive_read_support_format_gnutar(a); 383 1.2 christos set_reader_options(bsdtar, a); 384 1.2 christos if (archive_read_open_fd(a, bsdtar->fd, bsdtar->bytes_per_block) 385 1.2 christos != ARCHIVE_OK) { 386 1.2 christos lafe_errc(1, 0, 387 1.1 joerg "Can't open %s: %s", bsdtar->filename, 388 1.1 joerg archive_error_string(a)); 389 1.1 joerg } 390 1.1 joerg 391 1.1 joerg /* Build a list of all entries and their recorded mod times. */ 392 1.1 joerg while (0 == archive_read_next_header(a, &entry)) { 393 1.2 christos if (archive_filter_code(a, 0) != ARCHIVE_FILTER_NONE) { 394 1.2 christos archive_read_free(a); 395 1.1 joerg close(bsdtar->fd); 396 1.2 christos lafe_errc(1, 0, 397 1.7 christos "Cannot append to compressed archive"); 398 1.1 joerg } 399 1.2 christos if (archive_match_exclude_entry(bsdtar->matching, 400 1.2 christos ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER | 401 1.2 christos ARCHIVE_MATCH_EQUAL, entry) != ARCHIVE_OK) 402 1.7 christos lafe_errc(1, 0, "%s", 403 1.2 christos archive_error_string(bsdtar->matching)); 404 1.1 joerg /* Record the last format determination we see */ 405 1.1 joerg format = archive_format(a); 406 1.1 joerg /* Keep going until we hit end-of-archive */ 407 1.1 joerg } 408 1.1 joerg 409 1.1 joerg end_offset = archive_read_header_position(a); 410 1.2 christos archive_read_free(a); 411 1.1 joerg 412 1.1 joerg /* Re-open archive for writing. */ 413 1.1 joerg a = archive_write_new(); 414 1.1 joerg /* 415 1.2 christos * Set format to same one auto-detected above. 416 1.1 joerg */ 417 1.1 joerg archive_write_set_format(a, format); 418 1.2 christos archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block); 419 1.2 christos archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block); 420 1.2 christos 421 1.2 christos if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0) 422 1.2 christos lafe_errc(1, errno, "Could not seek to archive end"); 423 1.2 christos set_writer_options(bsdtar, a); 424 1.2 christos if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd)) 425 1.2 christos lafe_errc(1, 0, "%s", archive_error_string(a)); 426 1.1 joerg 427 1.1 joerg write_archive(a, bsdtar); 428 1.1 joerg 429 1.1 joerg close(bsdtar->fd); 430 1.1 joerg bsdtar->fd = -1; 431 1.1 joerg 432 1.1 joerg while (bsdtar->archive_dir->head != NULL) { 433 1.1 joerg p = bsdtar->archive_dir->head->next; 434 1.1 joerg free(bsdtar->archive_dir->head->name); 435 1.1 joerg free(bsdtar->archive_dir->head); 436 1.1 joerg bsdtar->archive_dir->head = p; 437 1.1 joerg } 438 1.1 joerg bsdtar->archive_dir->tail = NULL; 439 1.1 joerg } 440 1.1 joerg 441 1.1 joerg 442 1.1 joerg /* 443 1.1 joerg * Write user-specified files/dirs to opened archive. 444 1.1 joerg */ 445 1.1 joerg static void 446 1.1 joerg write_archive(struct archive *a, struct bsdtar *bsdtar) 447 1.1 joerg { 448 1.1 joerg const char *arg; 449 1.1 joerg struct archive_entry *entry, *sparse_entry; 450 1.1 joerg 451 1.2 christos /* Choose a suitable copy buffer size */ 452 1.2 christos bsdtar->buff_size = 64 * 1024; 453 1.2 christos while (bsdtar->buff_size < (size_t)bsdtar->bytes_per_block) 454 1.2 christos bsdtar->buff_size *= 2; 455 1.2 christos /* Try to compensate for space we'll lose to alignment. */ 456 1.2 christos bsdtar->buff_size += 16 * 1024; 457 1.2 christos 458 1.2 christos /* Allocate a buffer for file data. */ 459 1.2 christos if ((bsdtar->buff = malloc(bsdtar->buff_size)) == NULL) 460 1.2 christos lafe_errc(1, 0, "cannot allocate memory"); 461 1.2 christos 462 1.1 joerg if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) 463 1.2 christos lafe_errc(1, 0, "cannot create link resolver"); 464 1.1 joerg archive_entry_linkresolver_set_strategy(bsdtar->resolver, 465 1.1 joerg archive_format(a)); 466 1.1 joerg 467 1.2 christos /* Create a read_disk object. */ 468 1.2 christos if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) 469 1.2 christos lafe_errc(1, 0, "Cannot create read_disk object"); 470 1.2 christos /* Tell the read_disk how handle symlink. */ 471 1.2 christos switch (bsdtar->symlink_mode) { 472 1.2 christos case 'H': 473 1.2 christos archive_read_disk_set_symlink_hybrid(bsdtar->diskreader); 474 1.2 christos break; 475 1.2 christos case 'L': 476 1.2 christos archive_read_disk_set_symlink_logical(bsdtar->diskreader); 477 1.2 christos break; 478 1.2 christos default: 479 1.2 christos archive_read_disk_set_symlink_physical(bsdtar->diskreader); 480 1.2 christos break; 481 1.2 christos } 482 1.2 christos /* Register entry filters. */ 483 1.2 christos archive_read_disk_set_matching(bsdtar->diskreader, 484 1.2 christos bsdtar->matching, excluded_callback, bsdtar); 485 1.2 christos archive_read_disk_set_metadata_filter_callback( 486 1.2 christos bsdtar->diskreader, metadata_filter, bsdtar); 487 1.2 christos /* Set the behavior of archive_read_disk. */ 488 1.2 christos archive_read_disk_set_behavior(bsdtar->diskreader, 489 1.2 christos bsdtar->readdisk_flags); 490 1.2 christos archive_read_disk_set_standard_lookup(bsdtar->diskreader); 491 1.2 christos 492 1.1 joerg if (bsdtar->names_from_file != NULL) 493 1.1 joerg archive_names_from_file(bsdtar, a); 494 1.1 joerg 495 1.1 joerg while (*bsdtar->argv) { 496 1.1 joerg arg = *bsdtar->argv; 497 1.1 joerg if (arg[0] == '-' && arg[1] == 'C') { 498 1.1 joerg arg += 2; 499 1.1 joerg if (*arg == '\0') { 500 1.1 joerg bsdtar->argv++; 501 1.1 joerg arg = *bsdtar->argv; 502 1.1 joerg if (arg == NULL) { 503 1.2 christos lafe_warnc(0, "%s", 504 1.1 joerg "Missing argument for -C"); 505 1.1 joerg bsdtar->return_value = 1; 506 1.2 christos goto cleanup; 507 1.2 christos } 508 1.2 christos if (*arg == '\0') { 509 1.2 christos lafe_warnc(0, 510 1.2 christos "Meaningless argument for -C: ''"); 511 1.2 christos bsdtar->return_value = 1; 512 1.2 christos goto cleanup; 513 1.1 joerg } 514 1.1 joerg } 515 1.1 joerg set_chdir(bsdtar, arg); 516 1.1 joerg } else { 517 1.2 christos if (*arg != '/') 518 1.1 joerg do_chdir(bsdtar); /* Handle a deferred -C */ 519 1.1 joerg if (*arg == '@') { 520 1.1 joerg if (append_archive_filename(bsdtar, a, 521 1.1 joerg arg + 1) != 0) 522 1.1 joerg break; 523 1.1 joerg } else 524 1.1 joerg write_hierarchy(bsdtar, a, arg); 525 1.1 joerg } 526 1.1 joerg bsdtar->argv++; 527 1.1 joerg } 528 1.1 joerg 529 1.2 christos archive_read_disk_set_matching(bsdtar->diskreader, NULL, NULL, NULL); 530 1.2 christos archive_read_disk_set_metadata_filter_callback( 531 1.2 christos bsdtar->diskreader, NULL, NULL); 532 1.1 joerg entry = NULL; 533 1.1 joerg archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); 534 1.1 joerg while (entry != NULL) { 535 1.2 christos int r; 536 1.2 christos struct archive_entry *entry2; 537 1.2 christos struct archive *disk = bsdtar->diskreader; 538 1.2 christos 539 1.2 christos /* 540 1.2 christos * This tricky code here is to correctly read the contents 541 1.2 christos * of the entry because the disk reader bsdtar->diskreader 542 1.2 christos * is pointing at does not have any information about the 543 1.2 christos * entry by this time and using archive_read_data_block() 544 1.2 christos * with the disk reader consequently must fail. And we 545 1.2 christos * have to re-open the entry to read the contents. 546 1.2 christos */ 547 1.2 christos /* TODO: Work with -C option as well. */ 548 1.2 christos r = archive_read_disk_open(disk, 549 1.2 christos archive_entry_sourcepath(entry)); 550 1.2 christos if (r != ARCHIVE_OK) { 551 1.2 christos lafe_warnc(archive_errno(disk), 552 1.2 christos "%s", archive_error_string(disk)); 553 1.2 christos bsdtar->return_value = 1; 554 1.2 christos goto next_entry; 555 1.2 christos } 556 1.2 christos 557 1.2 christos /* 558 1.2 christos * Invoke archive_read_next_header2() to work 559 1.2 christos * archive_read_data_block(), which is called via write_file(), 560 1.2 christos * without failure. 561 1.2 christos */ 562 1.2 christos entry2 = archive_entry_new(); 563 1.2 christos r = archive_read_next_header2(disk, entry2); 564 1.2 christos archive_entry_free(entry2); 565 1.2 christos if (r != ARCHIVE_OK) { 566 1.2 christos lafe_warnc(archive_errno(disk), 567 1.2 christos "%s", archive_error_string(disk)); 568 1.2 christos if (r == ARCHIVE_FATAL) 569 1.2 christos bsdtar->return_value = 1; 570 1.2 christos archive_read_close(disk); 571 1.2 christos goto next_entry; 572 1.2 christos } 573 1.2 christos 574 1.2 christos write_file(bsdtar, a, entry); 575 1.2 christos archive_read_close(disk); 576 1.2 christos next_entry: 577 1.1 joerg archive_entry_free(entry); 578 1.1 joerg entry = NULL; 579 1.1 joerg archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); 580 1.1 joerg } 581 1.1 joerg 582 1.1 joerg if (archive_write_close(a)) { 583 1.2 christos lafe_warnc(0, "%s", archive_error_string(a)); 584 1.1 joerg bsdtar->return_value = 1; 585 1.1 joerg } 586 1.2 christos 587 1.2 christos cleanup: 588 1.2 christos /* Free file data buffer. */ 589 1.2 christos free(bsdtar->buff); 590 1.2 christos archive_entry_linkresolver_free(bsdtar->resolver); 591 1.2 christos bsdtar->resolver = NULL; 592 1.2 christos archive_read_free(bsdtar->diskreader); 593 1.2 christos bsdtar->diskreader = NULL; 594 1.2 christos 595 1.2 christos if (bsdtar->flags & OPTFLAG_TOTALS) { 596 1.2 christos fprintf(stderr, "Total bytes written: %s\n", 597 1.2 christos tar_i64toa(archive_filter_bytes(a, -1))); 598 1.2 christos } 599 1.2 christos 600 1.2 christos archive_write_free(a); 601 1.1 joerg } 602 1.1 joerg 603 1.1 joerg /* 604 1.1 joerg * Archive names specified in file. 605 1.1 joerg * 606 1.1 joerg * Unless --null was specified, a line containing exactly "-C" will 607 1.1 joerg * cause the next line to be a directory to pass to chdir(). If 608 1.1 joerg * --null is specified, then a line "-C" is just another filename. 609 1.1 joerg */ 610 1.2 christos static void 611 1.1 joerg archive_names_from_file(struct bsdtar *bsdtar, struct archive *a) 612 1.1 joerg { 613 1.2 christos struct lafe_line_reader *lr; 614 1.2 christos const char *line; 615 1.1 joerg 616 1.1 joerg bsdtar->next_line_is_dir = 0; 617 1.2 christos 618 1.2 christos lr = lafe_line_reader(bsdtar->names_from_file, 619 1.2 christos (bsdtar->flags & OPTFLAG_NULL)); 620 1.2 christos while ((line = lafe_line_reader_next(lr)) != NULL) { 621 1.2 christos if (bsdtar->next_line_is_dir) { 622 1.2 christos if (*line != '\0') 623 1.2 christos set_chdir(bsdtar, line); 624 1.2 christos else { 625 1.2 christos lafe_warnc(0, 626 1.2 christos "Meaningless argument for -C: ''"); 627 1.2 christos bsdtar->return_value = 1; 628 1.2 christos } 629 1.2 christos bsdtar->next_line_is_dir = 0; 630 1.2 christos } else if (((bsdtar->flags & OPTFLAG_NULL) == 0) && 631 1.2 christos strcmp(line, "-C") == 0) 632 1.2 christos bsdtar->next_line_is_dir = 1; 633 1.2 christos else { 634 1.2 christos if (*line != '/') 635 1.2 christos do_chdir(bsdtar); /* Handle a deferred -C */ 636 1.2 christos write_hierarchy(bsdtar, a, line); 637 1.2 christos } 638 1.2 christos } 639 1.2 christos lafe_line_reader_free(lr); 640 1.1 joerg if (bsdtar->next_line_is_dir) 641 1.2 christos lafe_errc(1, errno, 642 1.1 joerg "Unexpected end of filename list; " 643 1.1 joerg "directory expected after -C"); 644 1.1 joerg } 645 1.1 joerg 646 1.1 joerg /* 647 1.1 joerg * Copy from specified archive to current archive. Returns non-zero 648 1.1 joerg * for write errors (which force us to terminate the entire archiving 649 1.1 joerg * operation). If there are errors reading the input archive, we set 650 1.1 joerg * bsdtar->return_value but return zero, so the overall archiving 651 1.1 joerg * operation will complete and return non-zero. 652 1.1 joerg */ 653 1.1 joerg static int 654 1.1 joerg append_archive_filename(struct bsdtar *bsdtar, struct archive *a, 655 1.2 christos const char *raw_filename) 656 1.1 joerg { 657 1.1 joerg struct archive *ina; 658 1.2 christos const char *filename = raw_filename; 659 1.1 joerg int rc; 660 1.1 joerg 661 1.1 joerg if (strcmp(filename, "-") == 0) 662 1.1 joerg filename = NULL; /* Library uses NULL for stdio. */ 663 1.1 joerg 664 1.1 joerg ina = archive_read_new(); 665 1.1 joerg archive_read_support_format_all(ina); 666 1.2 christos archive_read_support_filter_all(ina); 667 1.2 christos set_reader_options(bsdtar, ina); 668 1.2 christos archive_read_set_options(ina, "mtree:checkfs"); 669 1.2 christos if (bsdtar->passphrase != NULL) 670 1.2 christos rc = archive_read_add_passphrase(a, bsdtar->passphrase); 671 1.2 christos else 672 1.2 christos rc = archive_read_set_passphrase_callback(ina, bsdtar, 673 1.2 christos &passphrase_callback); 674 1.2 christos if (rc != ARCHIVE_OK) 675 1.2 christos lafe_errc(1, 0, "%s", archive_error_string(a)); 676 1.2 christos if (archive_read_open_filename(ina, filename, 677 1.2 christos bsdtar->bytes_per_block)) { 678 1.2 christos lafe_warnc(0, "%s", archive_error_string(ina)); 679 1.1 joerg bsdtar->return_value = 1; 680 1.1 joerg return (0); 681 1.1 joerg } 682 1.1 joerg 683 1.1 joerg rc = append_archive(bsdtar, a, ina); 684 1.1 joerg 685 1.2 christos if (rc != ARCHIVE_OK) { 686 1.2 christos lafe_warnc(0, "Error reading archive %s: %s", 687 1.2 christos raw_filename, archive_error_string(ina)); 688 1.1 joerg bsdtar->return_value = 1; 689 1.1 joerg } 690 1.2 christos archive_read_free(ina); 691 1.1 joerg 692 1.1 joerg return (rc); 693 1.1 joerg } 694 1.1 joerg 695 1.1 joerg static int 696 1.1 joerg append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) 697 1.1 joerg { 698 1.1 joerg struct archive_entry *in_entry; 699 1.1 joerg int e; 700 1.1 joerg 701 1.2 christos while (ARCHIVE_OK == (e = archive_read_next_header(ina, &in_entry))) { 702 1.2 christos if (archive_match_excluded(bsdtar->matching, in_entry)) 703 1.1 joerg continue; 704 1.4 christos if(edit_pathname(bsdtar, in_entry)) 705 1.4 christos continue; 706 1.2 christos if ((bsdtar->flags & OPTFLAG_INTERACTIVE) && 707 1.1 joerg !yes("copy '%s'", archive_entry_pathname(in_entry))) 708 1.1 joerg continue; 709 1.6 christos edit_mtime(bsdtar, in_entry); 710 1.2 christos if (bsdtar->verbose > 1) { 711 1.2 christos safe_fprintf(stderr, "a "); 712 1.2 christos list_item_verbose(bsdtar, stderr, in_entry); 713 1.2 christos } else if (bsdtar->verbose > 0) 714 1.1 joerg safe_fprintf(stderr, "a %s", 715 1.1 joerg archive_entry_pathname(in_entry)); 716 1.2 christos if (need_report()) 717 1.2 christos report_write(bsdtar, a, in_entry, 0); 718 1.1 joerg 719 1.1 joerg e = archive_write_header(a, in_entry); 720 1.1 joerg if (e != ARCHIVE_OK) { 721 1.1 joerg if (!bsdtar->verbose) 722 1.2 christos lafe_warnc(0, "%s: %s", 723 1.1 joerg archive_entry_pathname(in_entry), 724 1.1 joerg archive_error_string(a)); 725 1.1 joerg else 726 1.1 joerg fprintf(stderr, ": %s", archive_error_string(a)); 727 1.1 joerg } 728 1.1 joerg if (e == ARCHIVE_FATAL) 729 1.1 joerg exit(1); 730 1.1 joerg 731 1.1 joerg if (e >= ARCHIVE_WARN) { 732 1.1 joerg if (archive_entry_size(in_entry) == 0) 733 1.1 joerg archive_read_data_skip(ina); 734 1.2 christos else if (copy_file_data_block(bsdtar, a, ina, in_entry)) 735 1.1 joerg exit(1); 736 1.1 joerg } 737 1.1 joerg 738 1.1 joerg if (bsdtar->verbose) 739 1.1 joerg fprintf(stderr, "\n"); 740 1.1 joerg } 741 1.1 joerg 742 1.2 christos return (e == ARCHIVE_EOF ? ARCHIVE_OK : e); 743 1.1 joerg } 744 1.1 joerg 745 1.2 christos /* Helper function to copy file to archive. */ 746 1.1 joerg static int 747 1.2 christos copy_file_data_block(struct bsdtar *bsdtar, struct archive *a, 748 1.2 christos struct archive *in_a, struct archive_entry *entry) 749 1.1 joerg { 750 1.2 christos size_t bytes_read; 751 1.1 joerg ssize_t bytes_written; 752 1.2 christos int64_t offset, progress = 0; 753 1.2 christos char *null_buff = NULL; 754 1.2 christos const void *buff; 755 1.2 christos int r; 756 1.1 joerg 757 1.2 christos while ((r = archive_read_data_block(in_a, &buff, 758 1.2 christos &bytes_read, &offset)) == ARCHIVE_OK) { 759 1.2 christos if (need_report()) 760 1.2 christos report_write(bsdtar, a, entry, progress); 761 1.2 christos 762 1.2 christos if (offset > progress) { 763 1.2 christos int64_t sparse = offset - progress; 764 1.2 christos size_t ns; 765 1.2 christos 766 1.2 christos if (null_buff == NULL) { 767 1.2 christos null_buff = bsdtar->buff; 768 1.2 christos memset(null_buff, 0, bsdtar->buff_size); 769 1.2 christos } 770 1.2 christos 771 1.2 christos while (sparse > 0) { 772 1.2 christos if (sparse > (int64_t)bsdtar->buff_size) 773 1.2 christos ns = bsdtar->buff_size; 774 1.2 christos else 775 1.2 christos ns = (size_t)sparse; 776 1.2 christos bytes_written = 777 1.2 christos archive_write_data(a, null_buff, ns); 778 1.2 christos if (bytes_written < 0) { 779 1.2 christos /* Write failed; this is bad */ 780 1.2 christos lafe_warnc(0, "%s", 781 1.2 christos archive_error_string(a)); 782 1.2 christos return (-1); 783 1.2 christos } 784 1.2 christos if ((size_t)bytes_written < ns) { 785 1.2 christos /* Write was truncated; warn but 786 1.2 christos * continue. */ 787 1.2 christos lafe_warnc(0, 788 1.2 christos "%s: Truncated write; file may " 789 1.7 christos "have grown while being archived", 790 1.2 christos archive_entry_pathname(entry)); 791 1.2 christos return (0); 792 1.2 christos } 793 1.2 christos progress += bytes_written; 794 1.2 christos sparse -= bytes_written; 795 1.2 christos } 796 1.2 christos } 797 1.1 joerg 798 1.1 joerg bytes_written = archive_write_data(a, buff, bytes_read); 799 1.2 christos if (bytes_written < 0) { 800 1.2 christos /* Write failed; this is bad */ 801 1.2 christos lafe_warnc(0, "%s", archive_error_string(a)); 802 1.1 joerg return (-1); 803 1.1 joerg } 804 1.2 christos if ((size_t)bytes_written < bytes_read) { 805 1.2 christos /* Write was truncated; warn but continue. */ 806 1.2 christos lafe_warnc(0, 807 1.2 christos "%s: Truncated write; file may have grown " 808 1.7 christos "while being archived", 809 1.2 christos archive_entry_pathname(entry)); 810 1.2 christos return (0); 811 1.2 christos } 812 1.1 joerg progress += bytes_written; 813 1.1 joerg } 814 1.2 christos if (r < ARCHIVE_WARN) { 815 1.3 christos const char *s = archive_error_string(a); 816 1.3 christos if (s) 817 1.3 christos lafe_warnc(archive_errno(a), "%s", s); 818 1.2 christos return (-1); 819 1.2 christos } 820 1.2 christos return (0); 821 1.2 christos } 822 1.2 christos 823 1.2 christos static void 824 1.2 christos excluded_callback(struct archive *a, void *_data, struct archive_entry *entry) 825 1.2 christos { 826 1.2 christos struct bsdtar *bsdtar = (struct bsdtar *)_data; 827 1.2 christos 828 1.2 christos if (bsdtar->flags & OPTFLAG_NO_SUBDIRS) 829 1.2 christos return; 830 1.2 christos if (!archive_read_disk_can_descend(a)) 831 1.2 christos return; 832 1.2 christos if ((bsdtar->flags & OPTFLAG_INTERACTIVE) && 833 1.2 christos !yes("add '%s'", archive_entry_pathname(entry))) 834 1.2 christos return; 835 1.2 christos archive_read_disk_descend(a); 836 1.2 christos } 837 1.2 christos 838 1.2 christos static int 839 1.2 christos metadata_filter(struct archive *a, void *_data, struct archive_entry *entry) 840 1.2 christos { 841 1.2 christos struct bsdtar *bsdtar = (struct bsdtar *)_data; 842 1.2 christos 843 1.2 christos /* XXX TODO: check whether this filesystem is 844 1.2 christos * synthetic and/or local. Add a new 845 1.2 christos * --local-only option to skip non-local 846 1.2 christos * filesystems. Skip synthetic filesystems 847 1.2 christos * regardless. 848 1.2 christos * 849 1.2 christos * The results should be cached, since 850 1.2 christos * tree.c doesn't usually visit a directory 851 1.2 christos * and the directory contents together. A simple 852 1.2 christos * move-to-front list should perform quite well. 853 1.2 christos * 854 1.2 christos * Use archive_read_disk_current_filesystem_is_remote(). 855 1.2 christos */ 856 1.2 christos 857 1.2 christos /* 858 1.2 christos * If the user vetoes this file/directory, skip it. 859 1.2 christos * We want this to be fairly late; if some other 860 1.2 christos * check would veto this file, we shouldn't bother 861 1.2 christos * the user with it. 862 1.2 christos */ 863 1.2 christos if ((bsdtar->flags & OPTFLAG_INTERACTIVE) && 864 1.2 christos !yes("add '%s'", archive_entry_pathname(entry))) 865 1.2 christos return (0); 866 1.1 joerg 867 1.2 christos /* Note: if user vetoes, we won't descend. */ 868 1.2 christos if (((bsdtar->flags & OPTFLAG_NO_SUBDIRS) == 0) && 869 1.2 christos archive_read_disk_can_descend(a)) 870 1.2 christos archive_read_disk_descend(a); 871 1.2 christos 872 1.2 christos return (1); 873 1.1 joerg } 874 1.1 joerg 875 1.1 joerg /* 876 1.1 joerg * Add the file or dir hierarchy named by 'path' to the archive 877 1.1 joerg */ 878 1.1 joerg static void 879 1.1 joerg write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) 880 1.1 joerg { 881 1.2 christos struct archive *disk = bsdtar->diskreader; 882 1.2 christos struct archive_entry *entry = NULL, *spare_entry = NULL; 883 1.2 christos int r; 884 1.1 joerg 885 1.2 christos r = archive_read_disk_open(disk, path); 886 1.2 christos if (r != ARCHIVE_OK) { 887 1.2 christos lafe_warnc(archive_errno(disk), 888 1.2 christos "%s", archive_error_string(disk)); 889 1.1 joerg bsdtar->return_value = 1; 890 1.1 joerg return; 891 1.1 joerg } 892 1.2 christos bsdtar->first_fs = -1; 893 1.1 joerg 894 1.2 christos for (;;) { 895 1.2 christos archive_entry_free(entry); 896 1.2 christos entry = archive_entry_new(); 897 1.2 christos r = archive_read_next_header2(disk, entry); 898 1.2 christos if (r == ARCHIVE_EOF) 899 1.2 christos break; 900 1.2 christos else if (r != ARCHIVE_OK) { 901 1.2 christos lafe_warnc(archive_errno(disk), 902 1.2 christos "%s", archive_error_string(disk)); 903 1.2 christos if (r == ARCHIVE_FATAL || r == ARCHIVE_FAILED) { 904 1.1 joerg bsdtar->return_value = 1; 905 1.2 christos archive_entry_free(entry); 906 1.2 christos archive_read_close(disk); 907 1.2 christos return; 908 1.2 christos } else if (r < ARCHIVE_WARN) 909 1.2 christos continue; 910 1.1 joerg } 911 1.1 joerg 912 1.2 christos if (bsdtar->uid >= 0) { 913 1.2 christos archive_entry_set_uid(entry, bsdtar->uid); 914 1.2 christos if (!bsdtar->uname) 915 1.2 christos archive_entry_set_uname(entry, 916 1.2 christos archive_read_disk_uname(bsdtar->diskreader, 917 1.2 christos bsdtar->uid)); 918 1.2 christos } 919 1.2 christos if (bsdtar->gid >= 0) { 920 1.2 christos archive_entry_set_gid(entry, bsdtar->gid); 921 1.2 christos if (!bsdtar->gname) 922 1.2 christos archive_entry_set_gname(entry, 923 1.2 christos archive_read_disk_gname(bsdtar->diskreader, 924 1.2 christos bsdtar->gid)); 925 1.2 christos } 926 1.2 christos if (bsdtar->uname) 927 1.2 christos archive_entry_set_uname(entry, bsdtar->uname); 928 1.2 christos if (bsdtar->gname) 929 1.2 christos archive_entry_set_gname(entry, bsdtar->gname); 930 1.1 joerg 931 1.1 joerg /* 932 1.2 christos * Rewrite the pathname to be archived. If rewrite 933 1.2 christos * fails, skip the entry. 934 1.1 joerg */ 935 1.2 christos if (edit_pathname(bsdtar, entry)) 936 1.1 joerg continue; 937 1.1 joerg 938 1.6 christos /* Rewrite the mtime. */ 939 1.6 christos edit_mtime(bsdtar, entry); 940 1.6 christos 941 1.2 christos /* Display entry as we process it. */ 942 1.2 christos if (bsdtar->verbose > 1) { 943 1.2 christos safe_fprintf(stderr, "a "); 944 1.2 christos list_item_verbose(bsdtar, stderr, entry); 945 1.2 christos } else if (bsdtar->verbose > 0) { 946 1.2 christos /* This format is required by SUSv2. */ 947 1.2 christos safe_fprintf(stderr, "a %s", 948 1.2 christos archive_entry_pathname(entry)); 949 1.2 christos } 950 1.1 joerg 951 1.2 christos /* Non-regular files get archived with zero size. */ 952 1.2 christos if (archive_entry_filetype(entry) != AE_IFREG) 953 1.2 christos archive_entry_set_size(entry, 0); 954 1.1 joerg 955 1.2 christos archive_entry_linkify(bsdtar->resolver, &entry, &spare_entry); 956 1.1 joerg 957 1.2 christos while (entry != NULL) { 958 1.2 christos write_file(bsdtar, a, entry); 959 1.5 christos if (entry != spare_entry) { 960 1.5 christos archive_entry_free(entry); 961 1.5 christos } 962 1.2 christos entry = spare_entry; 963 1.2 christos spare_entry = NULL; 964 1.1 joerg } 965 1.1 joerg 966 1.2 christos if (bsdtar->verbose) 967 1.2 christos fprintf(stderr, "\n"); 968 1.2 christos } 969 1.2 christos archive_entry_free(entry); 970 1.2 christos archive_read_close(disk); 971 1.2 christos } 972 1.1 joerg 973 1.2 christos /* 974 1.2 christos * Write a single file (or directory or other filesystem object) to 975 1.2 christos * the archive. 976 1.2 christos */ 977 1.2 christos static void 978 1.2 christos write_file(struct bsdtar *bsdtar, struct archive *a, 979 1.2 christos struct archive_entry *entry) 980 1.2 christos { 981 1.2 christos write_entry(bsdtar, a, entry); 982 1.1 joerg } 983 1.1 joerg 984 1.1 joerg /* 985 1.2 christos * Write a single entry to the archive. 986 1.1 joerg */ 987 1.1 joerg static void 988 1.2 christos write_entry(struct bsdtar *bsdtar, struct archive *a, 989 1.2 christos struct archive_entry *entry) 990 1.1 joerg { 991 1.1 joerg int e; 992 1.1 joerg 993 1.1 joerg e = archive_write_header(a, entry); 994 1.1 joerg if (e != ARCHIVE_OK) { 995 1.2 christos if (bsdtar->verbose > 0) { 996 1.2 christos safe_fprintf(stderr, "a "); 997 1.2 christos list_item_verbose(bsdtar, stderr, entry); 998 1.2 christos lafe_warnc(0, ": %s", archive_error_string(a)); 999 1.2 christos } else { 1000 1.2 christos lafe_warnc(0, "%s: %s", 1001 1.1 joerg archive_entry_pathname(entry), 1002 1.1 joerg archive_error_string(a)); 1003 1.2 christos } 1004 1.1 joerg } 1005 1.1 joerg 1006 1.1 joerg if (e == ARCHIVE_FATAL) 1007 1.1 joerg exit(1); 1008 1.1 joerg 1009 1.1 joerg /* 1010 1.1 joerg * If we opened a file earlier, write it out now. Note that 1011 1.1 joerg * the format handler might have reset the size field to zero 1012 1.1 joerg * to inform us that the archive body won't get stored. In 1013 1.1 joerg * that case, just skip the write. 1014 1.1 joerg */ 1015 1.2 christos if (e >= ARCHIVE_WARN && archive_entry_size(entry) > 0) { 1016 1.2 christos if (copy_file_data_block(bsdtar, a, bsdtar->diskreader, entry)) 1017 1.1 joerg exit(1); 1018 1.1 joerg } 1019 1.1 joerg } 1020 1.1 joerg 1021 1.1 joerg static void 1022 1.2 christos report_write(struct bsdtar *bsdtar, struct archive *a, 1023 1.2 christos struct archive_entry *entry, int64_t progress) 1024 1.1 joerg { 1025 1.2 christos uint64_t comp, uncomp; 1026 1.2 christos int compression; 1027 1.1 joerg 1028 1.1 joerg if (bsdtar->verbose) 1029 1.1 joerg fprintf(stderr, "\n"); 1030 1.2 christos comp = archive_filter_bytes(a, -1); 1031 1.2 christos uncomp = archive_filter_bytes(a, 0); 1032 1.2 christos fprintf(stderr, "In: %d files, %s bytes;", 1033 1.2 christos archive_file_count(a), tar_i64toa(uncomp)); 1034 1.2 christos if (comp >= uncomp) 1035 1.2 christos compression = 0; 1036 1.1 joerg else 1037 1.2 christos compression = (int)((uncomp - comp) * 100 / uncomp); 1038 1.2 christos fprintf(stderr, 1039 1.2 christos " Out: %s bytes, compression %d%%\n", 1040 1.2 christos tar_i64toa(comp), compression); 1041 1.2 christos /* Can't have two calls to tar_i64toa() pending, so split the output. */ 1042 1.2 christos safe_fprintf(stderr, "Current: %s (%s", 1043 1.2 christos archive_entry_pathname(entry), 1044 1.2 christos tar_i64toa(progress)); 1045 1.2 christos fprintf(stderr, "/%s bytes)\n", 1046 1.2 christos tar_i64toa(archive_entry_size(entry))); 1047 1.1 joerg } 1048 1.1 joerg 1049 1.1 joerg static void 1050 1.1 joerg test_for_append(struct bsdtar *bsdtar) 1051 1.1 joerg { 1052 1.1 joerg struct stat s; 1053 1.1 joerg 1054 1.1 joerg if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) 1055 1.2 christos lafe_errc(1, 0, "no files or directories specified"); 1056 1.1 joerg if (bsdtar->filename == NULL) 1057 1.7 christos lafe_errc(1, 0, "Cannot append to stdout"); 1058 1.1 joerg 1059 1.1 joerg if (stat(bsdtar->filename, &s) != 0) 1060 1.1 joerg return; 1061 1.1 joerg 1062 1.1 joerg if (!S_ISREG(s.st_mode) && !S_ISBLK(s.st_mode)) 1063 1.2 christos lafe_errc(1, 0, 1064 1.7 christos "Cannot append to %s: not a regular file", 1065 1.1 joerg bsdtar->filename); 1066 1.2 christos 1067 1.2 christos /* Is this an appropriate check here on Windows? */ 1068 1.2 christos /* 1069 1.2 christos if (GetFileType(handle) != FILE_TYPE_DISK) 1070 1.2 christos lafe_errc(1, 0, "Cannot append"); 1071 1.2 christos */ 1072 1.2 christos 1073 1.1 joerg } 1074