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