X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fbuffer.c;h=f451413e8e8d61703e644e3153401ecc6f329b1a;hb=c1b9212b16a53da408548efa3f9c8b1a62335b42;hp=d29ccccef279350575905ec718a9326e32888264;hpb=0e041a7bfe4655f4b2ffe4ce3f5ebe942a0151f0;p=chaz%2Ftar diff --git a/src/buffer.c b/src/buffer.c index d29cccc..f451413 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1,7 +1,7 @@ /* Buffer management for tar. - Copyright 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001 Free - Software Foundation, Inc. + Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, + 2003 Free Software Foundation, Inc. Written by John Gilmore, on 1985-08-25. @@ -23,14 +23,6 @@ #include -#if MSDOS -# include -#endif - -#if XENIX -# include -#endif - #include #include #include @@ -38,9 +30,6 @@ #include "common.h" #include "rmt.h" -#define PREAD 0 /* read file descriptor from pipe() */ -#define PWRITE 1 /* write file descriptor from pipe() */ - /* Number of retries before giving up on read. */ #define READ_ERROR_MAX 10 @@ -62,24 +51,13 @@ enum access_mode access_mode; /* how do we handle the archive */ off_t records_read; /* number of records read from this archive */ off_t records_written; /* likewise, for records written */ -static struct stat archive_stat; /* stat block for archive file */ - static off_t record_start_block; /* block ordinal at record_start */ -/* Where we write list messages (not errors, not interactions) to. Stdout - unless we're writing a pipe, in which case stderr. */ +/* Where we write list messages (not errors, not interactions) to. */ FILE *stdlis; -static void backspace_output PARAMS ((void)); -static int new_volume PARAMS ((enum access_mode)); -static void archive_write_error PARAMS ((ssize_t)) __attribute__ ((noreturn)); -static void archive_read_error PARAMS ((void)); - -#if !MSDOS -/* Obnoxious test to see if dimwit is trying to dump the archive. */ -dev_t ar_dev; -ino_t ar_ino; -#endif +static void backspace_output (void); +static int new_volume (enum access_mode); /* PID of child program, if compress_option or remote archive access. */ static pid_t child_pid; @@ -129,6 +107,12 @@ static off_t real_s_sizeleft; /* Functions. */ +void +clear_read_error_count () +{ + read_error_count = 0; +} + void print_total_written (void) { @@ -137,6 +121,7 @@ print_total_written (void) char abbr[LONGEST_HUMAN_READABLE + 1]; char rate[LONGEST_HUMAN_READABLE + 1]; double seconds; + int human_opts = human_autoscale | human_base_1024 | human_SI | human_B; #if HAVE_CLOCK_GETTIME struct timespec now; @@ -150,10 +135,10 @@ print_total_written (void) sprintf (bytes, TARLONG_FORMAT, written); /* Amanda 2.4.1p1 looks for "Total bytes written: [0-9][0-9]*". */ - fprintf (stderr, _("Total bytes written: %s (%sB, %sB/s)\n"), bytes, - human_readable ((uintmax_t) written, abbr, 1, -1024), + fprintf (stderr, _("Total bytes written: %s (%s, %s/s)\n"), bytes, + human_readable (written, abbr, human_opts, 1, 1), (0 < seconds && written / seconds < (uintmax_t) -1 - ? human_readable ((uintmax_t) (written / seconds), rate, 1, -1024) + ? human_readable (written / seconds, rate, human_opts, 1, 1) : "?")); } @@ -224,401 +209,13 @@ available_space_after (union block *pointer) } /* Close file having descriptor FD, and abort if close unsuccessful. */ -static void +void xclose (int fd) { if (close (fd) != 0) close_error (_("(pipe)")); } -/* Duplicate file descriptor FROM into becoming INTO. - INTO is closed first and has to be the next available slot. */ -static void -xdup2 (int from, int into) -{ - if (from != into) - { - int status = close (into); - - if (status != 0 && errno != EBADF) - { - int e = errno; - FATAL_ERROR ((0, e, _("Cannot close"))); - } - status = dup (from); - if (status != into) - { - if (status < 0) - { - int e = errno; - FATAL_ERROR ((0, e, _("Cannot dup"))); - } - abort (); - } - xclose (from); - } -} - -#if MSDOS - -/* Set ARCHIVE for writing, then compressing an archive. */ -static void -child_open_for_compress (void) -{ - FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives"))); -} - -/* Set ARCHIVE for uncompressing, then reading an archive. */ -static void -child_open_for_uncompress (void) -{ - FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives"))); -} - -#else /* not MSDOS */ - -/* Return nonzero if NAME is the name of a regular file, or if the file - does not exist (so it would be created as a regular file). */ -static int -is_regular_file (const char *name) -{ - struct stat stbuf; - - if (stat (name, &stbuf) == 0) - return S_ISREG (stbuf.st_mode); - else - return errno == ENOENT; -} - -static ssize_t -write_archive_buffer (void) -{ - ssize_t status; - ssize_t written = 0; - - while (0 <= (status = rmtwrite (archive, record_start->buffer + written, - record_size - written))) - { - written += status; - if (written == record_size - || _isrmt (archive) || ! S_ISFIFO (archive_stat.st_mode)) - break; - } - - return written ? written : status; -} - -/* Set ARCHIVE for writing, then compressing an archive. */ -static void -child_open_for_compress (void) -{ - int parent_pipe[2]; - int child_pipe[2]; - pid_t grandchild_pid; - int wait_status; - - xpipe (parent_pipe); - child_pid = xfork (); - - if (child_pid > 0) - { - /* The parent tar is still here! Just clean up. */ - - archive = parent_pipe[PWRITE]; - xclose (parent_pipe[PREAD]); - return; - } - - /* The new born child tar is here! */ - - program_name = _("tar (child)"); - - xdup2 (parent_pipe[PREAD], STDIN_FILENO); - xclose (parent_pipe[PWRITE]); - - /* Check if we need a grandchild tar. This happens only if either: - a) we are writing stdout: to force reblocking; - b) the file is to be accessed by rmt: compressor doesn't know how; - c) the file is not a plain file. */ - - if (strcmp (archive_name_array[0], "-") != 0 - && !_remdev (archive_name_array[0]) - && is_regular_file (archive_name_array[0])) - { - if (backup_option) - maybe_backup_file (archive_name_array[0], 1); - - /* We don't need a grandchild tar. Open the archive and launch the - compressor. */ - - archive = creat (archive_name_array[0], MODE_RW); - if (archive < 0) - { - int saved_errno = errno; - - if (backup_option) - undo_last_backup (); - errno = saved_errno; - open_fatal (archive_name_array[0]); - } - xdup2 (archive, STDOUT_FILENO); - execlp (use_compress_program_option, use_compress_program_option, - (char *) 0); - exec_fatal (use_compress_program_option); - } - - /* We do need a grandchild tar. */ - - xpipe (child_pipe); - grandchild_pid = xfork (); - - if (grandchild_pid == 0) - { - /* The newborn grandchild tar is here! Launch the compressor. */ - - program_name = _("tar (grandchild)"); - - xdup2 (child_pipe[PWRITE], STDOUT_FILENO); - xclose (child_pipe[PREAD]); - execlp (use_compress_program_option, use_compress_program_option, - (char *) 0); - exec_fatal (use_compress_program_option); - } - - /* The child tar is still here! */ - - /* Prepare for reblocking the data from the compressor into the archive. */ - - xdup2 (child_pipe[PREAD], STDIN_FILENO); - xclose (child_pipe[PWRITE]); - - if (strcmp (archive_name_array[0], "-") == 0) - archive = STDOUT_FILENO; - else - { - archive = rmtcreat (archive_name_array[0], MODE_RW, rsh_command_option); - if (archive < 0) - open_fatal (archive_name_array[0]); - } - - /* Let's read out of the stdin pipe and write an archive. */ - - while (1) - { - ssize_t status = 0; - char *cursor; - size_t length; - - /* Assemble a record. */ - - for (length = 0, cursor = record_start->buffer; - length < record_size; - length += status, cursor += status) - { - size_t size = record_size - length; - - if (size < BLOCKSIZE) - size = BLOCKSIZE; - status = safe_read (STDIN_FILENO, cursor, size); - if (status <= 0) - break; - } - - if (status < 0) - read_fatal (use_compress_program_option); - - /* Copy the record. */ - - if (status == 0) - { - /* We hit the end of the file. Write last record at - full length, as the only role of the grandchild is - doing proper reblocking. */ - - if (length > 0) - { - memset (record_start->buffer + length, 0, record_size - length); - status = write_archive_buffer (); - if (status != record_size) - archive_write_error (status); - } - - /* There is nothing else to read, break out. */ - break; - } - - status = write_archive_buffer (); - if (status != record_size) - archive_write_error (status); - } - -#if 0 - close_archive (); -#endif - - /* Propagate any failure of the grandchild back to the parent. */ - - while (waitpid (grandchild_pid, &wait_status, 0) == -1) - if (errno != EINTR) - { - waitpid_error (use_compress_program_option); - break; - } - - if (WIFSIGNALED (wait_status)) - { - kill (child_pid, WTERMSIG (wait_status)); - exit_status = TAREXIT_FAILURE; - } - else if (WEXITSTATUS (wait_status) != 0) - exit_status = WEXITSTATUS (wait_status); - - exit (exit_status); -} - -/* Set ARCHIVE for uncompressing, then reading an archive. */ -static void -child_open_for_uncompress (void) -{ - int parent_pipe[2]; - int child_pipe[2]; - pid_t grandchild_pid; - int wait_status; - - xpipe (parent_pipe); - child_pid = xfork (); - - if (child_pid > 0) - { - /* The parent tar is still here! Just clean up. */ - - read_full_records_option = 1; - archive = parent_pipe[PREAD]; - xclose (parent_pipe[PWRITE]); - return; - } - - /* The newborn child tar is here! */ - - program_name = _("tar (child)"); - - xdup2 (parent_pipe[PWRITE], STDOUT_FILENO); - xclose (parent_pipe[PREAD]); - - /* Check if we need a grandchild tar. This happens only if either: - a) we're reading stdin: to force unblocking; - b) the file is to be accessed by rmt: compressor doesn't know how; - c) the file is not a plain file. */ - - if (strcmp (archive_name_array[0], "-") != 0 - && !_remdev (archive_name_array[0]) - && is_regular_file (archive_name_array[0])) - { - /* We don't need a grandchild tar. Open the archive and lauch the - uncompressor. */ - - archive = open (archive_name_array[0], O_RDONLY | O_BINARY, MODE_RW); - if (archive < 0) - open_fatal (archive_name_array[0]); - xdup2 (archive, STDIN_FILENO); - execlp (use_compress_program_option, use_compress_program_option, - "-d", (char *) 0); - exec_fatal (use_compress_program_option); - } - - /* We do need a grandchild tar. */ - - xpipe (child_pipe); - grandchild_pid = xfork (); - - if (grandchild_pid == 0) - { - /* The newborn grandchild tar is here! Launch the uncompressor. */ - - program_name = _("tar (grandchild)"); - - xdup2 (child_pipe[PREAD], STDIN_FILENO); - xclose (child_pipe[PWRITE]); - execlp (use_compress_program_option, use_compress_program_option, - "-d", (char *) 0); - exec_fatal (use_compress_program_option); - } - - /* The child tar is still here! */ - - /* Prepare for unblocking the data from the archive into the - uncompressor. */ - - xdup2 (child_pipe[PWRITE], STDOUT_FILENO); - xclose (child_pipe[PREAD]); - - if (strcmp (archive_name_array[0], "-") == 0) - archive = STDIN_FILENO; - else - archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY, - MODE_RW, rsh_command_option); - if (archive < 0) - open_fatal (archive_name_array[0]); - - /* Let's read the archive and pipe it into stdout. */ - - while (1) - { - char *cursor; - size_t maximum; - size_t count; - ssize_t status; - - read_error_count = 0; - - error_loop: - status = rmtread (archive, record_start->buffer, record_size); - if (status < 0) - { - archive_read_error (); - goto error_loop; - } - if (status == 0) - break; - cursor = record_start->buffer; - maximum = status; - while (maximum) - { - count = maximum < BLOCKSIZE ? maximum : BLOCKSIZE; - if (full_write (STDOUT_FILENO, cursor, count) != count) - write_error (use_compress_program_option); - cursor += count; - maximum -= count; - } - } - - xclose (STDOUT_FILENO); -#if 0 - close_archive (); -#endif - - /* Propagate any failure of the grandchild back to the parent. */ - - while (waitpid (grandchild_pid, &wait_status, 0) == -1) - if (errno != EINTR) - { - waitpid_error (use_compress_program_option); - break; - } - - if (WIFSIGNALED (wait_status)) - { - kill (child_pid, WTERMSIG (wait_status)); - exit_status = TAREXIT_FAILURE; - } - else if (WEXITSTATUS (wait_status) != 0) - exit_status = WEXITSTATUS (wait_status); - - exit (exit_status); -} - -#endif /* not MSDOS */ - /* Check the LABEL block against the volume label, seen as a globbing pattern. Return true if the pattern matches. In case of failure, retry matching a volume sequence number before giving up in @@ -654,7 +251,14 @@ open_archive (enum access_mode wanted_access) { int backed_up_flag = 0; - stdlis = to_stdout_option ? stderr : stdout; + if (index_file_name) + { + stdlis = fopen (index_file_name, "w"); + if (! stdlis) + open_error (index_file_name); + } + else + stdlis = to_stdout_option ? stderr : stdout; if (record_size == 0) FATAL_ERROR ((0, 0, _("Invalid value for record_size"))); @@ -662,8 +266,7 @@ open_archive (enum access_mode wanted_access) if (archive_names == 0) FATAL_ERROR ((0, 0, _("No archive name given"))); - current_file_name = 0; - current_link_name = 0; + destroy_stat (¤t_stat_info); save_name = 0; real_s_name = 0; @@ -696,11 +299,11 @@ open_archive (enum access_mode wanted_access) switch (wanted_access) { case ACCESS_READ: - child_open_for_uncompress (); + child_pid = sys_child_open_for_uncompress (); break; case ACCESS_WRITE: - child_open_for_compress (); + child_pid = sys_child_open_for_compress (); break; case ACCESS_UPDATE: @@ -764,7 +367,7 @@ open_archive (enum access_mode wanted_access) } if (archive < 0 - || (! _isrmt (archive) && fstat (archive, &archive_stat) < 0)) + || (! _isrmt (archive) && !sys_get_archive_stat ())) { int saved_errno = errno; @@ -774,35 +377,9 @@ open_archive (enum access_mode wanted_access) open_fatal (archive_name_array[0]); } -#if !MSDOS - - /* Detect if outputting to "/dev/null". */ - { - static char const dev_null[] = "/dev/null"; - struct stat dev_null_stat; - - dev_null_output = - (strcmp (archive_name_array[0], dev_null) == 0 - || (! _isrmt (archive) - && S_ISCHR (archive_stat.st_mode) - && stat (dev_null, &dev_null_stat) == 0 - && archive_stat.st_dev == dev_null_stat.st_dev - && archive_stat.st_ino == dev_null_stat.st_ino)); - } - - if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode)) - { - ar_dev = archive_stat.st_dev; - ar_ino = archive_stat.st_ino; - } - else - ar_dev = 0; - -#endif /* not MSDOS */ - -#if MSDOS - setmode (archive, O_BINARY); -#endif + sys_detect_dev_null_output (); + sys_save_archive_dev_ino (); + SET_BINARY_MODE (archive); switch (wanted_access) { @@ -838,11 +415,12 @@ open_archive (enum access_mode wanted_access) else strcpy (record_start->header.name, volume_label_option); - assign_string (¤t_file_name, record_start->header.name); + assign_string (¤t_stat_info.file_name, record_start->header.name); + current_stat_info.had_trailing_slash = strip_trailing_slashes (current_stat_info.file_name); record_start->header.typeflag = GNUTYPE_VOLHDR; TIME_TO_CHARS (start_time, record_start->header.mtime); - finish_header (record_start); + finish_header (record_start, -1); #if 0 current_block++; #endif @@ -869,7 +447,7 @@ flush_write (void) else if (dev_null_output) status = record_size; else - status = write_archive_buffer (); + status = sys_write_archive_buffer (); if (status != record_size && !multi_volume_option) archive_write_error (status); @@ -883,23 +461,18 @@ flush_write (void) { if (multi_volume_option) { - char *cursor; - - if (!save_name) + if (save_name) + { + assign_string (&real_s_name, safer_name_suffix (save_name, 0)); + real_s_totsize = save_totsize; + real_s_sizeleft = save_sizeleft; + } + else { assign_string (&real_s_name, 0); real_s_totsize = 0; real_s_sizeleft = 0; - return; } - - cursor = save_name + FILESYSTEM_PREFIX_LEN (save_name); - while (ISSLASH (*cursor)) - cursor++; - - assign_string (&real_s_name, cursor); - real_s_totsize = save_totsize; - real_s_sizeleft = save_sizeleft; } return; } @@ -939,7 +512,7 @@ flush_write (void) volume_label_option, volno); TIME_TO_CHARS (start_time, record_start->header.mtime); record_start->header.typeflag = GNUTYPE_VOLHDR; - finish_header (record_start); + finish_header (record_start, -1); } if (real_s_name) @@ -962,14 +535,14 @@ flush_write (void) record_start->oldgnu_header.offset); tmp = verbose_option; verbose_option = 0; - finish_header (record_start); + finish_header (record_start, -1); verbose_option = tmp; if (volume_label_option) record_start--; } - status = write_archive_buffer (); + status = sys_write_archive_buffer (); if (status != record_size) archive_write_error (status); @@ -989,12 +562,7 @@ flush_write (void) assign_string (&real_s_name, 0); else { - char *cursor = save_name + FILESYSTEM_PREFIX_LEN (save_name); - - while (ISSLASH (*cursor)) - cursor++; - - assign_string (&real_s_name, cursor); + assign_string (&real_s_name, safer_name_suffix (save_name, 0)); real_s_sizeleft = save_sizeleft; real_s_totsize = save_totsize; } @@ -1005,7 +573,7 @@ flush_write (void) /* Handle write errors on the archive. Write errors are always fatal. Hitting the end of a volume does not cause a write error unless the write was the first record of the volume. */ -static void +void archive_write_error (ssize_t status) { /* It might be useful to know how much was written before the error @@ -1022,7 +590,7 @@ archive_write_error (ssize_t status) /* Handle read errors on the archive. If the read should be retried, return to the caller. */ -static void +void archive_read_error (void) { read_error (*archive_name_cursor); @@ -1038,13 +606,65 @@ archive_read_error (void) return; } +static void +short_read (ssize_t status) +{ + size_t left; /* bytes left */ + char *more; /* pointer to next byte to read */ + + more = record_start->buffer + status; + left = record_size - status; + + while (left % BLOCKSIZE != 0 + || (left && status && read_full_records_option)) + { + if (status) + while ((status = rmtread (archive, more, left)) < 0) + archive_read_error (); + + if (status == 0) + break; + + if (! read_full_records_option) + { + unsigned long rest = record_size - left; + + FATAL_ERROR ((0, 0, + ngettext ("Unaligned block (%lu byte) in archive", + "Unaligned block (%lu bytes) in archive", + rest), + rest)); + } + + /* User warned us about this. Fix up. */ + + left -= status; + more += status; + } + + /* FIXME: for size=0, multi-volume support. On the first record, warn + about the problem. */ + + if (!read_full_records_option && verbose_option + && record_start_block == 0 && status > 0) + { + unsigned long rsize = (record_size - left) / BLOCKSIZE; + WARN ((0, 0, + ngettext ("Record size = %lu block", + "Record size = %lu blocks", + rsize), + rsize)); + } + + record_end = record_start + (record_size - left) / BLOCKSIZE; + records_read++; +} + /* Perform a read to flush the buffer. */ void flush_read (void) { ssize_t status; /* result from system call */ - size_t left; /* bytes left */ - char *more; /* pointer to next byte to read */ if (checkpoint_option && !(++checkpoint % 10)) WARN ((0, 0, _("Read checkpoint %d"), checkpoint)); @@ -1057,7 +677,7 @@ flush_read (void) if (write_archive_to_stdout && record_start_block != 0) { archive = STDOUT_FILENO; - status = write_archive_buffer (); + status = sys_write_archive_buffer (); archive = STDIN_FILENO; if (status != record_size) archive_write_error (status); @@ -1066,12 +686,7 @@ flush_read (void) { if (save_name) { - char *cursor = save_name + FILESYSTEM_PREFIX_LEN (save_name); - - while (ISSLASH (*cursor)) - cursor++; - - assign_string (&real_s_name, cursor); + assign_string (&real_s_name, safer_name_suffix (save_name, 0)); real_s_sizeleft = save_sizeleft; real_s_totsize = save_totsize; } @@ -1122,7 +737,7 @@ flush_read (void) goto vol_error; } if (status != record_size) - goto short_read; + short_read (status); cursor = record_start; @@ -1196,45 +811,7 @@ flush_read (void) goto error_loop; /* try again */ } - short_read: - more = record_start->buffer + status; - left = record_size - status; - - while (left % BLOCKSIZE != 0 - || (left && status && read_full_records_option)) - { - if (status) - while ((status = rmtread (archive, more, left)) < 0) - archive_read_error (); - - if (status == 0) - { - if (left % BLOCKSIZE != 0) - ERROR ((0, 0, _("%d garbage bytes ignored at end of archive"), - (int) ((record_size - left) % BLOCKSIZE))); - break; - } - - if (! read_full_records_option) - FATAL_ERROR ((0, 0, _("Unaligned block (%lu bytes) in archive"), - (unsigned long) (record_size - left))); - - /* User warned us about this. Fix up. */ - - left -= status; - more += status; - } - - /* FIXME: for size=0, multi-volume support. On the first record, warn - about the problem. */ - - if (!read_full_records_option && verbose_option - && record_start_block == 0 && status > 0) - WARN ((0, 0, _("Record size = %lu blocks"), - (unsigned long) ((record_size - left) / BLOCKSIZE))); - - record_end = record_start + (record_size - left) / BLOCKSIZE; - records_read++; + short_read (status); } /* Flush the current buffer to/from the archive. */ @@ -1326,52 +903,17 @@ close_archive (void) if (time_to_start_writing || access_mode == ACCESS_WRITE) flush_archive (); -#if !MSDOS - - /* Manage to fully drain a pipe we might be reading, so to not break it on - the producer after the EOF block. FIXME: one of these days, GNU tar - might become clever enough to just stop working, once there is no more - work to do, we might have to revise this area in such time. */ - - if (access_mode == ACCESS_READ - && ! _isrmt (archive) - && S_ISFIFO (archive_stat.st_mode)) - while (rmtread (archive, record_start->buffer, record_size) > 0) - continue; -#endif - + sys_drain_input_pipe (); + if (verify_option) verify_volume (); if (rmtclose (archive) != 0) close_warn (*archive_name_cursor); -#if !MSDOS - - if (child_pid) - { - int wait_status; - - while (waitpid (child_pid, &wait_status, 0) == -1) - if (errno != EINTR) - { - waitpid_error (use_compress_program_option); - break; - } - - if (WIFSIGNALED (wait_status)) - ERROR ((0, 0, _("Child died with signal %d"), - WTERMSIG (wait_status))); - else if (WEXITSTATUS (wait_status) != 0) - ERROR ((0, 0, _("Child returned status %d"), - WEXITSTATUS (wait_status))); - } -#endif /* !MSDOS */ - - if (current_file_name) - free (current_file_name); - if (current_link_name) - free (current_link_name); + sys_wait_for_child (child_pid); + + destroy_stat (¤t_stat_info); if (save_name) free (save_name); if (real_s_name) @@ -1532,38 +1074,18 @@ new_volume (enum access_mode access) break; case '!': -#if MSDOS - spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0); -#else /* not MSDOS */ - { - pid_t child; - const char *shell = getenv ("SHELL"); - if (! shell) - shell = "/bin/sh"; - child = xfork (); - if (child == 0) - { - execlp (shell, "-sh", "-i", 0); - exec_fatal (shell); - } - else - { - int wait_status; - while (waitpid (child, &wait_status, 0) == -1) - if (errno != EINTR) - { - waitpid_error (shell); - break; - } - } - } -#endif /* not MSDOS */ + sys_spawn_shell (); break; } } } - if (verify_option) + if (strcmp (archive_name_cursor[0], "-") == 0) + { + read_full_records_option = true; + archive = STDIN_FILENO; + } + else if (verify_option) archive = rmtopen (*archive_name_cursor, O_RDWR | O_CREAT, MODE_RW, rsh_command_option); else @@ -1595,9 +1117,8 @@ new_volume (enum access_mode access) goto tryagain; } -#if MSDOS - setmode (archive, O_BINARY); -#endif + SET_BINARY_MODE (archive); return 1; } +