- int pipe[2];
- int err = 0;
- int nar;
-
- int kidpipe[2];
- int kidchildpid;
-
-#define READ 0
-#define WRITE 1
-
- ck_pipe (pipe);
-
- childpid = fork ();
- if (childpid < 0)
- {
- msg_perror ("cannot fork");
- exit (EX_SYSTEM);
- }
- if (childpid > 0)
- {
- /* We're the parent. Clean up and be happy */
- /* This, at least, is easy */
-
- if (ar_reading)
- {
- f_reblock++;
- archive = pipe[READ];
- ck_close (pipe[WRITE]);
- }
- else
- {
- archive = pipe[WRITE];
- ck_close (pipe[READ]);
- }
- return;
- }
-
- /* We're the kid */
- if (ar_reading)
- {
- dupto (pipe[WRITE], STDOUT, "(child) pipe to stdout");
- ck_close (pipe[READ]);
- }
- else
- {
- dupto (pipe[READ], STDIN, "(child) pipe to stdin");
- ck_close (pipe[WRITE]);
- }
-
- /* We need a child tar only if
- 1: we're reading/writing stdin/out (to force reblocking)
- 2: the file is to be accessed by rmt (compress doesn't know how)
- 3: the file is not a plain file */
-#ifdef NO_REMOTE
- if (!(ar_files[0][0] == '-' && ar_files[0][1] == '\0') && isfile (ar_files[0]))
-#else
- if (!(ar_files[0][0] == '-' && ar_files[0][1] == '\0') && !_remdev (ar_files[0]) && isfile (ar_files[0]))
-#endif
- {
- /* We don't need a child tar. Open the archive */
- if (ar_reading)
- {
- archive = open (ar_files[0], O_RDONLY | O_BINARY, 0666);
- if (archive < 0)
- {
- msg_perror ("can't open archive %s", ar_files[0]);
- exit (EX_BADARCH);
- }
- dupto (archive, STDIN, "archive to stdin");
- /* close(archive); */
- }
- else
- {
- archive = creat (ar_files[0], 0666);
- if (archive < 0)
- {
- msg_perror ("can't open archive %s", ar_files[0]);
- exit (EX_BADARCH);
- }
- dupto (archive, STDOUT, "archive to stdout");
- /* close(archive); */
- }
- }
- else
- {
- /* We need a child tar */
- ck_pipe (kidpipe);
-
- kidchildpid = fork ();
- if (kidchildpid < 0)
- {
- msg_perror ("child can't fork");
- exit (EX_SYSTEM);
- }
-
- 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);
- }
- }