diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-11-03 02:38:31 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-11-03 02:38:31 +0100 |
commit | 833d4e7f84f59099ee66eabfa3457ebb7d37eaa8 (patch) | |
tree | 3be84e1049707ce8077291065fe3689497c69b9c /archival/libarchive/data_extract_to_command.c | |
parent | 5e9934028aa030312a1a2e2e32d5ceade8672beb (diff) | |
download | busybox-w32-833d4e7f84f59099ee66eabfa3457ebb7d37eaa8.tar.gz busybox-w32-833d4e7f84f59099ee66eabfa3457ebb7d37eaa8.tar.bz2 busybox-w32-833d4e7f84f59099ee66eabfa3457ebb7d37eaa8.zip |
rename archival/libunarchive -> archival/libarchive; move bz/ into it
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'archival/libarchive/data_extract_to_command.c')
-rw-r--r-- | archival/libarchive/data_extract_to_command.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c new file mode 100644 index 000000000..2bbab7641 --- /dev/null +++ b/archival/libarchive/data_extract_to_command.c | |||
@@ -0,0 +1,134 @@ | |||
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 "archive.h" | ||
8 | |||
9 | enum { | ||
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 | |||
24 | static 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 | |||
38 | static void xputenv(char *str) | ||
39 | { | ||
40 | if (putenv(str)) | ||
41 | bb_error_msg_and_die(bb_msg_memory_exhausted); | ||
42 | } | ||
43 | |||
44 | static 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 | |||
50 | static 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 | |||
56 | static 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 | |||
62 | void 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__next_file_sctx; | ||
68 | if (!sctx) | ||
69 | sctx = archive_handle->tar__global_sctx; | ||
70 | if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */ | ||
71 | setfscreatecon(sctx); | ||
72 | free(archive_handle->tar__next_file_sctx); | ||
73 | archive_handle->tar__next_file_sctx = 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(DEFAULT_SHELL, DEFAULT_SHELL_SHORT_NAME, "-c", archive_handle->tar__to_command, NULL); | ||
103 | bb_perror_msg_and_die("can't execute '%s'", DEFAULT_SHELL); | ||
104 | } | ||
105 | close(p[0]); | ||
106 | /* Our caller is expected to do signal(SIGPIPE, SIG_IGN) | ||
107 | * so that we don't die if child don't read all the input: */ | ||
108 | bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size); | ||
109 | close(p[1]); | ||
110 | |||
111 | if (safe_waitpid(pid, &status, 0) == -1) | ||
112 | bb_perror_msg_and_die("waitpid"); | ||
113 | if (WIFEXITED(status) && WEXITSTATUS(status)) | ||
114 | bb_error_msg_and_die("'%s' returned status %d", | ||
115 | archive_handle->tar__to_command, WEXITSTATUS(status)); | ||
116 | if (WIFSIGNALED(status)) | ||
117 | bb_error_msg_and_die("'%s' terminated on signal %d", | ||
118 | archive_handle->tar__to_command, WTERMSIG(status)); | ||
119 | |||
120 | if (!BB_MMU) { | ||
121 | int i; | ||
122 | for (i = 0; i < TAR_MAX; i++) { | ||
123 | if (tar_env[i]) | ||
124 | bb_unsetenv_and_free(tar_env[i]); | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | |||
129 | #if 0 /* ENABLE_FEATURE_TAR_SELINUX */ | ||
130 | if (sctx) | ||
131 | /* reset the context after creating an entry */ | ||
132 | setfscreatecon(NULL); | ||
133 | #endif | ||
134 | } | ||