Merge recent gnulib changes, and remove some lint.
[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    59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 void
122 sys_reset_uid_gid (void)
123 {
124 }
125
126 size_t
127 sys_write_archive_buffer (void)
128 {
129   return full_write (archive, record_start->buffer, record_size);
130 }
131
132 /* Set ARCHIVE for writing, then compressing an archive.  */
133 void
134 sys_child_open_for_compress (void)
135 {
136   FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
137 }
138
139 /* Set ARCHIVE for uncompressing, then reading an archive.  */
140 void
141 sys_child_open_for_uncompress (void)
142 {
143   FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
144 }
145
146 #else
147
148 extern union block *record_start; /* FIXME */
149
150 static struct stat archive_stat; /* stat block for archive file */
151
152 bool
153 sys_get_archive_stat (void)
154 {
155   return fstat (archive, &archive_stat) == 0;
156 }
157
158 bool
159 sys_file_is_archive (struct tar_stat_info *p)
160 {
161   return (ar_dev && p->stat.st_dev == ar_dev && p->stat.st_ino == ar_ino);
162 }
163
164 /* Save archive file inode and device numbers */
165 void
166 sys_save_archive_dev_ino (void)
167 {
168   if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode))
169     {
170       ar_dev = archive_stat.st_dev;
171       ar_ino = archive_stat.st_ino;
172     }
173   else
174     ar_dev = 0;
175 }
176
177 /* Detect if outputting to "/dev/null".  */
178 void
179 sys_detect_dev_null_output (void)
180 {
181   static char const dev_null[] = "/dev/null";
182   struct stat dev_null_stat;
183
184   dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0
185                      || (! _isrmt (archive)
186                          && S_ISCHR (archive_stat.st_mode)
187                          && stat (dev_null, &dev_null_stat) == 0
188                          && archive_stat.st_dev == dev_null_stat.st_dev
189                          && archive_stat.st_ino == dev_null_stat.st_ino));
190 }
191
192 /* Manage to fully drain a pipe we might be reading, so to not break it on
193    the producer after the EOF block.  FIXME: one of these days, GNU tar
194    might become clever enough to just stop working, once there is no more
195    work to do, we might have to revise this area in such time.  */
196
197 void
198 sys_drain_input_pipe (void)
199 {
200   size_t r;
201
202   if (access_mode == ACCESS_READ
203       && ! _isrmt (archive)
204       && (S_ISFIFO (archive_stat.st_mode) || S_ISSOCK (archive_stat.st_mode)))
205     while ((r = rmtread (archive, record_start->buffer, record_size)) != 0
206            && r != SAFE_READ_ERROR)
207       continue;
208 }
209
210 void
211 sys_wait_for_child (pid_t child_pid)
212 {
213   if (child_pid)
214     {
215       int wait_status;
216
217       while (waitpid (child_pid, &wait_status, 0) == -1)
218         if (errno != EINTR)
219           {
220             waitpid_error (use_compress_program_option);
221             break;
222           }
223
224       if (WIFSIGNALED (wait_status))
225         ERROR ((0, 0, _("Child died with signal %d"),
226                 WTERMSIG (wait_status)));
227       else if (WEXITSTATUS (wait_status) != 0)
228         ERROR ((0, 0, _("Child returned status %d"),
229                 WEXITSTATUS (wait_status)));
230     }
231 }
232
233 void
234 sys_spawn_shell (void)
235 {
236   pid_t child;
237   const char *shell = getenv ("SHELL");
238   if (! shell)
239     shell = "/bin/sh";
240   child = xfork ();
241   if (child == 0)
242     {
243       execlp (shell, "-sh", "-i", (char *) 0);
244       exec_fatal (shell);
245     }
246   else
247     {
248       int wait_status;
249       while (waitpid (child, &wait_status, 0) == -1)
250         if (errno != EINTR)
251           {
252             waitpid_error (shell);
253             break;
254           }
255     }
256 }
257
258 bool
259 sys_compare_uid (struct stat *a, struct stat *b)
260 {
261   return a->st_uid == b->st_uid;
262 }
263
264 bool
265 sys_compare_gid (struct stat *a, struct stat *b)
266 {
267   return a->st_gid == b->st_gid;
268 }
269
270 bool
271 sys_compare_links (struct stat *link_data, struct stat *stat_data)
272 {
273   return stat_data->st_dev == link_data->st_dev
274          && stat_data->st_ino == link_data->st_ino;
275 }
276
277 int
278 sys_truncate (int fd)
279 {
280   off_t pos = lseek (fd, (off_t) 0, SEEK_CUR);
281   return pos < 0 ? -1 : ftruncate (fd, pos);
282 }
283
284 void
285 sys_reset_uid_gid (void)
286 {
287   setuid (getuid ());
288   setgid (getgid ());
289 }
290
291 /* Return nonzero if NAME is the name of a regular file, or if the file
292    does not exist (so it would be created as a regular file).  */
293 static int
294 is_regular_file (const char *name)
295 {
296   struct stat stbuf;
297
298   if (stat (name, &stbuf) == 0)
299     return S_ISREG (stbuf.st_mode);
300   else
301     return errno == ENOENT;
302 }
303
304 size_t
305 sys_write_archive_buffer (void)
306 {
307   return rmtwrite (archive, record_start->buffer, record_size);
308 }
309
310 #define PREAD 0                 /* read file descriptor from pipe() */
311 #define PWRITE 1                /* write file descriptor from pipe() */
312
313 /* Duplicate file descriptor FROM into becoming INTO.
314    INTO is closed first and has to be the next available slot.  */
315 static void
316 xdup2 (int from, int into)
317 {
318   if (from != into)
319     {
320       int status = close (into);
321
322       if (status != 0 && errno != EBADF)
323         {
324           int e = errno;
325           FATAL_ERROR ((0, e, _("Cannot close")));
326         }
327       status = dup (from);
328       if (status != into)
329         {
330           if (status < 0)
331             {
332               int e = errno;
333               FATAL_ERROR ((0, e, _("Cannot dup")));
334             }
335           abort ();
336         }
337       xclose (from);
338     }
339 }
340
341 /* Set ARCHIVE for writing, then compressing an archive.  */
342 pid_t
343 sys_child_open_for_compress (void)
344 {
345   int parent_pipe[2];
346   int child_pipe[2];
347   pid_t grandchild_pid;
348   pid_t child_pid;
349   int wait_status;
350
351   xpipe (parent_pipe);
352   child_pid = xfork ();
353
354   if (child_pid > 0)
355     {
356       /* The parent tar is still here!  Just clean up.  */
357
358       archive = parent_pipe[PWRITE];
359       xclose (parent_pipe[PREAD]);
360       return child_pid;
361     }
362
363   /* The new born child tar is here!  */
364
365   program_name = _("tar (child)");
366
367   xdup2 (parent_pipe[PREAD], STDIN_FILENO);
368   xclose (parent_pipe[PWRITE]);
369
370   /* Check if we need a grandchild tar.  This happens only if either:
371      a) we are writing stdout: to force reblocking;
372      b) the file is to be accessed by rmt: compressor doesn't know how;
373      c) the file is not a plain file.  */
374
375   if (strcmp (archive_name_array[0], "-") != 0
376       && !_remdev (archive_name_array[0])
377       && is_regular_file (archive_name_array[0]))
378     {
379       if (backup_option)
380         maybe_backup_file (archive_name_array[0], 1);
381
382       /* We don't need a grandchild tar.  Open the archive and launch the
383          compressor.  */
384
385       archive = creat (archive_name_array[0], MODE_RW);
386       if (archive < 0)
387         {
388           int saved_errno = errno;
389
390           if (backup_option)
391             undo_last_backup ();
392           errno = saved_errno;
393           open_fatal (archive_name_array[0]);
394         }
395       xdup2 (archive, STDOUT_FILENO);
396       execlp (use_compress_program_option, use_compress_program_option,
397               (char *) 0);
398       exec_fatal (use_compress_program_option);
399     }
400
401   /* We do need a grandchild tar.  */
402
403   xpipe (child_pipe);
404   grandchild_pid = xfork ();
405
406   if (grandchild_pid == 0)
407     {
408       /* The newborn grandchild tar is here!  Launch the compressor.  */
409
410       program_name = _("tar (grandchild)");
411
412       xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
413       xclose (child_pipe[PREAD]);
414       execlp (use_compress_program_option, use_compress_program_option,
415               (char *) 0);
416       exec_fatal (use_compress_program_option);
417     }
418
419   /* The child tar is still here!  */
420
421   /* Prepare for reblocking the data from the compressor into the archive.  */
422
423   xdup2 (child_pipe[PREAD], STDIN_FILENO);
424   xclose (child_pipe[PWRITE]);
425
426   if (strcmp (archive_name_array[0], "-") == 0)
427     archive = STDOUT_FILENO;
428   else
429     {
430       archive = rmtcreat (archive_name_array[0], MODE_RW, rsh_command_option);
431       if (archive < 0)
432         open_fatal (archive_name_array[0]);
433     }
434
435   /* Let's read out of the stdin pipe and write an archive.  */
436
437   while (1)
438     {
439       size_t status = 0;
440       char *cursor;
441       size_t length;
442
443       /* Assemble a record.  */
444
445       for (length = 0, cursor = record_start->buffer;
446            length < record_size;
447            length += status, cursor += status)
448         {
449           size_t size = record_size - length;
450
451           status = safe_read (STDIN_FILENO, cursor, size);
452           if (status == SAFE_READ_ERROR)
453             read_fatal (use_compress_program_option);
454           if (status == 0)
455             break;
456         }
457
458       /* Copy the record.  */
459
460       if (status == 0)
461         {
462           /* We hit the end of the file.  Write last record at
463              full length, as the only role of the grandchild is
464              doing proper reblocking.  */
465
466           if (length > 0)
467             {
468               memset (record_start->buffer + length, 0, record_size - length);
469               status = sys_write_archive_buffer ();
470               if (status != record_size)
471                 archive_write_error (status);
472             }
473
474           /* There is nothing else to read, break out.  */
475           break;
476         }
477
478       status = sys_write_archive_buffer ();
479       if (status != record_size)
480         archive_write_error (status);
481     }
482
483   /* Propagate any failure of the grandchild back to the parent.  */
484
485   while (waitpid (grandchild_pid, &wait_status, 0) == -1)
486     if (errno != EINTR)
487       {
488         waitpid_error (use_compress_program_option);
489         break;
490       }
491
492   if (WIFSIGNALED (wait_status))
493     {
494       kill (child_pid, WTERMSIG (wait_status));
495       exit_status = TAREXIT_FAILURE;
496     }
497   else if (WEXITSTATUS (wait_status) != 0)
498     exit_status = WEXITSTATUS (wait_status);
499
500   exit (exit_status);
501 }
502
503 /* Set ARCHIVE for uncompressing, then reading an archive.  */
504 pid_t
505 sys_child_open_for_uncompress (void)
506 {
507   int parent_pipe[2];
508   int child_pipe[2];
509   pid_t grandchild_pid;
510   pid_t child_pid;
511   int wait_status;
512
513   xpipe (parent_pipe);
514   child_pid = xfork ();
515
516   if (child_pid > 0)
517     {
518       /* The parent tar is still here!  Just clean up.  */
519
520       read_full_records_option = true;
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   program_name = _("tar (child)");
529
530   xdup2 (parent_pipe[PWRITE], STDOUT_FILENO);
531   xclose (parent_pipe[PREAD]);
532
533   /* Check if we need a grandchild tar.  This happens only if either:
534      a) we're reading stdin: to force unblocking;
535      b) the file is to be accessed by rmt: compressor doesn't know how;
536      c) the file is not a plain file.  */
537
538   if (strcmp (archive_name_array[0], "-") != 0
539       && !_remdev (archive_name_array[0])
540       && is_regular_file (archive_name_array[0]))
541     {
542       /* We don't need a grandchild tar.  Open the archive and lauch the
543          uncompressor.  */
544
545       archive = open (archive_name_array[0], O_RDONLY | O_BINARY, MODE_RW);
546       if (archive < 0)
547         open_fatal (archive_name_array[0]);
548       xdup2 (archive, STDIN_FILENO);
549       execlp (use_compress_program_option, use_compress_program_option,
550               "-d", (char *) 0);
551       exec_fatal (use_compress_program_option);
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       program_name = _("tar (grandchild)");
564
565       xdup2 (child_pipe[PREAD], STDIN_FILENO);
566       xclose (child_pipe[PWRITE]);
567       execlp (use_compress_program_option, use_compress_program_option,
568               "-d", (char *) 0);
569       exec_fatal (use_compress_program_option);
570     }
571
572   /* The child tar is still here!  */
573
574   /* Prepare for unblocking the data from the archive into the
575      uncompressor.  */
576
577   xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
578   xclose (child_pipe[PREAD]);
579
580   if (strcmp (archive_name_array[0], "-") == 0)
581     archive = STDIN_FILENO;
582   else
583     archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
584                        MODE_RW, rsh_command_option);
585   if (archive < 0)
586     open_fatal (archive_name_array[0]);
587
588   /* Let's read the archive and pipe it into stdout.  */
589
590   while (1)
591     {
592       char *cursor;
593       size_t maximum;
594       size_t count;
595       size_t status;
596
597       clear_read_error_count ();
598
599     error_loop:
600       status = rmtread (archive, record_start->buffer, record_size);
601       if (status == SAFE_READ_ERROR)
602         {
603           archive_read_error ();
604           goto error_loop;
605         }
606       if (status == 0)
607         break;
608       cursor = record_start->buffer;
609       maximum = status;
610       while (maximum)
611         {
612           count = maximum < BLOCKSIZE ? maximum : BLOCKSIZE;
613           if (full_write (STDOUT_FILENO, cursor, count) != count)
614             write_error (use_compress_program_option);
615           cursor += count;
616           maximum -= count;
617         }
618     }
619
620   xclose (STDOUT_FILENO);
621
622   /* Propagate any failure of the grandchild back to the parent.  */
623
624   while (waitpid (grandchild_pid, &wait_status, 0) == -1)
625     if (errno != EINTR)
626       {
627         waitpid_error (use_compress_program_option);
628         break;
629       }
630
631   if (WIFSIGNALED (wait_status))
632     {
633       kill (child_pid, WTERMSIG (wait_status));
634       exit_status = TAREXIT_FAILURE;
635     }
636   else if (WEXITSTATUS (wait_status) != 0)
637     exit_status = WEXITSTATUS (wait_status);
638
639   exit (exit_status);
640 }
641
642 #endif /* not MSDOS */
643