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