1
2
3
4
5#include "libbb.h"
6#include "bb_archive.h"
7
8enum {
9
10 TAR_MODE,
11 TAR_FILENAME,
12 TAR_REALNAME,
13#if ENABLE_FEATURE_TAR_UNAME_GNAME
14 TAR_UNAME,
15 TAR_GNAME,
16#endif
17 TAR_SIZE,
18 TAR_UID,
19 TAR_GID,
20 TAR_MAX,
21};
22
23static const char *const tar_var[] ALIGN_PTR = {
24
25 "MODE",
26 "FILENAME",
27 "REALNAME",
28#if ENABLE_FEATURE_TAR_UNAME_GNAME
29 "UNAME",
30 "GNAME",
31#endif
32 "SIZE",
33 "UID",
34 "GID",
35};
36
37static void xputenv(char *str)
38{
39 if (putenv(str))
40 bb_die_memory_exhausted();
41}
42
43static void str2env(char *env[], int idx, const char *str)
44{
45 env[idx] = xasprintf("TAR_%s=%s", tar_var[idx], str);
46 xputenv(env[idx]);
47}
48
49static void dec2env(char *env[], int idx, unsigned long long val)
50{
51 env[idx] = xasprintf("TAR_%s=%llu", tar_var[idx], val);
52 xputenv(env[idx]);
53}
54
55static void oct2env(char *env[], int idx, unsigned long val)
56{
57 env[idx] = xasprintf("TAR_%s=%lo", tar_var[idx], val);
58 xputenv(env[idx]);
59}
60
61void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle)
62{
63 file_header_t *file_header = archive_handle->file_header;
64
65#if 0
66 char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE];
67 if (!sctx)
68 sctx = archive_handle->tar__sctx[PAX_GLOBAL];
69 if (sctx) {
70 setfscreatecon(sctx);
71 free(archive_handle->tar__sctx[PAX_NEXT_FILE]);
72 archive_handle->tar__sctx[PAX_NEXT_FILE] = NULL;
73 }
74#endif
75
76 if ((file_header->mode & S_IFMT) == S_IFREG) {
77 pid_t pid;
78 int p[2], status;
79 char *tar_env[TAR_MAX];
80
81 memset(tar_env, 0, sizeof(tar_env));
82
83 xpipe(p);
84 pid = BB_MMU ? xfork() : xvfork();
85 if (pid == 0) {
86
87
88 oct2env(tar_env, TAR_MODE, file_header->mode);
89 str2env(tar_env, TAR_FILENAME, file_header->name);
90 str2env(tar_env, TAR_REALNAME, file_header->name);
91#if ENABLE_FEATURE_TAR_UNAME_GNAME
92 str2env(tar_env, TAR_UNAME, file_header->tar__uname);
93 str2env(tar_env, TAR_GNAME, file_header->tar__gname);
94#endif
95 dec2env(tar_env, TAR_SIZE, file_header->size);
96 dec2env(tar_env, TAR_UID, file_header->uid);
97 dec2env(tar_env, TAR_GID, file_header->gid);
98 close(p[1]);
99 xdup2(p[0], STDIN_FILENO);
100 signal(SIGPIPE, SIG_DFL);
101 execl(archive_handle->tar__to_command_shell,
102 archive_handle->tar__to_command_shell,
103 "-c",
104 archive_handle->tar__to_command,
105 (char *)0);
106 bb_perror_msg_and_die("can't execute '%s'", archive_handle->tar__to_command_shell);
107 }
108 close(p[0]);
109
110
111 bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size);
112 close(p[1]);
113
114 status = wait_for_exitstatus(pid);
115 if (WIFEXITED(status) && WEXITSTATUS(status))
116 bb_error_msg_and_die("'%s' returned status %d",
117 archive_handle->tar__to_command, WEXITSTATUS(status));
118 if (WIFSIGNALED(status))
119 bb_error_msg_and_die("'%s' terminated by signal %d",
120 archive_handle->tar__to_command, WTERMSIG(status));
121
122 if (!BB_MMU) {
123 int i;
124 for (i = 0; i < TAR_MAX; i++) {
125 if (tar_env[i])
126 bb_unsetenv_and_free(tar_env[i]);
127 }
128 }
129 }
130
131#if 0
132 if (sctx)
133
134 setfscreatecon(NULL);
135#endif
136}
137