]> Dogcows Code - chaz/tar/blobdiff - src/system.c
Update FSF postal mail address.
[chaz/tar] / src / system.c
index 1e99aabe0056d6f890930cb7a0ef199cc4172bad..dee82b2285cb242d7208e4bf46f4cb9722892abd 100644 (file)
 
    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
-#include "system.h"
+#include <system.h>
 
 #include "common.h"
-#include "rmt.h"
+#include <rmt.h>
 #include <signal.h>
 
 void
@@ -118,11 +118,6 @@ sys_truncate (int fd)
   return write (fd, "", 0);
 }
 
-void
-sys_reset_uid_gid (void)
-{
-}
-
 size_t
 sys_write_archive_buffer (void)
 {
@@ -281,13 +276,6 @@ sys_truncate (int fd)
   return pos < 0 ? -1 : ftruncate (fd, pos);
 }
 
-void
-sys_reset_uid_gid (void)
-{
-  setuid (getuid ());
-  setgid (getgid ());
-}
-
 /* Return nonzero if NAME is the name of a regular file, or if the file
    does not exist (so it would be created as a regular file).  */
 static int
@@ -517,7 +505,6 @@ sys_child_open_for_uncompress (void)
     {
       /* The parent tar is still here!  Just clean up.  */
 
-      read_full_records_option = true;
       archive = parent_pipe[PREAD];
       xclose (parent_pipe[PWRITE]);
       return child_pid;
@@ -639,5 +626,154 @@ sys_child_open_for_uncompress (void)
   exit (exit_status);
 }
 
+\f
+
+static void
+dec_to_env (char *envar, uintmax_t num)
+{
+  char buf[UINTMAX_STRSIZE_BOUND];
+  char *numstr;
+
+  numstr = STRINGIFY_BIGINT (num, buf);
+  setenv (envar, numstr, 1);
+}
+
+static void
+oct_to_env (char *envar, unsigned long num)
+{
+  char buf[1+1+(sizeof(unsigned long)*CHAR_BIT+2)/3];
+  
+  snprintf (buf, sizeof buf, "0%lo", num);
+  setenv (envar, buf, 1);
+}
+
+static void
+str_to_env (char *envar, char const *str)
+{
+  if (str)
+    setenv (envar, str, 1);
+  else
+    unsetenv (envar);
+}
+
+static void
+chr_to_env (char *envar, char c)
+{
+  char buf[2];
+  buf[0] = c;
+  buf[1] = 0;
+  setenv (envar, buf, 1);
+}
+
+static void
+stat_to_env (char *name, char type, struct tar_stat_info *st)
+{
+  chr_to_env ("TAR_FILETYPE", type);
+  oct_to_env ("TAR_MODE", st->stat.st_mode);
+  str_to_env ("TAR_FILENAME", name);
+  str_to_env ("TAR_REALNAME", st->file_name);
+  str_to_env ("TAR_UNAME", st->uname);
+  str_to_env ("TAR_GNAME", st->gname);
+  dec_to_env ("TAR_MTIME", st->stat.st_mtime);
+  dec_to_env ("TAR_ATIME", st->stat.st_atime);
+  dec_to_env ("TAR_CTIME", st->stat.st_ctime);
+  dec_to_env ("TAR_SIZE", st->stat.st_size);
+  dec_to_env ("TAR_UID", st->stat.st_uid);
+  dec_to_env ("TAR_GID", st->stat.st_gid);     
+
+  switch (type)
+    {
+    case 'b':
+    case 'c':
+      dec_to_env ("TAR_MINOR", minor (st->stat.st_rdev));
+      dec_to_env ("TAR_MAJOR", major (st->stat.st_rdev));
+      unsetenv ("TAR_LINKNAME");
+      break;
+
+    case 'l':
+    case 'h':
+      unsetenv ("TAR_MINOR");
+      unsetenv ("TAR_MAJOR");
+      str_to_env ("TAR_LINKNAME", st->link_name);
+      break;
+
+    default:
+      unsetenv ("TAR_MINOR");
+      unsetenv ("TAR_MAJOR");
+      unsetenv ("TAR_LINKNAME");
+      break;
+    }
+}
+
+static pid_t pid;
+static RETSIGTYPE (*pipe_handler) (int sig);
+
+int
+sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st)
+{
+  int p[2];
+  char *argv[4];
+  
+  xpipe (p);
+  pipe_handler = signal (SIGPIPE, SIG_IGN);
+  pid = xfork ();
+
+  if (pid != 0)
+    {
+      xclose (p[PREAD]);
+      return p[PWRITE];
+    }
+
+  /* Child */
+  xdup2 (p[PREAD], STDIN_FILENO);
+  xclose (p[PWRITE]);
+  
+  stat_to_env (file_name, typechar, st);
+
+  argv[0] = "/bin/sh";
+  argv[1] = "-c";
+  argv[2] = to_command_option;
+  argv[3] = NULL;
+
+  execv ("/bin/sh", argv);
+
+  exec_fatal (file_name);
+}
+
+void
+sys_wait_command (void)
+{
+  int status;
+  
+  if (pid < 0)
+    return;
+
+  signal (SIGPIPE, pipe_handler);
+  while (waitpid (pid, &status, 0) == -1)
+    if (errno != EINTR)
+      {
+        pid = -1;
+        waitpid_error (to_command_option);
+        return;
+      }
+
+  if (WIFEXITED (status))
+    {
+      if (!ignore_command_error_option && WEXITSTATUS (status))
+       ERROR ((0, 0, _("%lu: Child returned status %d"),
+               (unsigned long) pid, WEXITSTATUS (status)));
+    }
+  else if (WIFSIGNALED (status))
+    {
+      WARN ((0, 0, _("%lu: Child terminated on signal %d"),
+            (unsigned long) pid, WTERMSIG (status)));
+    }
+  else
+    ERROR ((0, 0, _("%lu: Child terminated on unknown reason"),
+           (unsigned long) pid));
+
+  pid = -1;
+}
+
 #endif /* not MSDOS */
 
This page took 0.023212 seconds and 4 git commands to generate.