/* We're reading, but we just read the last block and it's time to update.
Declared in update.c
-
+
FIXME: Either eliminate it or move it to common.h.
*/
extern bool time_to_start_writing;
\f
/* Multi-volume tracking support */
-/* When creating a multi-volume archive, each `bufmap' represents
+/* When creating a multi-volume archive, each 'bufmap' represents
a member stored (perhaps partly) in the current record buffer.
After flushing the record to the output media, all bufmaps that
represent fully written members are removed from the list, then
bufmap_locate (size_t off)
{
struct bufmap *map;
-
+
for (map = bufmap_head; map; map = map->next)
{
if (!map->next
static struct tar_stat_info dummy;
void
-buffer_write_global_xheader ()
+buffer_write_global_xheader (void)
{
xheader_write_global (&dummy.xhdr);
}
}
void
-mv_end ()
+mv_end (void)
{
if (multi_volume_option)
bufmap_free (NULL);
double duration;
void
-set_start_time ()
+set_start_time (void)
{
gettime (&start_time);
volume_start_time = start_time;
}
void
-compute_duration ()
+compute_duration (void)
{
struct timespec now;
gettime (&now);
/* Compression detection */
enum compress_type {
- ct_tar, /* Plain tar file */
ct_none, /* Unknown compression type */
+ ct_tar, /* Plain tar file */
ct_compress,
ct_gzip,
ct_bzip2,
ct_xz
};
+static enum compress_type archive_compression_type = ct_none;
+
struct zip_magic
{
enum compress_type type;
size_t length;
char const *magic;
+};
+
+struct zip_program
+{
+ enum compress_type type;
char const *program;
char const *option;
};
static struct zip_magic const magic[] = {
- { ct_tar },
{ ct_none, },
- { ct_compress, 2, "\037\235", COMPRESS_PROGRAM, "-Z" },
- { ct_gzip, 2, "\037\213", GZIP_PROGRAM, "-z" },
- { ct_bzip2, 3, "BZh", BZIP2_PROGRAM, "-j" },
- { ct_lzip, 4, "LZIP", LZIP_PROGRAM, "--lzip" },
- { ct_lzma, 6, "\xFFLZMA", LZMA_PROGRAM, "--lzma" },
- { ct_lzop, 4, "\211LZO", LZOP_PROGRAM, "--lzop" },
- { ct_xz, 6, "\xFD" "7zXZ", XZ_PROGRAM, "-J" },
+ { ct_tar },
+ { ct_compress, 2, "\037\235" },
+ { ct_gzip, 2, "\037\213" },
+ { ct_bzip2, 3, "BZh" },
+ { ct_lzip, 4, "LZIP" },
+ { ct_lzma, 6, "\xFFLZMA" },
+ { ct_lzop, 4, "\211LZO" },
+ { ct_xz, 6, "\xFD" "7zXZ" },
};
#define NMAGIC (sizeof(magic)/sizeof(magic[0]))
-#define compress_option(t) magic[t].option
-#define compress_program(t) magic[t].program
+static struct zip_program zip_program[] = {
+ { ct_compress, COMPRESS_PROGRAM, "-Z" },
+ { ct_compress, GZIP_PROGRAM, "-z" },
+ { ct_gzip, GZIP_PROGRAM, "-z" },
+ { ct_bzip2, BZIP2_PROGRAM, "-j" },
+ { ct_bzip2, "lbzip2", "-j" },
+ { ct_lzip, LZIP_PROGRAM, "--lzip" },
+ { ct_lzma, LZMA_PROGRAM, "--lzma" },
+ { ct_lzma, XZ_PROGRAM, "-J" },
+ { ct_lzop, LZOP_PROGRAM, "--lzop" },
+ { ct_xz, XZ_PROGRAM, "-J" },
+ { ct_none }
+};
+
+static struct zip_program const *
+find_zip_program (enum compress_type type, int *pstate)
+{
+ int i;
+
+ for (i = *pstate; zip_program[i].type != ct_none; i++)
+ {
+ if (zip_program[i].type == type)
+ {
+ *pstate = i + 1;
+ return zip_program + i;
+ }
+ }
+ *pstate = i;
+ return NULL;
+}
+
+const char *
+first_decompress_program (int *pstate)
+{
+ struct zip_program const *zp;
+
+ if (use_compress_program_option)
+ return use_compress_program_option;
+
+ if (archive_compression_type == ct_none)
+ return NULL;
+
+ *pstate = 0;
+ zp = find_zip_program (archive_compression_type, pstate);
+ return zp ? zp->program : NULL;
+}
+
+const char *
+next_decompress_program (int *pstate)
+{
+ struct zip_program const *zp;
+
+ if (use_compress_program_option)
+ return NULL;
+ zp = find_zip_program (archive_compression_type, pstate);
+ return zp ? zp->program : NULL;
+}
+
+static const char *
+compress_option (enum compress_type type)
+{
+ struct zip_program const *zp;
+ int i = 0;
+ zp = find_zip_program (type, &i);
+ return zp ? zp->option : NULL;
+}
/* Check if the file ARCHIVE is a compressed archive. */
static enum compress_type
case ct_none:
if (shortfile)
ERROR ((0, 0, _("This does not look like a tar archive")));
- set_comression_program_by_suffix (archive_name_array[0], NULL);
+ set_compression_program_by_suffix (archive_name_array[0], NULL);
if (!use_compress_program_option)
return archive;
break;
default:
- use_compress_program_option = compress_program (type);
+ archive_compression_type = type;
break;
}
}
}
void
-print_total_stats ()
+print_total_stats (void)
{
switch (subcommand_option)
{
FATAL_ERROR ((0, 0, _("No archive name given")));
tar_stat_destroy (¤t_stat_info);
-
+
record_index = 0;
init_buffer ();
map = map->next;
bufmap_reset (map, map ? (- map->start) : 0);
}
- }
+ }
return status;
}
size_t copy_size;
size_t bufsize;
struct bufmap *map;
-
+
status = _flush_write ();
if (status != record_size && !multi_volume_option)
archive_write_error (status);
}
map = bufmap_locate (status);
-
+
if (status % BLOCKSIZE)
{
ERROR ((0, 0, _("write did not end on a block boundary")));
copy_ptr = record_start->buffer + status;
copy_size = buffer_level - status;
-
+
/* Switch to the next buffer */
record_index = !record_index;
init_buffer ();
inhibit_map = 1;
-
+
if (volume_label_option)
add_volume_label ();
}
void
-flush_read ()
+flush_read (void)
{
flush_read_ptr ();
}
void
-flush_write ()
+flush_write (void)
{
flush_write_ptr (record_size);
}