source: MondoRescue/branches/3.3/mindi-busybox/archival/libarchive/data_extract_to_command.c@ 3803

Last change on this file since 3803 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 3.4 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
4 */
5
6#include "libbb.h"
7#include "bb_archive.h"
8
9enum {
10 //TAR_FILETYPE,
11 TAR_MODE,
12 TAR_FILENAME,
13 TAR_REALNAME,
14#if ENABLE_FEATURE_TAR_UNAME_GNAME
15 TAR_UNAME,
16 TAR_GNAME,
17#endif
18 TAR_SIZE,
19 TAR_UID,
20 TAR_GID,
21 TAR_MAX,
22};
23
24static const char *const tar_var[] = {
25 // "FILETYPE",
26 "MODE",
27 "FILENAME",
28 "REALNAME",
29#if ENABLE_FEATURE_TAR_UNAME_GNAME
30 "UNAME",
31 "GNAME",
32#endif
33 "SIZE",
34 "UID",
35 "GID",
36};
37
38static void xputenv(char *str)
39{
40 if (putenv(str))
41 bb_error_msg_and_die(bb_msg_memory_exhausted);
42}
43
44static void str2env(char *env[], int idx, const char *str)
45{
46 env[idx] = xasprintf("TAR_%s=%s", tar_var[idx], str);
47 xputenv(env[idx]);
48}
49
50static void dec2env(char *env[], int idx, unsigned long long val)
51{
52 env[idx] = xasprintf("TAR_%s=%llu", tar_var[idx], val);
53 xputenv(env[idx]);
54}
55
56static void oct2env(char *env[], int idx, unsigned long val)
57{
58 env[idx] = xasprintf("TAR_%s=%lo", tar_var[idx], val);
59 xputenv(env[idx]);
60}
61
62void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle)
63{
64 file_header_t *file_header = archive_handle->file_header;
65
66#if 0 /* do we need this? ENABLE_FEATURE_TAR_SELINUX */
67 char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE];
68 if (!sctx)
69 sctx = archive_handle->tar__sctx[PAX_GLOBAL];
70 if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */
71 setfscreatecon(sctx);
72 free(archive_handle->tar__sctx[PAX_NEXT_FILE]);
73 archive_handle->tar__sctx[PAX_NEXT_FILE] = NULL;
74 }
75#endif
76
77 if ((file_header->mode & S_IFMT) == S_IFREG) {
78 pid_t pid;
79 int p[2], status;
80 char *tar_env[TAR_MAX];
81
82 memset(tar_env, 0, sizeof(tar_env));
83
84 xpipe(p);
85 pid = BB_MMU ? xfork() : xvfork();
86 if (pid == 0) {
87 /* Child */
88 /* str2env(tar_env, TAR_FILETYPE, "f"); - parent should do it once */
89 oct2env(tar_env, TAR_MODE, file_header->mode);
90 str2env(tar_env, TAR_FILENAME, file_header->name);
91 str2env(tar_env, TAR_REALNAME, file_header->name);
92#if ENABLE_FEATURE_TAR_UNAME_GNAME
93 str2env(tar_env, TAR_UNAME, file_header->tar__uname);
94 str2env(tar_env, TAR_GNAME, file_header->tar__gname);
95#endif
96 dec2env(tar_env, TAR_SIZE, file_header->size);
97 dec2env(tar_env, TAR_UID, file_header->uid);
98 dec2env(tar_env, TAR_GID, file_header->gid);
99 close(p[1]);
100 xdup2(p[0], STDIN_FILENO);
101 signal(SIGPIPE, SIG_DFL);
102 execl(archive_handle->tar__to_command_shell,
103 archive_handle->tar__to_command_shell,
104 "-c",
105 archive_handle->tar__to_command,
106 (char *)0);
107 bb_perror_msg_and_die("can't execute '%s'", archive_handle->tar__to_command_shell);
108 }
109 close(p[0]);
110 /* Our caller is expected to do signal(SIGPIPE, SIG_IGN)
111 * so that we don't die if child don't read all the input: */
112 bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size);
113 close(p[1]);
114
115 status = wait_for_exitstatus(pid);
116 if (WIFEXITED(status) && WEXITSTATUS(status))
117 bb_error_msg_and_die("'%s' returned status %d",
118 archive_handle->tar__to_command, WEXITSTATUS(status));
119 if (WIFSIGNALED(status))
120 bb_error_msg_and_die("'%s' terminated by signal %d",
121 archive_handle->tar__to_command, WTERMSIG(status));
122
123 if (!BB_MMU) {
124 int i;
125 for (i = 0; i < TAR_MAX; i++) {
126 if (tar_env[i])
127 bb_unsetenv_and_free(tar_env[i]);
128 }
129 }
130 }
131
132#if 0 /* ENABLE_FEATURE_TAR_SELINUX */
133 if (sctx)
134 /* reset the context after creating an entry */
135 setfscreatecon(NULL);
136#endif
137}
Note: See TracBrowser for help on using the repository browser.