Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/archival/libarchive/open_transformer.c
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/archival/libarchive/open_transformer.c
r2725 r3232 5 5 6 6 #include "libbb.h" 7 #include "archive.h" 7 #include "bb_archive.h" 8 9 void FAST_FUNC init_transformer_aux_data(transformer_aux_data_t *aux) 10 { 11 memset(aux, 0, sizeof(*aux)); 12 } 13 14 int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigned magic16) 15 { 16 if (aux && aux->check_signature) { 17 uint16_t magic2; 18 if (full_read(src_fd, &magic2, 2) != 2 || magic2 != magic16) { 19 bb_error_msg("invalid magic"); 20 #if 0 /* possible future extension */ 21 if (aux->check_signature > 1) 22 xfunc_die(); 23 #endif 24 return -1; 25 } 26 } 27 return 0; 28 } 29 30 void check_errors_in_children(int signo) 31 { 32 int status; 33 34 if (!signo) { 35 /* block waiting for any child */ 36 if (wait(&status) < 0) 37 return; /* probably there are no children */ 38 goto check_status; 39 } 40 41 /* Wait for any child without blocking */ 42 for (;;) { 43 if (wait_any_nohang(&status) < 0) 44 /* wait failed?! I'm confused... */ 45 return; 46 check_status: 47 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) 48 /* this child exited with 0 */ 49 continue; 50 /* Cannot happen? 51 if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???; */ 52 bb_got_signal = 1; 53 } 54 } 8 55 9 56 /* transformer(), more than meets the eye */ 10 /* 11 * On MMU machine, the transform_prog is removed by macro magic 12 * in include/archive.h. On NOMMU, transformer is removed. 13 */ 57 #if BB_MMU 14 58 void FAST_FUNC open_transformer(int fd, 15 IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd), 16 const char *transform_prog) 59 int check_signature, 60 IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd) 61 ) 62 #else 63 void FAST_FUNC open_transformer(int fd, const char *transform_prog) 64 #endif 17 65 { 18 66 struct fd_pair fd_pipe; … … 26 74 // FIXME: error check? 27 75 #if BB_MMU 28 transformer(fd, fd_pipe.wr); 29 if (ENABLE_FEATURE_CLEAN_UP) { 30 close(fd_pipe.wr); /* send EOF */ 31 close(fd); 32 } 33 /* must be _exit! bug was actually seen here */ 34 _exit(EXIT_SUCCESS); 76 { 77 transformer_aux_data_t aux; 78 init_transformer_aux_data(&aux); 79 aux.check_signature = check_signature; 80 transformer(&aux, fd, fd_pipe.wr); 81 if (ENABLE_FEATURE_CLEAN_UP) { 82 close(fd_pipe.wr); /* send EOF */ 83 close(fd); 84 } 85 /* must be _exit! bug was actually seen here */ 86 _exit(EXIT_SUCCESS); 87 } 35 88 #else 36 89 { … … 53 106 xmove_fd(fd_pipe.rd, fd); 54 107 } 108 109 110 #if SEAMLESS_COMPRESSION 111 112 /* Used by e.g. rpm which gives us a fd without filename, 113 * thus we can't guess the format from filename's extension. 114 */ 115 int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_detected) 116 { 117 union { 118 uint8_t b[4]; 119 uint16_t b16[2]; 120 uint32_t b32[1]; 121 } magic; 122 int offset = -2; 123 USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);) 124 USE_FOR_NOMMU(const char *xformer_prog;) 125 126 /* .gz and .bz2 both have 2-byte signature, and their 127 * unpack_XXX_stream wants this header skipped. */ 128 xread(fd, magic.b16, sizeof(magic.b16[0])); 129 if (ENABLE_FEATURE_SEAMLESS_GZ 130 && magic.b16[0] == GZIP_MAGIC 131 ) { 132 USE_FOR_MMU(xformer = unpack_gz_stream;) 133 USE_FOR_NOMMU(xformer_prog = "gunzip";) 134 goto found_magic; 135 } 136 if (ENABLE_FEATURE_SEAMLESS_BZ2 137 && magic.b16[0] == BZIP2_MAGIC 138 ) { 139 USE_FOR_MMU(xformer = unpack_bz2_stream;) 140 USE_FOR_NOMMU(xformer_prog = "bunzip2";) 141 goto found_magic; 142 } 143 if (ENABLE_FEATURE_SEAMLESS_XZ 144 && magic.b16[0] == XZ_MAGIC1 145 ) { 146 offset = -6; 147 xread(fd, magic.b32, sizeof(magic.b32[0])); 148 if (magic.b32[0] == XZ_MAGIC2) { 149 USE_FOR_MMU(xformer = unpack_xz_stream;) 150 USE_FOR_NOMMU(xformer_prog = "unxz";) 151 goto found_magic; 152 } 153 } 154 155 /* No known magic seen */ 156 if (fail_if_not_detected) 157 bb_error_msg_and_die("no gzip" 158 IF_FEATURE_SEAMLESS_BZ2("/bzip2") 159 IF_FEATURE_SEAMLESS_XZ("/xz") 160 " magic"); 161 xlseek(fd, offset, SEEK_CUR); 162 return 1; 163 164 found_magic: 165 # if BB_MMU 166 open_transformer_with_no_sig(fd, xformer); 167 # else 168 /* NOMMU version of open_transformer execs 169 * an external unzipper that wants 170 * file position at the start of the file */ 171 xlseek(fd, offset, SEEK_CUR); 172 open_transformer_with_sig(fd, xformer, xformer_prog); 173 # endif 174 return 0; 175 } 176 177 int FAST_FUNC open_zipped(const char *fname) 178 { 179 char *sfx; 180 int fd; 181 182 fd = open(fname, O_RDONLY); 183 if (fd < 0) 184 return fd; 185 186 sfx = strrchr(fname, '.'); 187 if (sfx) { 188 sfx++; 189 if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0) 190 /* .lzma has no header/signature, just trust it */ 191 open_transformer_with_sig(fd, unpack_lzma_stream, "unlzma"); 192 else 193 if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0) 194 || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0) 195 || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0) 196 ) { 197 setup_unzip_on_fd(fd, /*fail_if_not_detected:*/ 1); 198 } 199 } 200 201 return fd; 202 } 203 204 #endif /* SEAMLESS_COMPRESSION */ 205 206 void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) 207 { 208 int fd; 209 char *image; 210 211 fd = open_zipped(fname); 212 if (fd < 0) 213 return NULL; 214 215 image = xmalloc_read(fd, maxsz_p); 216 if (!image) 217 bb_perror_msg("read error from '%s'", fname); 218 close(fd); 219 220 return image; 221 }
Note:
See TracChangeset
for help on using the changeset viewer.