X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fbuffer.c;h=5977f5a56ed80b17ad6723646fcb46b405928d64;hb=d659cbaccdc1f3279c49107cf15f15a639738529;hp=0d142f7907e29909c7b61718bff8dc4995ee00fa;hpb=4674867a23ed4b42b0a84102331d369f6fc7e467;p=chaz%2Ftar diff --git a/src/buffer.c b/src/buffer.c index 0d142f7..5977f5a 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1,7 +1,7 @@ /* Buffer management for tar. Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, - 2003, 2004 Free Software Foundation, Inc. + 2003, 2004, 2005 Free Software Foundation, Inc. Written by John Gilmore, on 1985-08-25. @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -73,7 +73,6 @@ static bool hit_eof; static int checkpoint; static bool read_full_records = false; -static bool reading_from_pipe = false; /* We're reading, but we just read the last block and it's time to update. Declared in update.c @@ -126,23 +125,16 @@ double duration; void set_start_time () { -#if HAVE_CLOCK_GETTIME - if (clock_gettime (CLOCK_REALTIME, &start_timespec) != 0) -#endif - start_time = time (0); + gettime (&start_time); } void compute_duration () { -#if HAVE_CLOCK_GETTIME struct timespec now; - if (clock_gettime (CLOCK_REALTIME, &now) == 0) - duration += ((now.tv_sec - start_timespec.tv_sec) - + (now.tv_nsec - start_timespec.tv_nsec) / 1e9); - else -#endif - duration += time (NULL) - start_time; + gettime (&now); + duration += ((now.tv_sec - start_time.tv_sec) + + (now.tv_nsec - start_time.tv_nsec) / 1e9); set_start_time (); } @@ -159,17 +151,17 @@ enum compress_type { struct zip_magic { enum compress_type type; - unsigned char *magic; size_t length; + char *magic; char *program; char *option; }; -static struct zip_magic magic[] = { +static struct zip_magic const magic[] = { { ct_none, }, - { ct_compress, "\037\235", 2, "compress", "-Z" }, - { ct_gzip, "\037\213", 2, "gzip", "-z" }, - { ct_bzip2, "BZh", 3, "bzip2", "-j" }, + { ct_compress, 2, "\037\235", "compress", "-Z" }, + { ct_gzip, 2, "\037\213", "gzip", "-z" }, + { ct_bzip2, 3, "BZh", "bzip2", "-j" }, }; #define NMAGIC (sizeof(magic)/sizeof(magic[0])) @@ -177,34 +169,31 @@ static struct zip_magic magic[] = { #define compress_option(t) magic[t].option #define compress_program(t) magic[t].program -/* Check if the file FD is a compressed archive. FD is guaranteed to - represent a local file */ -enum compress_type -check_compressed_archive (int fd) +/* Check if the file ARCHIVE is a compressed archive. */ +enum compress_type +check_compressed_archive () { - struct zip_magic *p; - size_t status; - union block buf; - - status = read (fd, &buf, sizeof buf); - if (status != sizeof buf) - { - archive_read_error (); - FATAL_ERROR ((0, 0, _("Quitting now."))); - } + struct zip_magic const *p; + bool sfr; - lseek (fd, 0, SEEK_SET); /* This will fail if fd==0, but that does not - matter, since we do not handle compressed - stdin anyway */ - - if (tar_checksum (&buf) == HEADER_SUCCESS) + /* Prepare global data needed for find_next_block: */ + record_end = record_start; /* set up for 1st record = # 0 */ + sfr = read_full_records; + read_full_records = true; /* Suppress fatal error on reading a partial + record */ + find_next_block (); + + /* Restore global values */ + read_full_records = sfr; + + if (tar_checksum (record_start, true) == HEADER_SUCCESS) /* Probably a valid header */ return ct_none; for (p = magic + 1; p < magic + NMAGIC; p++) - if (memcmp (buf.buffer, p->magic, p->length) == 0) + if (memcmp (record_start->buffer, p->magic, p->length) == 0) return p->type; - + return ct_none; } @@ -214,33 +203,32 @@ check_compressed_archive (int fd) int open_compressed_archive () { - enum compress_type type; - int fd = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY, - MODE_RW, rsh_command_option); - if (fd == -1 || _isrmt (fd)) - return fd; - - type = check_compressed_archive (fd); - - if (type == ct_none) + archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY, + MODE_RW, rsh_command_option); + if (archive == -1) + return archive; + + if (!multi_volume_option) { - if (rmtlseek (fd, (off_t) 0, SEEK_CUR) != 0) - { - /* Archive may be not seekable. Reopen it. */ - rmtclose (fd); - fd = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY, - MODE_RW, rsh_command_option); - } - return fd; - } + enum compress_type type = check_compressed_archive (); + + if (type == ct_none) + return archive; - /* FD is not needed any more */ - rmtclose (fd); + /* FD is not needed any more */ + rmtclose (archive); - /* Open compressed archive */ - use_compress_program_option = compress_program (type); - child_pid = sys_child_open_for_uncompress (); - read_full_records = reading_from_pipe = true; + hit_eof = false; /* It might have been set by find_next_block in + check_compressed_archive */ + + /* Open compressed archive */ + use_compress_program_option = compress_program (type); + child_pid = sys_child_open_for_uncompress (); + read_full_records = true; + } + + records_read = 0; + record_end = record_start; /* set up for 1st record = # 0 */ return archive; } @@ -253,7 +241,7 @@ print_total_written (void) char bytes[sizeof (tarlong) * CHAR_BIT]; char abbr[LONGEST_HUMAN_READABLE + 1]; char rate[LONGEST_HUMAN_READABLE + 1]; - + int human_opts = human_autoscale | human_base_1024 | human_SI | human_B; sprintf (bytes, TARLONG_FORMAT, written); @@ -406,15 +394,17 @@ open_archive (enum access_mode wanted_access) access_mode = wanted_access == ACCESS_UPDATE ? ACCESS_READ : wanted_access; read_full_records = read_full_records_option; - reading_from_pipe = false; - + + records_read = 0; + if (use_compress_program_option) { switch (wanted_access) { case ACCESS_READ: child_pid = sys_child_open_for_uncompress (); - read_full_records = reading_from_pipe = true; + read_full_records = true; + record_end = record_start; /* set up for 1st record = # 0 */ break; case ACCESS_WRITE: @@ -441,7 +431,7 @@ open_archive (enum access_mode wanted_access) case ACCESS_READ: { enum compress_type type; - + archive = STDIN_FILENO; type = check_compressed_archive (archive); @@ -509,9 +499,9 @@ open_archive (enum access_mode wanted_access) { case ACCESS_UPDATE: records_written = 0; - case ACCESS_READ: - records_read = 0; record_end = record_start; /* set up for 1st record = # 0 */ + + case ACCESS_READ: find_next_block (); /* read it in, check for EOF */ if (volume_label_option) @@ -545,7 +535,7 @@ open_archive (enum access_mode wanted_access) strip_trailing_slashes (current_stat_info.file_name); record_start->header.typeflag = GNUTYPE_VOLHDR; - TIME_TO_CHARS (start_time, record_start->header.mtime); + TIME_TO_CHARS (start_time.tv_sec, record_start->header.mtime); finish_header (¤t_stat_info, record_start, -1); } break; @@ -560,6 +550,10 @@ flush_write (void) ssize_t status; if (checkpoint_option && !(++checkpoint % 10)) + /* TRANSLATORS: This is a ``checkpoint of write operation'', + *not* ``Writing a checkpoint''. + E.g. in Spanish ``Punto de comprobaci@'on de escritura'', + *not* ``Escribiendo un punto de comprobaci@'on'' */ WARN ((0, 0, _("Write checkpoint %d"), checkpoint)); if (tape_length_option && tape_length_option <= bytes_written) @@ -586,7 +580,9 @@ flush_write (void) { if (save_name) { - assign_string (&real_s_name, safer_name_suffix (save_name, false)); + assign_string (&real_s_name, + safer_name_suffix (save_name, false, + absolute_names_option)); real_s_totsize = save_totsize; real_s_sizeleft = save_sizeleft; } @@ -633,7 +629,7 @@ flush_write (void) memset (record_start, 0, BLOCKSIZE); sprintf (record_start->header.name, "%s Volume %d", volume_label_option, volno); - TIME_TO_CHARS (start_time, record_start->header.mtime); + TIME_TO_CHARS (start_time.tv_sec, record_start->header.mtime); record_start->header.typeflag = GNUTYPE_VOLHDR; finish_header (¤t_stat_info, record_start, -1); } @@ -646,10 +642,10 @@ flush_write (void) record_start++; if (strlen (real_s_name) > NAME_FIELD_SIZE) - FATAL_ERROR ((0, 0, - _("%s: file name too long to be stored in a GNU multivolume header"), + WARN ((0, 0, + _("%s: file name too long to be stored in a GNU multivolume header, truncated"), quotearg_colon (real_s_name))); - + memset (record_start, 0, BLOCKSIZE); /* FIXME: Michael P Urban writes: [a long name file] is being written @@ -662,7 +658,7 @@ flush_write (void) OFF_TO_CHARS (real_s_sizeleft, record_start->header.size); OFF_TO_CHARS (real_s_totsize - real_s_sizeleft, record_start->oldgnu_header.offset); - + tmp = verbose_option; verbose_option = 0; finish_header (¤t_stat_info, record_start, -1); @@ -692,7 +688,9 @@ flush_write (void) assign_string (&real_s_name, 0); else { - assign_string (&real_s_name, safer_name_suffix (save_name, false)); + assign_string (&real_s_name, + safer_name_suffix (save_name, false, + absolute_names_option)); real_s_sizeleft = save_sizeleft; real_s_totsize = save_totsize; } @@ -753,17 +751,7 @@ short_read (size_t status) archive_read_error (); if (status == 0) - { - if (!reading_from_pipe) - { - char buf[UINTMAX_STRSIZE_BOUND]; - - WARN((0, 0, _("Read %s bytes from %s"), - STRINGIFY_BIGINT (record_size - left, buf), - *archive_name_cursor)); - } - break; - } + break; if (! read_full_records) { @@ -807,6 +795,10 @@ flush_read (void) size_t status; /* result from system call */ if (checkpoint_option && !(++checkpoint % 10)) + /* TRANSLATORS: This is a ``checkpoint of read operation'', + *not* ``Reading a checkpoint''. + E.g. in Spanish ``Punto de comprobaci@'on de lectura'', + *not* ``Leyendo un punto de comprobaci@'on'' */ WARN ((0, 0, _("Read checkpoint %d"), checkpoint)); /* Clear the count of errors. This only applies to a single call to @@ -826,7 +818,9 @@ flush_read (void) { if (save_name) { - assign_string (&real_s_name, safer_name_suffix (save_name, false)); + assign_string (&real_s_name, + safer_name_suffix (save_name, false, + absolute_names_option)); real_s_sizeleft = save_sizeleft; real_s_totsize = save_totsize; } @@ -1036,13 +1030,13 @@ seek_archive (off_t size) off_t offset; off_t nrec, nblk; off_t skipped = (blocking_factor - (current_block - record_start)); - + size -= skipped * BLOCKSIZE; - + if (size < record_size) return 0; /* FIXME: flush? */ - + /* Compute number of records to skip */ nrec = size / record_size; offset = rmtlseek (archive, nrec * record_size, SEEK_CUR); @@ -1061,7 +1055,7 @@ seek_archive (off_t size) records_read += nblk / blocking_factor; record_start_block = offset - blocking_factor; current_block = record_end; - + return nblk; } @@ -1075,7 +1069,7 @@ close_archive (void) sys_drain_input_pipe (); compute_duration (); - if (verify_option) + if (verify_option) verify_volume (); if (rmtclose (archive) != 0) @@ -1172,7 +1166,8 @@ new_volume (enum access_mode mode) if (volno_file_option) closeout_volume_number (); if (system (info_script_option) != 0) - FATAL_ERROR ((0, 0, _("`%s' command failed"), info_script_option)); + FATAL_ERROR ((0, 0, _("%s command failed"), + quote (info_script_option))); } else while (1) @@ -1295,4 +1290,3 @@ new_volume (enum access_mode mode) return true; } -