- if(kidchildpid>0) {
- /* About to exec compress: set up the files */
- if(ar_reading) {
- dupto(kidpipe[READ],STDIN,"((child)) pipe to stdin");
- ck_close(kidpipe[WRITE]);
- /* dup2(pipe[WRITE],STDOUT); */
- } else {
- /* dup2(pipe[READ],STDIN); */
- dupto(kidpipe[WRITE],STDOUT,"((child)) pipe to stdout");
- ck_close(kidpipe[READ]);
- }
- /* ck_close(pipe[READ]); */
- /* ck_close(pipe[WRITE]); */
- /* ck_close(kidpipe[READ]);
- ck_close(kidpipe[WRITE]); */
- } else {
- /* Grandchild. Do the right thing, namely sit here and
- read/write the archive, and feed stuff back to compress */
- tar="tar (child)";
- if(ar_reading) {
- dupto(kidpipe[WRITE],STDOUT,"[child] pipe to stdout");
- ck_close(kidpipe[READ]);
- } else {
- dupto(kidpipe[READ],STDIN,"[child] pipe to stdin");
- ck_close(kidpipe[WRITE]);
- }
-
- if (ar_files[0][0] == '-' && ar_files[0][1] == '\0') {
- if (ar_reading)
- archive = STDIN;
- else
- archive = STDOUT;
- } else /* This can't happen if (ar_reading==2)
- archive = rmtopen(ar_files[0], O_RDWR|O_CREAT|O_BINARY, 0666);
- else */if(ar_reading)
- archive = rmtopen(ar_files[0], O_RDONLY|O_BINARY, 0666);
- else
- archive = rmtcreat(ar_files[0], 0666);
-
- if (archive < 0) {
- msg_perror("can't open archive %s",ar_files[0]);
- exit(EX_BADARCH);
- }
-
- if(ar_reading) {
- for(;;) {
- char *ptr;
- int max,count;
-
- r_error_count = 0;
- error_loop:
- err=rmtread(archive, ar_block->charptr,(int)(blocksize));
- if(err<0) {
- readerror();
- goto error_loop;
- }
- if(err==0)
- break;
- ptr = ar_block->charptr;
- max = err;
- while(max) {
- count = (max<RECORDSIZE) ? max : RECORDSIZE;
- err=write(STDOUT,ptr,count);
- if(err!=count) {
- if(err<0) {
- msg_perror("can't write to compress");
- exit(EX_SYSTEM);
- } else
- msg("write to compress short %d bytes",count-err);
- count = (err<0) ? 0 : err;
- }
- ptr+=count;
- max-=count;
- }
- }
- } else {
- for(;;) {
- int n;
- char *ptr;
-
- n=blocksize;
- ptr = ar_block->charptr;
- while(n) {
- err=read(STDIN,ptr,(n<RECORDSIZE) ? n : RECORDSIZE);
- if(err<=0)
- break;
- n-=err;
- ptr+=err;
- }
- /* EOF */
- if(err==0) {
- if(f_compress<2)
- blocksize-=n;
- else
- bzero(ar_block->charptr+blocksize-n,n);
- err=rmtwrite(archive,ar_block->charptr,blocksize);
- if(err!=(blocksize))
- writeerror(err);
- if(f_compress<2)
- blocksize+=n;
- break;
- }
- if(n) {
- msg_perror("can't read from compress");
- exit(EX_SYSTEM);
- }
- err=rmtwrite(archive, ar_block->charptr, (int)blocksize);
- if(err!=blocksize)
- writeerror(err);
- }
- }
-
- /* close_archive(); */
- exit(0);
- }
+/*---------------------------------------------------------.
+| Set ARCHIVE for uncompressing, then reading an archive. |
+`---------------------------------------------------------*/
+
+static void
+child_open_for_uncompress (void)
+{
+ int parent_pipe[2];
+ int child_pipe[2];
+ int grandchild_pid;
+
+ if (pipe (parent_pipe) < 0)
+ FATAL_ERROR ((0, errno, _("Cannot open pipe")));
+
+ child_pid = fork ();
+ if (child_pid < 0)
+ FATAL_ERROR ((0, errno, _("Cannot fork")));
+
+ 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 new born child tar is here! */
+
+ program_name = _("tar (child)");
+
+ xdup2 (parent_pipe[PWRITE], STDOUT, _("(child) Pipe to stdout"));
+ 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, 0666);
+ if (archive < 0)
+ FATAL_ERROR ((0, errno, _("Cannot open archive %s"),
+ archive_name_array[0]));
+ xdup2 (archive, STDIN, _("Archive to stdin"));
+ execlp (use_compress_program_option, use_compress_program_option,
+ "-d", (char *) 0);
+ FATAL_ERROR ((0, errno, _("Cannot exec %s"),
+ use_compress_program_option));
+ }
+
+ /* We do need a grandchild tar. */
+
+ if (pipe (child_pipe) < 0)
+ FATAL_ERROR ((0, errno, _("Cannot open pipe")));
+
+ grandchild_pid = fork ();
+ if (grandchild_pid < 0)
+ FATAL_ERROR ((0, errno, _("Child cannot fork")));
+
+ if (grandchild_pid > 0)
+ {
+ /* The child tar is still here! Launch the uncompressor. */
+
+ xdup2 (child_pipe[PREAD], STDIN, _("((child)) Pipe to stdin"));
+ xclose (child_pipe[PWRITE]);
+ execlp (use_compress_program_option, use_compress_program_option,
+ "-d", (char *) 0);
+ FATAL_ERROR ((0, errno, _("Cannot exec %s"),
+ use_compress_program_option));
+ }
+
+ /* The new born grandchild tar is here! */
+
+ program_name = _("tar (grandchild)");
+
+ /* Prepare for unblocking the data from the archive into the uncompressor. */
+
+ xdup2 (child_pipe[PWRITE], STDOUT, _("(grandchild) Pipe to stdout"));
+ xclose (child_pipe[PREAD]);
+
+ if (strcmp (archive_name_array[0], "-") == 0)
+ archive = STDIN;
+ else
+ archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
+ 0666, rsh_command_option);
+ if (archive < 0)
+ FATAL_ERROR ((0, errno, _("Cannot open archive %s"),
+ archive_name_array[0]));
+
+ /* Let's read the archive and pipe it into stdout. */
+
+ while (1)
+ {
+ char *cursor;
+ int maximum;
+ int count;
+ int status;
+
+ read_error_count = 0;
+
+ error_loop:
+ status = rmtread (archive, record_start->buffer,
+ (unsigned int) (record_size));
+ if (status < 0)
+ {
+ read_error ();
+ goto error_loop;