1 /* System-dependent calls for tar.
3 Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
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
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.
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. */
29 sys_get_archive_stat (void)
35 sys_file_is_archive (struct tar_stat_info
*p
)
41 sys_save_archive_dev_ino (void)
46 sys_detect_dev_null_output (void)
48 static char const dev_null
[] = "nul";
50 dev_null_output
= (strcmp (archive_name_array
[0], dev_null
) == 0
51 || (! _isrmt (archive
)));
55 sys_drain_input_pipe (void)
60 sys_wait_for_child (pid_t child_pid
)
65 sys_spawn_shell (void)
67 spawnl (P_WAIT
, getenv ("COMSPEC"), "-", 0);
70 /* stat() in djgpp's C library gives a constant number of 42 as the
71 uid and gid of a file. So, comparing an FTP'ed archive just after
72 unpack would fail on MSDOS. */
75 sys_compare_uid (struct stat
*a
, struct stat
*b
)
81 sys_compare_gid (struct stat
*a
, struct stat
*b
)
87 sys_compare_links (struct stat
*link_data
, struct stat
*stat_data
)
95 return write (fd
, "", 0);
99 sys_write_archive_buffer (void)
101 return full_write (archive
, record_start
->buffer
, record_size
);
104 /* Set ARCHIVE for writing, then compressing an archive. */
106 sys_child_open_for_compress (void)
108 FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
111 /* Set ARCHIVE for uncompressing, then reading an archive. */
113 sys_child_open_for_uncompress (void)
115 FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
120 extern union block
*record_start
; /* FIXME */
122 static struct stat archive_stat
; /* stat block for archive file */
125 sys_get_archive_stat (void)
127 return fstat (archive
, &archive_stat
) == 0;
131 sys_file_is_archive (struct tar_stat_info
*p
)
133 return (ar_dev
&& p
->stat
.st_dev
== ar_dev
&& p
->stat
.st_ino
== ar_ino
);
136 /* Save archive file inode and device numbers */
138 sys_save_archive_dev_ino (void)
140 if (!_isrmt (archive
) && S_ISREG (archive_stat
.st_mode
))
142 ar_dev
= archive_stat
.st_dev
;
143 ar_ino
= archive_stat
.st_ino
;
149 /* Detect if outputting to "/dev/null". */
151 sys_detect_dev_null_output (void)
153 static char const dev_null
[] = "/dev/null";
154 struct stat dev_null_stat
;
156 dev_null_output
= (strcmp (archive_name_array
[0], dev_null
) == 0
157 || (! _isrmt (archive
)
158 && S_ISCHR (archive_stat
.st_mode
)
159 && stat (dev_null
, &dev_null_stat
) == 0
160 && archive_stat
.st_dev
== dev_null_stat
.st_dev
161 && archive_stat
.st_ino
== dev_null_stat
.st_ino
));
164 /* Manage to fully drain a pipe we might be reading, so to not break it on
165 the producer after the EOF block. FIXME: one of these days, GNU tar
166 might become clever enough to just stop working, once there is no more
167 work to do, we might have to revise this area in such time. */
170 sys_drain_input_pipe (void)
174 if (access_mode
== ACCESS_READ
175 && ! _isrmt (archive
)
176 && (S_ISFIFO (archive_stat
.st_mode
) || S_ISSOCK (archive_stat
.st_mode
)))
177 while ((r
= rmtread (archive
, record_start
->buffer
, record_size
)) != 0
178 && r
!= SAFE_READ_ERROR
)
183 sys_wait_for_child (pid_t child_pid
)
189 while (waitpid (child_pid
, &wait_status
, 0) == -1)
192 waitpid_error (use_compress_program_option
);
196 if (WIFSIGNALED (wait_status
))
197 ERROR ((0, 0, _("Child died with signal %d"),
198 WTERMSIG (wait_status
)));
199 else if (WEXITSTATUS (wait_status
) != 0)
200 ERROR ((0, 0, _("Child returned status %d"),
201 WEXITSTATUS (wait_status
)));
206 sys_spawn_shell (void)
209 const char *shell
= getenv ("SHELL");
215 execlp (shell
, "-sh", "-i", (char *) 0);
221 while (waitpid (child
, &wait_status
, 0) == -1)
224 waitpid_error (shell
);
231 sys_compare_uid (struct stat
*a
, struct stat
*b
)
233 return a
->st_uid
== b
->st_uid
;
237 sys_compare_gid (struct stat
*a
, struct stat
*b
)
239 return a
->st_gid
== b
->st_gid
;
243 sys_compare_links (struct stat
*link_data
, struct stat
*stat_data
)
245 return stat_data
->st_dev
== link_data
->st_dev
246 && stat_data
->st_ino
== link_data
->st_ino
;
250 sys_truncate (int fd
)
252 off_t pos
= lseek (fd
, (off_t
) 0, SEEK_CUR
);
253 return pos
< 0 ? -1 : ftruncate (fd
, pos
);
256 /* Return nonzero if NAME is the name of a regular file, or if the file
257 does not exist (so it would be created as a regular file). */
259 is_regular_file (const char *name
)
263 if (stat (name
, &stbuf
) == 0)
264 return S_ISREG (stbuf
.st_mode
);
266 return errno
== ENOENT
;
270 sys_write_archive_buffer (void)
272 return rmtwrite (archive
, record_start
->buffer
, record_size
);
275 #define PREAD 0 /* read file descriptor from pipe() */
276 #define PWRITE 1 /* write file descriptor from pipe() */
278 /* Duplicate file descriptor FROM into becoming INTO.
279 INTO is closed first and has to be the next available slot. */
281 xdup2 (int from
, int into
)
285 int status
= close (into
);
287 if (status
!= 0 && errno
!= EBADF
)
290 FATAL_ERROR ((0, e
, _("Cannot close")));
298 FATAL_ERROR ((0, e
, _("Cannot dup")));
306 /* Set ARCHIVE for writing, then compressing an archive. */
308 sys_child_open_for_compress (void)
312 pid_t grandchild_pid
;
317 child_pid
= xfork ();
321 /* The parent tar is still here! Just clean up. */
323 archive
= parent_pipe
[PWRITE
];
324 xclose (parent_pipe
[PREAD
]);
328 /* The new born child tar is here! */
330 program_name
= _("tar (child)");
332 xdup2 (parent_pipe
[PREAD
], STDIN_FILENO
);
333 xclose (parent_pipe
[PWRITE
]);
335 /* Check if we need a grandchild tar. This happens only if either:
336 a) the file is to be accessed by rmt: compressor doesn't know how;
337 b) the file is not a plain file. */
339 if (!_remdev (archive_name_array
[0])
340 && is_regular_file (archive_name_array
[0]))
343 maybe_backup_file (archive_name_array
[0], 1);
345 /* We don't need a grandchild tar. Open the archive and launch the
347 if (strcmp (archive_name_array
[0], "-"))
349 archive
= creat (archive_name_array
[0], MODE_RW
);
352 int saved_errno
= errno
;
357 open_fatal (archive_name_array
[0]);
359 xdup2 (archive
, STDOUT_FILENO
);
361 execlp (use_compress_program_option
, use_compress_program_option
, NULL
);
362 exec_fatal (use_compress_program_option
);
365 /* We do need a grandchild tar. */
368 grandchild_pid
= xfork ();
370 if (grandchild_pid
== 0)
372 /* The newborn grandchild tar is here! Launch the compressor. */
374 program_name
= _("tar (grandchild)");
376 xdup2 (child_pipe
[PWRITE
], STDOUT_FILENO
);
377 xclose (child_pipe
[PREAD
]);
378 execlp (use_compress_program_option
, use_compress_program_option
,
380 exec_fatal (use_compress_program_option
);
383 /* The child tar is still here! */
385 /* Prepare for reblocking the data from the compressor into the archive. */
387 xdup2 (child_pipe
[PREAD
], STDIN_FILENO
);
388 xclose (child_pipe
[PWRITE
]);
390 if (strcmp (archive_name_array
[0], "-") == 0)
391 archive
= STDOUT_FILENO
;
394 archive
= rmtcreat (archive_name_array
[0], MODE_RW
, rsh_command_option
);
396 open_fatal (archive_name_array
[0]);
399 /* Let's read out of the stdin pipe and write an archive. */
407 /* Assemble a record. */
409 for (length
= 0, cursor
= record_start
->buffer
;
410 length
< record_size
;
411 length
+= status
, cursor
+= status
)
413 size_t size
= record_size
- length
;
415 status
= safe_read (STDIN_FILENO
, cursor
, size
);
416 if (status
== SAFE_READ_ERROR
)
417 read_fatal (use_compress_program_option
);
422 /* Copy the record. */
426 /* We hit the end of the file. Write last record at
427 full length, as the only role of the grandchild is
428 doing proper reblocking. */
432 memset (record_start
->buffer
+ length
, 0, record_size
- length
);
433 status
= sys_write_archive_buffer ();
434 if (status
!= record_size
)
435 archive_write_error (status
);
438 /* There is nothing else to read, break out. */
442 status
= sys_write_archive_buffer ();
443 if (status
!= record_size
)
444 archive_write_error (status
);
447 /* Propagate any failure of the grandchild back to the parent. */
449 while (waitpid (grandchild_pid
, &wait_status
, 0) == -1)
452 waitpid_error (use_compress_program_option
);
456 if (WIFSIGNALED (wait_status
))
458 kill (child_pid
, WTERMSIG (wait_status
));
459 exit_status
= TAREXIT_FAILURE
;
461 else if (WEXITSTATUS (wait_status
) != 0)
462 exit_status
= WEXITSTATUS (wait_status
);
467 /* Set ARCHIVE for uncompressing, then reading an archive. */
469 sys_child_open_for_uncompress (void)
473 pid_t grandchild_pid
;
478 child_pid
= xfork ();
482 /* The parent tar is still here! Just clean up. */
484 archive
= parent_pipe
[PREAD
];
485 xclose (parent_pipe
[PWRITE
]);
489 /* The newborn child tar is here! */
491 program_name
= _("tar (child)");
493 xdup2 (parent_pipe
[PWRITE
], STDOUT_FILENO
);
494 xclose (parent_pipe
[PREAD
]);
496 /* Check if we need a grandchild tar. This happens only if either:
497 a) we're reading stdin: to force unblocking;
498 b) the file is to be accessed by rmt: compressor doesn't know how;
499 c) the file is not a plain file. */
501 if (strcmp (archive_name_array
[0], "-") != 0
502 && !_remdev (archive_name_array
[0])
503 && is_regular_file (archive_name_array
[0]))
505 /* We don't need a grandchild tar. Open the archive and lauch the
508 archive
= open (archive_name_array
[0], O_RDONLY
| O_BINARY
, MODE_RW
);
510 open_fatal (archive_name_array
[0]);
511 xdup2 (archive
, STDIN_FILENO
);
512 execlp (use_compress_program_option
, use_compress_program_option
,
514 exec_fatal (use_compress_program_option
);
517 /* We do need a grandchild tar. */
520 grandchild_pid
= xfork ();
522 if (grandchild_pid
== 0)
524 /* The newborn grandchild tar is here! Launch the uncompressor. */
526 program_name
= _("tar (grandchild)");
528 xdup2 (child_pipe
[PREAD
], STDIN_FILENO
);
529 xclose (child_pipe
[PWRITE
]);
530 execlp (use_compress_program_option
, use_compress_program_option
,
532 exec_fatal (use_compress_program_option
);
535 /* The child tar is still here! */
537 /* Prepare for unblocking the data from the archive into the
540 xdup2 (child_pipe
[PWRITE
], STDOUT_FILENO
);
541 xclose (child_pipe
[PREAD
]);
543 if (strcmp (archive_name_array
[0], "-") == 0)
544 archive
= STDIN_FILENO
;
546 archive
= rmtopen (archive_name_array
[0], O_RDONLY
| O_BINARY
,
547 MODE_RW
, rsh_command_option
);
549 open_fatal (archive_name_array
[0]);
551 /* Let's read the archive and pipe it into stdout. */
560 clear_read_error_count ();
563 status
= rmtread (archive
, record_start
->buffer
, record_size
);
564 if (status
== SAFE_READ_ERROR
)
566 archive_read_error ();
571 cursor
= record_start
->buffer
;
575 count
= maximum
< BLOCKSIZE
? maximum
: BLOCKSIZE
;
576 if (full_write (STDOUT_FILENO
, cursor
, count
) != count
)
577 write_error (use_compress_program_option
);
583 xclose (STDOUT_FILENO
);
585 /* Propagate any failure of the grandchild back to the parent. */
587 while (waitpid (grandchild_pid
, &wait_status
, 0) == -1)
590 waitpid_error (use_compress_program_option
);
594 if (WIFSIGNALED (wait_status
))
596 kill (child_pid
, WTERMSIG (wait_status
));
597 exit_status
= TAREXIT_FAILURE
;
599 else if (WEXITSTATUS (wait_status
) != 0)
600 exit_status
= WEXITSTATUS (wait_status
);
608 dec_to_env (char *envar
, uintmax_t num
)
610 char buf
[UINTMAX_STRSIZE_BOUND
];
613 numstr
= STRINGIFY_BIGINT (num
, buf
);
614 if (setenv (envar
, numstr
, 1) != 0)
619 time_to_env (char *envar
, struct timespec t
)
621 char buf
[TIMESPEC_STRSIZE_BOUND
];
622 if (setenv (envar
, code_timespec (t
, buf
), 1) != 0)
627 oct_to_env (char *envar
, unsigned long num
)
629 char buf
[1+1+(sizeof(unsigned long)*CHAR_BIT
+2)/3];
631 snprintf (buf
, sizeof buf
, "0%lo", num
);
632 if (setenv (envar
, buf
, 1) != 0)
637 str_to_env (char *envar
, char const *str
)
641 if (setenv (envar
, str
, 1) != 0)
649 chr_to_env (char *envar
, char c
)
654 if (setenv (envar
, buf
, 1) != 0)
659 stat_to_env (char *name
, char type
, struct tar_stat_info
*st
)
661 str_to_env ("TAR_VERSION", PACKAGE_VERSION
);
662 chr_to_env ("TAR_FILETYPE", type
);
663 oct_to_env ("TAR_MODE", st
->stat
.st_mode
);
664 str_to_env ("TAR_FILENAME", name
);
665 str_to_env ("TAR_REALNAME", st
->file_name
);
666 str_to_env ("TAR_UNAME", st
->uname
);
667 str_to_env ("TAR_GNAME", st
->gname
);
668 time_to_env ("TAR_ATIME", st
->atime
);
669 time_to_env ("TAR_MTIME", st
->mtime
);
670 time_to_env ("TAR_CTIME", st
->ctime
);
671 dec_to_env ("TAR_SIZE", st
->stat
.st_size
);
672 dec_to_env ("TAR_UID", st
->stat
.st_uid
);
673 dec_to_env ("TAR_GID", st
->stat
.st_gid
);
679 dec_to_env ("TAR_MINOR", minor (st
->stat
.st_rdev
));
680 dec_to_env ("TAR_MAJOR", major (st
->stat
.st_rdev
));
681 unsetenv ("TAR_LINKNAME");
686 unsetenv ("TAR_MINOR");
687 unsetenv ("TAR_MAJOR");
688 str_to_env ("TAR_LINKNAME", st
->link_name
);
692 unsetenv ("TAR_MINOR");
693 unsetenv ("TAR_MAJOR");
694 unsetenv ("TAR_LINKNAME");
699 static pid_t global_pid
;
700 static RETSIGTYPE (*pipe_handler
) (int sig
);
703 sys_exec_command (char *file_name
, int typechar
, struct tar_stat_info
*st
)
709 pipe_handler
= signal (SIGPIPE
, SIG_IGN
);
710 global_pid
= xfork ();
719 xdup2 (p
[PREAD
], STDIN_FILENO
);
722 stat_to_env (file_name
, typechar
, st
);
726 argv
[2] = to_command_option
;
729 execv ("/bin/sh", argv
);
731 exec_fatal (file_name
);
735 sys_wait_command (void)
742 signal (SIGPIPE
, pipe_handler
);
743 while (waitpid (global_pid
, &status
, 0) == -1)
747 waitpid_error (to_command_option
);
751 if (WIFEXITED (status
))
753 if (!ignore_command_error_option
&& WEXITSTATUS (status
))
754 ERROR ((0, 0, _("%lu: Child returned status %d"),
755 (unsigned long) global_pid
, WEXITSTATUS (status
)));
757 else if (WIFSIGNALED (status
))
759 WARN ((0, 0, _("%lu: Child terminated on signal %d"),
760 (unsigned long) global_pid
, WTERMSIG (status
)));
763 ERROR ((0, 0, _("%lu: Child terminated on unknown reason"),
764 (unsigned long) global_pid
));
770 sys_exec_info_script (const char **archive_name
, int volume_number
)
774 char uintbuf
[UINTMAX_STRSIZE_BOUND
];
778 pipe_handler
= signal (SIGPIPE
, SIG_IGN
);
793 fp
= fdopen (p
[PREAD
], "r");
794 rc
= getline (&buf
, &size
, fp
);
797 if (rc
> 0 && buf
[rc
-1] == '\n')
800 while (waitpid (pid
, &status
, 0) == -1)
803 waitpid_error (info_script_option
);
807 if (WIFEXITED (status
))
809 if (WEXITSTATUS (status
) == 0 && rc
> 0)
813 return WEXITSTATUS (status
);
821 setenv ("TAR_VERSION", PACKAGE_VERSION
, 1);
822 setenv ("TAR_ARCHIVE", *archive_name
, 1);
823 setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number
, uintbuf
), 1);
824 setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option
), 1);
825 setenv ("TAR_FORMAT",
826 archive_format_string (current_format
== DEFAULT_FORMAT
?
827 archive_format
: current_format
), 1);
828 setenv ("TAR_FD", STRINGIFY_BIGINT (p
[PWRITE
], uintbuf
), 1);
834 argv
[2] = (char*) info_script_option
;
837 execv (argv
[0], argv
);
839 exec_fatal (info_script_option
);
843 #endif /* not MSDOS */