1 /* System-dependent calls for tar.
2 
3    Copyright 2003-2021 Free Software Foundation, Inc.
4 
5    This program is free software; you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by the
7    Free Software Foundation; either version 3, or (at your option) any later
8    version.
9 
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
13    Public License for more details.
14 
15    You should have received a copy of the GNU General Public License along
16    with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17 
18 #include <system.h>
19 
20 #include "common.h"
21 #include <priv-set.h>
22 #include <rmt.h>
23 #include <signal.h>
24 #include <wordsplit.h>
25 
26 static _Noreturn void
xexec(const char * cmd)27 xexec (const char *cmd)
28 {
29   char *argv[4];
30 
31   argv[0] = (char *) "/bin/sh";
32   argv[1] = (char *) "-c";
33   argv[2] = (char *) cmd;
34   argv[3] = NULL;
35 
36   execv ("/bin/sh", argv);
37   exec_fatal (cmd);
38 }
39 
40 #if MSDOS
41 
42 bool
sys_get_archive_stat(void)43 sys_get_archive_stat (void)
44 {
45   return 0;
46 }
47 
48 bool
sys_file_is_archive(struct tar_stat_info * p)49 sys_file_is_archive (struct tar_stat_info *p)
50 {
51   return false;
52 }
53 
54 void
sys_save_archive_dev_ino(void)55 sys_save_archive_dev_ino (void)
56 {
57 }
58 
59 void
sys_detect_dev_null_output(void)60 sys_detect_dev_null_output (void)
61 {
62   static char const dev_null[] = "nul";
63 
64   dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0
65 		     || (! _isrmt (archive)));
66 }
67 
68 void
sys_wait_for_child(pid_t child_pid,bool eof)69 sys_wait_for_child (pid_t child_pid, bool eof)
70 {
71 }
72 
73 void
sys_spawn_shell(void)74 sys_spawn_shell (void)
75 {
76   spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
77 }
78 
79 /* stat() in djgpp's C library gives a constant number of 42 as the
80    uid and gid of a file.  So, comparing an FTP'ed archive just after
81    unpack would fail on MSDOS.  */
82 
83 bool
sys_compare_uid(struct stat * a,struct stat * b)84 sys_compare_uid (struct stat *a, struct stat *b)
85 {
86   return true;
87 }
88 
89 bool
sys_compare_gid(struct stat * a,struct stat * b)90 sys_compare_gid (struct stat *a, struct stat *b)
91 {
92   return true;
93 }
94 
95 void
sys_compare_links(struct stat * link_data,struct stat * stat_data)96 sys_compare_links (struct stat *link_data, struct stat *stat_data)
97 {
98   return true;
99 }
100 
101 int
sys_truncate(int fd)102 sys_truncate (int fd)
103 {
104   return write (fd, "", 0);
105 }
106 
107 size_t
sys_write_archive_buffer(void)108 sys_write_archive_buffer (void)
109 {
110   return full_write (archive, record_start->buffer, record_size);
111 }
112 
113 /* Set ARCHIVE for writing, then compressing an archive.  */
114 void
sys_child_open_for_compress(void)115 sys_child_open_for_compress (void)
116 {
117   FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
118 }
119 
120 /* Set ARCHIVE for uncompressing, then reading an archive.  */
121 void
sys_child_open_for_uncompress(void)122 sys_child_open_for_uncompress (void)
123 {
124   FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
125 }
126 
127 #else
128 
129 extern union block *record_start; /* FIXME */
130 
131 static struct stat archive_stat; /* stat block for archive file */
132 
133 bool
sys_get_archive_stat(void)134 sys_get_archive_stat (void)
135 {
136   return fstat (archive, &archive_stat) == 0;
137 }
138 
139 bool
sys_file_is_archive(struct tar_stat_info * p)140 sys_file_is_archive (struct tar_stat_info *p)
141 {
142   return (ar_dev && p->stat.st_dev == ar_dev && p->stat.st_ino == ar_ino);
143 }
144 
145 /* Save archive file inode and device numbers */
146 void
sys_save_archive_dev_ino(void)147 sys_save_archive_dev_ino (void)
148 {
149   if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode))
150     {
151       ar_dev = archive_stat.st_dev;
152       ar_ino = archive_stat.st_ino;
153     }
154   else
155     ar_dev = 0;
156 }
157 
158 /* Detect if outputting to "/dev/null".  */
159 void
sys_detect_dev_null_output(void)160 sys_detect_dev_null_output (void)
161 {
162   static char const dev_null[] = "/dev/null";
163   struct stat dev_null_stat;
164 
165   dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0
166 		     || (! _isrmt (archive)
167 			 && S_ISCHR (archive_stat.st_mode)
168 			 && stat (dev_null, &dev_null_stat) == 0
169 			 && archive_stat.st_dev == dev_null_stat.st_dev
170 			 && archive_stat.st_ino == dev_null_stat.st_ino));
171 }
172 
173 void
sys_wait_for_child(pid_t child_pid,bool eof)174 sys_wait_for_child (pid_t child_pid, bool eof)
175 {
176   if (child_pid)
177     {
178       int wait_status;
179 
180       while (waitpid (child_pid, &wait_status, 0) == -1)
181 	if (errno != EINTR)
182 	  {
183 	    waitpid_error (use_compress_program_option);
184 	    break;
185 	  }
186 
187       if (WIFSIGNALED (wait_status))
188 	{
189 	  int sig = WTERMSIG (wait_status);
190 	  if (!(!eof && sig == SIGPIPE))
191 	    FATAL_ERROR ((0, 0, _("Child died with signal %d"), sig));
192 	}
193       else if (WEXITSTATUS (wait_status) != 0)
194 	FATAL_ERROR ((0, 0, _("Child returned status %d"),
195 		      WEXITSTATUS (wait_status)));
196     }
197 }
198 
199 void
sys_spawn_shell(void)200 sys_spawn_shell (void)
201 {
202   pid_t child;
203   const char *shell = getenv ("SHELL");
204   if (! shell)
205     shell = "/bin/sh";
206   child = xfork ();
207   if (child == 0)
208     {
209       priv_set_restore_linkdir ();
210       execlp (shell, "-sh", "-i", NULL);
211       exec_fatal (shell);
212     }
213   else
214     {
215       int wait_status;
216       while (waitpid (child, &wait_status, 0) == -1)
217 	if (errno != EINTR)
218 	  {
219 	    waitpid_error (shell);
220 	    break;
221 	  }
222     }
223 }
224 
225 bool
sys_compare_uid(struct stat * a,struct stat * b)226 sys_compare_uid (struct stat *a, struct stat *b)
227 {
228   return a->st_uid == b->st_uid;
229 }
230 
231 bool
sys_compare_gid(struct stat * a,struct stat * b)232 sys_compare_gid (struct stat *a, struct stat *b)
233 {
234   return a->st_gid == b->st_gid;
235 }
236 
237 bool
sys_compare_links(struct stat * link_data,struct stat * stat_data)238 sys_compare_links (struct stat *link_data, struct stat *stat_data)
239 {
240   return stat_data->st_dev == link_data->st_dev
241          && stat_data->st_ino == link_data->st_ino;
242 }
243 
244 int
sys_truncate(int fd)245 sys_truncate (int fd)
246 {
247   off_t pos = lseek (fd, (off_t) 0, SEEK_CUR);
248   return pos < 0 ? -1 : ftruncate (fd, pos);
249 }
250 
251 /* Return nonzero if NAME is the name of a regular file, or if the file
252    does not exist (so it would be created as a regular file).  */
253 static int
is_regular_file(const char * name)254 is_regular_file (const char *name)
255 {
256   struct stat stbuf;
257 
258   if (stat (name, &stbuf) == 0)
259     return S_ISREG (stbuf.st_mode);
260   else
261     return errno == ENOENT;
262 }
263 
264 size_t
sys_write_archive_buffer(void)265 sys_write_archive_buffer (void)
266 {
267   return rmtwrite (archive, record_start->buffer, record_size);
268 }
269 
270 #define	PREAD 0			/* read file descriptor from pipe() */
271 #define	PWRITE 1		/* write file descriptor from pipe() */
272 
273 /* Duplicate file descriptor FROM into becoming INTO.
274    INTO is closed first and has to be the next available slot.  */
275 static void
xdup2(int from,int into)276 xdup2 (int from, int into)
277 {
278   if (from != into)
279     {
280       int status = close (into);
281 
282       if (status != 0 && errno != EBADF)
283 	{
284 	  int e = errno;
285 	  FATAL_ERROR ((0, e, _("Cannot close")));
286 	}
287       status = dup (from);
288       if (status != into)
289 	{
290 	  if (status < 0)
291 	    {
292 	      int e = errno;
293 	      FATAL_ERROR ((0, e, _("Cannot dup")));
294 	    }
295 	  abort ();
296 	}
297       xclose (from);
298     }
299 }
300 
301 static void wait_for_grandchild (pid_t pid) __attribute__ ((__noreturn__));
302 
303 /* Propagate any failure of the grandchild back to the parent.  */
304 static void
wait_for_grandchild(pid_t pid)305 wait_for_grandchild (pid_t pid)
306 {
307   int wait_status;
308   int exit_code = 0;
309 
310   while (waitpid (pid, &wait_status, 0) == -1)
311     if (errno != EINTR)
312       {
313 	waitpid_error (use_compress_program_option);
314 	break;
315       }
316 
317   if (WIFSIGNALED (wait_status))
318     raise (WTERMSIG (wait_status));
319   else if (WEXITSTATUS (wait_status) != 0)
320     exit_code = WEXITSTATUS (wait_status);
321 
322   exit (exit_code);
323 }
324 
325 /* Set ARCHIVE for writing, then compressing an archive.  */
326 pid_t
sys_child_open_for_compress(void)327 sys_child_open_for_compress (void)
328 {
329   int parent_pipe[2];
330   int child_pipe[2];
331   pid_t grandchild_pid;
332   pid_t child_pid;
333 
334   signal (SIGPIPE, SIG_IGN);
335   xpipe (parent_pipe);
336   child_pid = xfork ();
337 
338   if (child_pid > 0)
339     {
340       /* The parent tar is still here!  Just clean up.  */
341 
342       archive = parent_pipe[PWRITE];
343       xclose (parent_pipe[PREAD]);
344       return child_pid;
345     }
346 
347   /* The new born child tar is here!  */
348 
349   set_program_name (_("tar (child)"));
350   signal (SIGPIPE, SIG_DFL);
351 
352   xdup2 (parent_pipe[PREAD], STDIN_FILENO);
353   xclose (parent_pipe[PWRITE]);
354 
355   /* Check if we need a grandchild tar.  This happens only if either:
356      a) the file is to be accessed by rmt: compressor doesn't know how;
357      b) the file is not a plain file.  */
358 
359   if (!_remdev (archive_name_array[0])
360       && is_regular_file (archive_name_array[0]))
361     {
362       if (backup_option)
363 	maybe_backup_file (archive_name_array[0], 1);
364 
365       /* We don't need a grandchild tar.  Open the archive and launch the
366 	 compressor.  */
367       if (strcmp (archive_name_array[0], "-"))
368 	{
369 	  archive = creat (archive_name_array[0], MODE_RW);
370 	  if (archive < 0)
371 	    {
372 	      int saved_errno = errno;
373 
374 	      if (backup_option)
375 		undo_last_backup ();
376 	      errno = saved_errno;
377 	      open_fatal (archive_name_array[0]);
378 	    }
379 	  xdup2 (archive, STDOUT_FILENO);
380 	}
381       priv_set_restore_linkdir ();
382       xexec (use_compress_program_option);
383     }
384 
385   /* We do need a grandchild tar.  */
386 
387   xpipe (child_pipe);
388   grandchild_pid = xfork ();
389 
390   if (grandchild_pid == 0)
391     {
392       /* The newborn grandchild tar is here!  Launch the compressor.  */
393 
394       set_program_name (_("tar (grandchild)"));
395 
396       xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
397       xclose (child_pipe[PREAD]);
398       priv_set_restore_linkdir ();
399       xexec (use_compress_program_option);
400     }
401 
402   /* The child tar is still here!  */
403 
404   /* Prepare for reblocking the data from the compressor into the archive.  */
405 
406   xdup2 (child_pipe[PREAD], STDIN_FILENO);
407   xclose (child_pipe[PWRITE]);
408 
409   if (strcmp (archive_name_array[0], "-") == 0)
410     archive = STDOUT_FILENO;
411   else
412     {
413       archive = rmtcreat (archive_name_array[0], MODE_RW, rsh_command_option);
414       if (archive < 0)
415 	open_fatal (archive_name_array[0]);
416     }
417 
418   /* Let's read out of the stdin pipe and write an archive.  */
419 
420   while (1)
421     {
422       size_t status = 0;
423       char *cursor;
424       size_t length;
425 
426       /* Assemble a record.  */
427 
428       for (length = 0, cursor = record_start->buffer;
429 	   length < record_size;
430 	   length += status, cursor += status)
431 	{
432 	  size_t size = record_size - length;
433 
434 	  status = safe_read (STDIN_FILENO, cursor, size);
435 	  if (status == SAFE_READ_ERROR)
436 	    read_fatal (use_compress_program_option);
437 	  if (status == 0)
438 	    break;
439 	}
440 
441       /* Copy the record.  */
442 
443       if (status == 0)
444 	{
445 	  /* We hit the end of the file.  Write last record at
446 	     full length, as the only role of the grandchild is
447 	     doing proper reblocking.  */
448 
449 	  if (length > 0)
450 	    {
451 	      memset (record_start->buffer + length, 0, record_size - length);
452 	      status = sys_write_archive_buffer ();
453 	      if (status != record_size)
454 		archive_write_error (status);
455 	    }
456 
457 	  /* There is nothing else to read, break out.  */
458 	  break;
459 	}
460 
461       status = sys_write_archive_buffer ();
462       if (status != record_size)
463 	archive_write_error (status);
464     }
465 
466   wait_for_grandchild (grandchild_pid);
467 }
468 
469 static void
run_decompress_program(void)470 run_decompress_program (void)
471 {
472   int i;
473   const char *p, *prog = NULL;
474   struct wordsplit ws;
475   int wsflags = (WRDSF_DEFFLAGS | WRDSF_ENV | WRDSF_DOOFFS) & ~WRDSF_NOVAR;
476 
477   ws.ws_env = (const char **) environ;
478   ws.ws_offs = 1;
479 
480   for (p = first_decompress_program (&i); p; p = next_decompress_program (&i))
481     {
482       if (prog)
483 	{
484 	  WARNOPT (WARN_DECOMPRESS_PROGRAM,
485 		   (0, errno, _("cannot run %s"), prog));
486 	  WARNOPT (WARN_DECOMPRESS_PROGRAM,
487 		   (0, 0, _("trying %s"), p));
488 	}
489       if (wordsplit (p, &ws, wsflags))
490 	FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
491 		      p, wordsplit_strerror (&ws)));
492       wsflags |= WRDSF_REUSE;
493       memmove(ws.ws_wordv, ws.ws_wordv + ws.ws_offs,
494 	      sizeof(ws.ws_wordv[0])*ws.ws_wordc);
495       ws.ws_wordv[ws.ws_wordc] = (char *) "-d";
496       prog = p;
497       execvp (ws.ws_wordv[0], ws.ws_wordv);
498       ws.ws_wordv[ws.ws_wordc] = NULL;
499     }
500   if (!prog)
501     FATAL_ERROR ((0, 0, _("unable to run decompression program")));
502   exec_fatal (prog);
503 }
504 
505 /* Set ARCHIVE for uncompressing, then reading an archive.  */
506 pid_t
sys_child_open_for_uncompress(void)507 sys_child_open_for_uncompress (void)
508 {
509   int parent_pipe[2];
510   int child_pipe[2];
511   pid_t grandchild_pid;
512   pid_t child_pid;
513 
514   xpipe (parent_pipe);
515   child_pid = xfork ();
516 
517   if (child_pid > 0)
518     {
519       /* The parent tar is still here!  Just clean up.  */
520 
521       archive = parent_pipe[PREAD];
522       xclose (parent_pipe[PWRITE]);
523       return child_pid;
524     }
525 
526   /* The newborn child tar is here!  */
527 
528   set_program_name (_("tar (child)"));
529   signal (SIGPIPE, SIG_DFL);
530 
531   xdup2 (parent_pipe[PWRITE], STDOUT_FILENO);
532   xclose (parent_pipe[PREAD]);
533 
534   /* Check if we need a grandchild tar.  This happens only if either:
535      a) we're reading stdin: to force unblocking;
536      b) the file is to be accessed by rmt: compressor doesn't know how;
537      c) the file is not a plain file.  */
538 
539   if (strcmp (archive_name_array[0], "-") != 0
540       && !_remdev (archive_name_array[0])
541       && is_regular_file (archive_name_array[0]))
542     {
543       /* We don't need a grandchild tar.  Open the archive and lauch the
544 	 uncompressor.  */
545 
546       archive = open (archive_name_array[0], O_RDONLY | O_BINARY, MODE_RW);
547       if (archive < 0)
548 	open_fatal (archive_name_array[0]);
549       xdup2 (archive, STDIN_FILENO);
550       priv_set_restore_linkdir ();
551       run_decompress_program ();
552     }
553 
554   /* We do need a grandchild tar.  */
555 
556   xpipe (child_pipe);
557   grandchild_pid = xfork ();
558 
559   if (grandchild_pid == 0)
560     {
561       /* The newborn grandchild tar is here!  Launch the uncompressor.  */
562 
563       set_program_name (_("tar (grandchild)"));
564 
565       xdup2 (child_pipe[PREAD], STDIN_FILENO);
566       xclose (child_pipe[PWRITE]);
567       priv_set_restore_linkdir ();
568       run_decompress_program ();
569     }
570 
571   /* The child tar is still here!  */
572 
573   /* Prepare for unblocking the data from the archive into the
574      uncompressor.  */
575 
576   xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
577   xclose (child_pipe[PREAD]);
578 
579   if (strcmp (archive_name_array[0], "-") == 0)
580     archive = STDIN_FILENO;
581   else
582     archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
583 		       MODE_RW, rsh_command_option);
584   if (archive < 0)
585     open_fatal (archive_name_array[0]);
586 
587   /* Let's read the archive and pipe it into stdout.  */
588 
589   while (1)
590     {
591       char *cursor;
592       size_t maximum;
593       size_t count;
594       size_t status;
595 
596       clear_read_error_count ();
597 
598     error_loop:
599       status = rmtread (archive, record_start->buffer, record_size);
600       if (status == SAFE_READ_ERROR)
601 	{
602 	  archive_read_error ();
603 	  goto error_loop;
604 	}
605       if (status == 0)
606 	break;
607       cursor = record_start->buffer;
608       maximum = status;
609       while (maximum)
610 	{
611 	  count = maximum < BLOCKSIZE ? maximum : BLOCKSIZE;
612 	  if (full_write (STDOUT_FILENO, cursor, count) != count)
613 	    write_error (use_compress_program_option);
614 	  cursor += count;
615 	  maximum -= count;
616 	}
617     }
618 
619   xclose (STDOUT_FILENO);
620 
621   wait_for_grandchild (grandchild_pid);
622 }
623 
624 
625 
626 static void
dec_to_env(char const * envar,uintmax_t num)627 dec_to_env (char const *envar, uintmax_t num)
628 {
629   char buf[UINTMAX_STRSIZE_BOUND];
630   char *numstr;
631 
632   numstr = STRINGIFY_BIGINT (num, buf);
633   if (setenv (envar, numstr, 1) != 0)
634     xalloc_die ();
635 }
636 
637 static void
time_to_env(char const * envar,struct timespec t)638 time_to_env (char const *envar, struct timespec t)
639 {
640   char buf[TIMESPEC_STRSIZE_BOUND];
641   if (setenv (envar, code_timespec (t, buf), 1) != 0)
642     xalloc_die ();
643 }
644 
645 static void
oct_to_env(char const * envar,unsigned long num)646 oct_to_env (char const *envar, unsigned long num)
647 {
648   char buf[1+1+(sizeof(unsigned long)*CHAR_BIT+2)/3];
649 
650   snprintf (buf, sizeof buf, "0%lo", num);
651   if (setenv (envar, buf, 1) != 0)
652     xalloc_die ();
653 }
654 
655 static void
str_to_env(char const * envar,char const * str)656 str_to_env (char const *envar, char const *str)
657 {
658   if (str)
659     {
660       if (setenv (envar, str, 1) != 0)
661 	xalloc_die ();
662     }
663   else
664     unsetenv (envar);
665 }
666 
667 static void
chr_to_env(char const * envar,char c)668 chr_to_env (char const *envar, char c)
669 {
670   char buf[2];
671   buf[0] = c;
672   buf[1] = 0;
673   if (setenv (envar, buf, 1) != 0)
674     xalloc_die ();
675 }
676 
677 static void
stat_to_env(char * name,char type,struct tar_stat_info * st)678 stat_to_env (char *name, char type, struct tar_stat_info *st)
679 {
680   str_to_env ("TAR_VERSION", PACKAGE_VERSION);
681   str_to_env ("TAR_ARCHIVE", *archive_name_cursor);
682   dec_to_env ("TAR_VOLUME", archive_name_cursor - archive_name_array + 1);
683   dec_to_env ("TAR_BLOCKING_FACTOR", blocking_factor);
684   str_to_env ("TAR_FORMAT",
685 	      archive_format_string (current_format == DEFAULT_FORMAT ?
686 				     archive_format : current_format));
687   chr_to_env ("TAR_FILETYPE", type);
688   oct_to_env ("TAR_MODE", st->stat.st_mode);
689   str_to_env ("TAR_FILENAME", name);
690   str_to_env ("TAR_REALNAME", st->file_name);
691   str_to_env ("TAR_UNAME", st->uname);
692   str_to_env ("TAR_GNAME", st->gname);
693   time_to_env ("TAR_ATIME", st->atime);
694   time_to_env ("TAR_MTIME", st->mtime);
695   time_to_env ("TAR_CTIME", st->ctime);
696   dec_to_env ("TAR_SIZE", st->stat.st_size);
697   dec_to_env ("TAR_UID", st->stat.st_uid);
698   dec_to_env ("TAR_GID", st->stat.st_gid);
699 
700   switch (type)
701     {
702     case 'b':
703     case 'c':
704       dec_to_env ("TAR_MINOR", minor (st->stat.st_rdev));
705       dec_to_env ("TAR_MAJOR", major (st->stat.st_rdev));
706       unsetenv ("TAR_LINKNAME");
707       break;
708 
709     case 'l':
710     case 'h':
711       unsetenv ("TAR_MINOR");
712       unsetenv ("TAR_MAJOR");
713       str_to_env ("TAR_LINKNAME", st->link_name);
714       break;
715 
716     default:
717       unsetenv ("TAR_MINOR");
718       unsetenv ("TAR_MAJOR");
719       unsetenv ("TAR_LINKNAME");
720       break;
721     }
722 }
723 
724 static pid_t global_pid;
725 static void (*pipe_handler) (int sig);
726 
727 int
sys_exec_command(char * file_name,int typechar,struct tar_stat_info * st)728 sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st)
729 {
730   int p[2];
731 
732   xpipe (p);
733   pipe_handler = signal (SIGPIPE, SIG_IGN);
734   global_pid = xfork ();
735 
736   if (global_pid != 0)
737     {
738       xclose (p[PREAD]);
739       return p[PWRITE];
740     }
741 
742   /* Child */
743   xdup2 (p[PREAD], STDIN_FILENO);
744   xclose (p[PWRITE]);
745 
746   stat_to_env (file_name, typechar, st);
747 
748   priv_set_restore_linkdir ();
749   xexec (to_command_option);
750 }
751 
752 void
sys_wait_command(void)753 sys_wait_command (void)
754 {
755   int status;
756 
757   if (global_pid < 0)
758     return;
759 
760   signal (SIGPIPE, pipe_handler);
761   while (waitpid (global_pid, &status, 0) == -1)
762     if (errno != EINTR)
763       {
764         global_pid = -1;
765         waitpid_error (to_command_option);
766         return;
767       }
768 
769   if (WIFEXITED (status))
770     {
771       if (!ignore_command_error_option && WEXITSTATUS (status))
772 	ERROR ((0, 0, _("%lu: Child returned status %d"),
773 		(unsigned long) global_pid, WEXITSTATUS (status)));
774     }
775   else if (WIFSIGNALED (status))
776     {
777       WARN ((0, 0, _("%lu: Child terminated on signal %d"),
778 	     (unsigned long) global_pid, WTERMSIG (status)));
779     }
780   else
781     ERROR ((0, 0, _("%lu: Child terminated on unknown reason"),
782 	    (unsigned long) global_pid));
783 
784   global_pid = -1;
785 }
786 
787 int
sys_exec_info_script(const char ** archive_name,int volume_number)788 sys_exec_info_script (const char **archive_name, int volume_number)
789 {
790   pid_t pid;
791   char uintbuf[UINTMAX_STRSIZE_BOUND];
792   int p[2];
793   static void (*saved_handler) (int sig);
794 
795   xpipe (p);
796   saved_handler = signal (SIGPIPE, SIG_IGN);
797 
798   pid = xfork ();
799 
800   if (pid != 0)
801     {
802       /* Master */
803 
804       int rc;
805       int status;
806       char *buf = NULL;
807       size_t size = 0;
808       FILE *fp;
809 
810       xclose (p[PWRITE]);
811       fp = fdopen (p[PREAD], "r");
812       rc = getline (&buf, &size, fp);
813       fclose (fp);
814 
815       if (rc > 0 && buf[rc-1] == '\n')
816 	buf[--rc] = 0;
817 
818       while (waitpid (pid, &status, 0) == -1)
819 	if (errno != EINTR)
820 	  {
821 	    signal (SIGPIPE, saved_handler);
822 	    waitpid_error (info_script_option);
823 	    return -1;
824 	  }
825 
826       signal (SIGPIPE, saved_handler);
827 
828       if (WIFEXITED (status))
829 	{
830 	  if (WEXITSTATUS (status) == 0 && rc > 0)
831 	    *archive_name = buf;
832 	  else
833 	    free (buf);
834 	  return WEXITSTATUS (status);
835 	}
836 
837       free (buf);
838       return -1;
839     }
840 
841   /* Child */
842   setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
843   setenv ("TAR_ARCHIVE", *archive_name, 1);
844   setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1);
845   setenv ("TAR_BLOCKING_FACTOR",
846 	  STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
847   setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
848   setenv ("TAR_FORMAT",
849 	  archive_format_string (current_format == DEFAULT_FORMAT ?
850 				 archive_format : current_format), 1);
851   setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1);
852 
853   xclose (p[PREAD]);
854 
855   priv_set_restore_linkdir ();
856   xexec (info_script_option);
857 }
858 
859 void
sys_exec_checkpoint_script(const char * script_name,const char * archive_name,int checkpoint_number)860 sys_exec_checkpoint_script (const char *script_name,
861 			    const char *archive_name,
862 			    int checkpoint_number)
863 {
864   pid_t pid;
865   char uintbuf[UINTMAX_STRSIZE_BOUND];
866 
867   pid = xfork ();
868 
869   if (pid != 0)
870     {
871       /* Master */
872 
873       int status;
874 
875       while (waitpid (pid, &status, 0) == -1)
876 	if (errno != EINTR)
877 	  {
878 	    waitpid_error (script_name);
879 	    break;
880 	  }
881 
882       return;
883     }
884 
885   /* Child */
886   setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
887   setenv ("TAR_ARCHIVE", archive_name, 1);
888   setenv ("TAR_CHECKPOINT", STRINGIFY_BIGINT (checkpoint_number, uintbuf), 1);
889   setenv ("TAR_BLOCKING_FACTOR",
890 	  STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
891   setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
892   setenv ("TAR_FORMAT",
893 	  archive_format_string (current_format == DEFAULT_FORMAT ?
894 				 archive_format : current_format), 1);
895   priv_set_restore_linkdir ();
896   xexec (script_name);
897 }
898 
899 #endif /* not MSDOS */
900