Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/archival
- Timestamp:
- Nov 4, 2007, 3:16:40 AM (16 years ago)
- Location:
- branches/2.2.5/mindi-busybox/archival
- Files:
-
- 4 added
- 10 deleted
- 39 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.5/mindi-busybox/archival/Config.in
r821 r1765 6 6 menu "Archival Utilities" 7 7 8 config CONFIG_AR8 config AR 9 9 bool "ar" 10 10 default n … … 29 29 probably say N here. 30 30 31 config CONFIG_FEATURE_AR_LONG_FILENAMES31 config FEATURE_AR_LONG_FILENAMES 32 32 bool "Enable support for long filenames (not need for debs)" 33 33 default n 34 depends on CONFIG_AR34 depends on AR 35 35 help 36 36 By default the ar format can only store the first 15 characters of the … … 39 39 filenames into a the data section of a new ar entry. 40 40 41 config CONFIG_BUNZIP241 config BUNZIP2 42 42 bool "bunzip2" 43 43 default n … … 55 55 should probably say N here. 56 56 57 config C ONFIG_CPIO57 config CPIO 58 58 bool "cpio" 59 59 default n … … 69 69 probably say N here. 70 70 71 config CONFIG_DPKG71 config DPKG 72 72 bool "dpkg" 73 73 default n … … 78 78 official dpkg if possible. 79 79 80 config CONFIG_DPKG_DEB80 config DPKG_DEB 81 81 bool "dpkg_deb" 82 82 default n … … 89 89 probably say N here. 90 90 91 config CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY91 config FEATURE_DPKG_DEB_EXTRACT_ONLY 92 92 bool "extract only (-x)" 93 93 default n 94 depends on CONFIG_DPKG_DEB94 depends on DPKG_DEB 95 95 help 96 96 This reduces dpkg-deb to the equivalent of "ar -p <deb> data.tar.gz | tar -zx". … … 98 98 needed, they are linked to internally. 99 99 100 config CONFIG_GUNZIP100 config GUNZIP 101 101 bool "gunzip" 102 102 default n … … 106 106 an archive, without decompressing it. 107 107 108 config CONFIG_FEATURE_GUNZIP_UNCOMPRESS108 config FEATURE_GUNZIP_UNCOMPRESS 109 109 bool "Uncompress support" 110 110 default n 111 depends on CONFIG_GUNZIP111 depends on GUNZIP 112 112 help 113 113 Enable if you want gunzip to have the ability to decompress … … 115 115 used anymore). 116 116 117 config CONFIG_GZIP117 config GZIP 118 118 bool "gzip" 119 119 default n … … 122 122 It's probably the most widely used UNIX compression program. 123 123 124 config CONFIG_RPM2CPIO124 config RPM2CPIO 125 125 bool "rpm2cpio" 126 126 default n … … 128 128 Converts an RPM file into a CPIO archive. 129 129 130 config CONFIG_RPM130 config RPM 131 131 bool "rpm" 132 132 default n 133 133 help 134 Mini RPM applet - queries and extracts 135 136 config CONFIG_TAR 134 Mini RPM applet - queries and extracts RPM packages. 135 136 config FEATURE_RPM_BZ2 137 bool "Enable handling of rpms with bzip2-compressed data inside" 138 default n 139 depends on RPM 140 help 141 Enable handling of rpms with bzip2-compressed data inside. 142 143 config TAR 137 144 bool "tar" 138 145 default n … … 142 149 UNIX archive program. 143 150 144 config CONFIG_FEATURE_TAR_CREATE151 config FEATURE_TAR_CREATE 145 152 bool "Enable archive creation" 146 153 default y 147 depends on CONFIG_TAR154 depends on TAR 148 155 help 149 156 If you enable this option you'll be able to create 150 157 tar archives using the `-c' option. 151 158 152 config CONFIG_FEATURE_TAR_BZIP2159 config FEATURE_TAR_BZIP2 153 160 bool "Enable -j option to handle .tar.bz2 files" 154 161 default n 155 depends on CONFIG_TAR162 depends on TAR 156 163 help 157 164 If you enable this option you'll be able to extract 158 165 archives compressed with bzip2. 159 166 160 config CONFIG_FEATURE_TAR_LZMA167 config FEATURE_TAR_LZMA 161 168 bool "Enable -a option to handle .tar.lzma files" 162 169 default n 163 depends on CONFIG_TAR170 depends on TAR 164 171 help 165 172 If you enable this option you'll be able to extract 166 173 archives compressed with lzma. 167 174 168 config CONFIG_FEATURE_TAR_FROM175 config FEATURE_TAR_FROM 169 176 bool "Enable -X (exclude from) and -T (include from) options)" 170 177 default n 171 depends on CONFIG_TAR178 depends on TAR 172 179 help 173 180 If you enable this option you'll be able to specify 174 181 a list of files to include or exclude from an archive. 175 182 176 config CONFIG_FEATURE_TAR_GZIP183 config FEATURE_TAR_GZIP 177 184 bool "Enable -z option" 178 185 default y 179 depends on CONFIG_TAR186 depends on TAR 180 187 help 181 188 If you enable this option tar will be able to call gzip, 182 189 when creating or extracting tar gziped archives. 183 190 184 config CONFIG_FEATURE_TAR_COMPRESS191 config FEATURE_TAR_COMPRESS 185 192 bool "Enable -Z option" 186 193 default n 187 depends on CONFIG_TAR194 depends on TAR 188 195 help 189 196 If you enable this option tar will be able to call uncompress, 190 197 when extracting .tar.Z archives. 191 198 192 config CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY199 config FEATURE_TAR_OLDGNU_COMPATIBILITY 193 200 bool "Enable support for old tar header format" 194 201 default N 195 depends on CONFIG_TAR202 depends on TAR 196 203 help 197 204 This option is required to unpack archives created in … … 199 206 repacking your ancient archives with the new format. 200 207 201 config CONFIG_FEATURE_TAR_GNU_EXTENSIONS 208 config FEATURE_TAR_OLDSUN_COMPATIBILITY 209 bool "Enable untarring of tarballs with checksums produced by buggy Sun tar" 210 default N 211 depends on TAR 212 help 213 This option is required to unpack archives created by some old 214 version of Sun's tar (it was calculating checksum using signed arithmetic). 215 It is said to be fixed in newer Sun tar, but "old" tarballs still exist. 216 217 config FEATURE_TAR_GNU_EXTENSIONS 202 218 bool "Enable support for some GNU tar extensions" 203 219 default y 204 depends on CONFIG_TAR220 depends on TAR 205 221 help 206 222 With this option busybox supports GNU long filenames and 207 223 linknames. 208 224 209 config CONFIG_FEATURE_TAR_LONG_OPTIONS225 config FEATURE_TAR_LONG_OPTIONS 210 226 bool "Enable long options" 211 227 default n 212 depends on CONFIG_TAR && CONFIG_GETOPT_LONG228 depends on TAR && GETOPT_LONG 213 229 help 214 230 Enable use of long options, increases size by about 400 Bytes 215 231 216 config CONFIG_UNCOMPRESS232 config UNCOMPRESS 217 233 bool "uncompress" 218 234 default n … … 221 237 Not much used anymore, replaced by gzip/gunzip. 222 238 223 config CONFIG_UNLZMA239 config UNLZMA 224 240 bool "unlzma" 225 241 default n … … 236 252 should probably say N here. 237 253 238 config CONFIG_FEATURE_LZMA_FAST254 config FEATURE_LZMA_FAST 239 255 bool "Optimze unlzma for speed" 240 256 default n 241 depends on CONFIG_UNLZMA257 depends on UNLZMA 242 258 help 243 259 This option reduces decompression time by about 33% at the cost of 244 260 a 2K bigger binary. 245 261 246 config CONFIG_UNZIP262 config UNZIP 247 263 bool "unzip" 248 264 default n … … 255 271 256 272 comment "Common options for cpio and tar" 257 depends on C ONFIG_CPIO || CONFIG_TAR258 259 config CONFIG_FEATURE_UNARCHIVE_TAPE273 depends on CPIO || TAR 274 275 config FEATURE_UNARCHIVE_TAPE 260 276 bool "Enable tape drive support" 261 277 default n 262 depends on C ONFIG_CPIO || CONFIG_TAR278 depends on CPIO || TAR 263 279 help 264 280 I don't think this is needed anymore. 265 281 266 282 comment "Common options for dpkg and dpkg_deb" 267 depends on CONFIG_DPKG || CONFIG_DPKG_DEB268 269 config CONFIG_FEATURE_DEB_TAR_GZ283 depends on DPKG || DPKG_DEB 284 285 config FEATURE_DEB_TAR_GZ 270 286 bool "gzip debian packages (normal)" 271 default y if CONFIG_DPKG || CONFIG_DPKG_DEB272 depends on CONFIG_DPKG || CONFIG_DPKG_DEB287 default y if DPKG || DPKG_DEB 288 depends on DPKG || DPKG_DEB 273 289 help 274 290 This is the default compression method inside the debian ar file. … … 276 292 If you want compatibility with standard .deb's you should say yes here. 277 293 278 config CONFIG_FEATURE_DEB_TAR_BZ2294 config FEATURE_DEB_TAR_BZ2 279 295 bool "bzip2 debian packages" 280 296 default n 281 depends on CONFIG_DPKG || CONFIG_DPKG_DEB297 depends on DPKG || DPKG_DEB 282 298 help 283 299 This allows dpkg and dpkg-deb to extract deb's that are compressed internally … … 287 303 use an internal control.tar.bz2 or data.tar.bz2. 288 304 289 config CONFIG_FEATURE_DEB_TAR_LZMA305 config FEATURE_DEB_TAR_LZMA 290 306 bool "lzma debian packages" 291 307 default n 292 depends on CONFIG_DPKG || CONFIG_DPKG_DEB308 depends on DPKG || DPKG_DEB 293 309 help 294 310 This allows dpkg and dpkg-deb to extract deb's that are compressed 295 311 internally with lzma instead of gzip. 296 312 297 313 You only want this if you are creating your own custom debian 298 314 packages that use an internal control.tar.lzma or data.tar.lzma. 299 315 300 316 endmenu -
branches/2.2.5/mindi-busybox/archival/ar.c
r821 r1765 8 8 * Based in part on BusyBox tar, Debian dpkg-deb and GNU ar. 9 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 23 11 * 24 12 * There is no single standard to adhere to so ar may not portable … … 27 15 */ 28 16 29 #include <fcntl.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <time.h> 34 #include <utime.h> 35 #include <unistd.h> 36 17 #include "libbb.h" 37 18 #include "unarchive.h" 38 #include "busybox.h"39 19 40 20 static void header_verbose_list_ar(const file_header_t *file_header) … … 47 27 memmove(&mtime[17], &mtime[20], 4); 48 28 mtime[21] = '\0'; 49 printf("%s %d/%d%7d %s %s\n", &mode[1], file_header->uid, file_header->gid, (int) file_header->size, &mtime[4], file_header->name); 29 printf("%s %d/%d%7d %s %s\n", &mode[1], file_header->uid, file_header->gid, 30 (int) file_header->size, &mtime[4], file_header->name); 50 31 } 51 32 … … 58 39 #define AR_OPT_INSERT 0x40 59 40 41 int ar_main(int argc, char **argv); 60 42 int ar_main(int argc, char **argv) 61 43 { 44 static const char msg_unsupported_err[] ALIGN1 = 45 "archive %s is not supported"; 46 62 47 archive_handle_t *archive_handle; 63 unsigned long opt; 64 static const char msg_unsupported_err[] = 65 "Archive %s not supported. Install binutils 'ar'."; 48 unsigned opt; 66 49 char magic[8]; 67 50 … … 69 52 70 53 /* Prepend '-' to the first argument if required */ 71 bb_opt_complementally = "--:p:t:x:-1:?:p--tx:t--px:x--pt";72 opt = bb_getopt_ulflags(argc,argv, "ptxovcr");54 opt_complementary = "--:p:t:x:-1:p--tx:t--px:x--pt"; 55 opt = getopt32(argv, "ptxovcr"); 73 56 74 57 if (opt & AR_CTX_PRINT) { … … 94 77 } 95 78 96 archive_handle->src_fd = bb_xopen(argv[optind++], O_RDONLY);79 archive_handle->src_fd = xopen(argv[optind++], O_RDONLY); 97 80 98 81 while (optind < argc) { … … 101 84 } 102 85 103 archive_xread_all(archive_handle, magic, 7);86 xread(archive_handle->src_fd, magic, 7); 104 87 if (strncmp(magic, "!<arch>", 7) != 0) { 105 bb_error_msg_and_die(" Invalid ar magic");88 bb_error_msg_and_die("invalid ar magic"); 106 89 } 107 90 archive_handle->offset += 7; 108 91 109 while (get_header_ar(archive_handle) == EXIT_SUCCESS); 92 while (get_header_ar(archive_handle) == EXIT_SUCCESS) 93 continue; 110 94 111 95 return EXIT_SUCCESS; -
branches/2.2.5/mindi-busybox/archival/cpio.c
r821 r1765 5 5 * Copyright (C) 2001 by Glenn McGrath 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 20 8 * 21 9 * Limitations: … … 24 12 * 25 13 */ 26 #include <fcntl.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <unistd.h> 14 #include "libbb.h" 30 15 #include "unarchive.h" 31 #include "busybox.h"32 16 33 #define CPIO_OPT_EXTRACT 34 #define CPIO_OPT_TEST 35 #define CPIO_OPT_UNCONDITIONAL 36 #define CPIO_OPT_VERBOSE 37 #define CPIO_OPT_FILE 38 #define CPIO_OPT_CREATE_LEADING_DIR 39 #define CPIO_OPT_PRESERVE_MTIME 17 #define CPIO_OPT_EXTRACT 0x01 18 #define CPIO_OPT_TEST 0x02 19 #define CPIO_OPT_UNCONDITIONAL 0x04 20 #define CPIO_OPT_VERBOSE 0x08 21 #define CPIO_OPT_FILE 0x10 22 #define CPIO_OPT_CREATE_LEADING_DIR 0x20 23 #define CPIO_OPT_PRESERVE_MTIME 0x40 40 24 25 int cpio_main(int argc, char **argv); 41 26 int cpio_main(int argc, char **argv) 42 27 { 43 28 archive_handle_t *archive_handle; 44 29 char *cpio_filename = NULL; 45 unsigned longopt;30 unsigned opt; 46 31 47 32 /* Initialise */ 48 33 archive_handle = init_handle(); 49 34 archive_handle->src_fd = STDIN_FILENO; 50 archive_handle->seek = seek_by_ char;35 archive_handle->seek = seek_by_read; 51 36 archive_handle->flags = ARCHIVE_EXTRACT_NEWER | ARCHIVE_PRESERVE_DATE; 52 37 53 opt = bb_getopt_ulflags(argc,argv, "ituvF:dm", &cpio_filename);38 opt = getopt32(argv, "ituvF:dm", &cpio_filename); 54 39 55 40 /* One of either extract or test options must be given */ … … 80 65 } 81 66 if (cpio_filename) { /* CPIO_OPT_FILE */ 82 archive_handle->src_fd = bb_xopen(cpio_filename, O_RDONLY);67 archive_handle->src_fd = xopen(cpio_filename, O_RDONLY); 83 68 archive_handle->seek = seek_by_jump; 84 69 } … … 95 80 while (get_header_cpio(archive_handle) == EXIT_SUCCESS); 96 81 97 return (EXIT_SUCCESS);82 return EXIT_SUCCESS; 98 83 } -
branches/2.2.5/mindi-busybox/archival/dpkg.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * Mini dpkg implementation for busybox.3 * This is not meant as a replacement for dpkg3 * mini dpkg implementation for busybox. 4 * this is not meant as a replacement for dpkg 4 5 * 5 * Written By Glenn McGrath with the help of others6 * Copyright (C) 2001 by Glenn McGrath6 * written by glenn mcgrath with the help of others 7 * copyright (c) 2001 by glenn mcgrath 7 8 * 8 * Started life as a busybox implementation of udpkg9 * started life as a busybox implementation of udpkg 9 10 * 10 * Licensed under GPLv2 or later, see file LICENSEin this tarball for details.11 * licensed under gplv2 or later, see file license in this tarball for details. 11 12 */ 12 13 13 14 /* 14 * Known difference between busybox dpkg and the official dpkg that i don't15 * known difference between busybox dpkg and the official dpkg that i don't 15 16 * consider important, its worth keeping a note of differences anyway, just to 16 17 * make it easier to maintain. 17 * - The first value for the Confflile: field isnt placed on a new line.18 * - When installing a package the Status: field is placed at the end of the19 * section, rather than just after the Package: field.18 * - the first value for the confflile: field isnt placed on a new line. 19 * - when installing a package the status: field is placed at the end of the 20 * section, rather than just after the package: field. 20 21 * 21 * Bugs that need to be fixed22 * bugs that need to be fixed 22 23 * - (unknown, please let me know when you find any) 23 24 * 24 25 */ 25 26 26 #include <fcntl.h> 27 #include <getopt.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <unistd.h> 27 #include "libbb.h" 31 28 #include "unarchive.h" 32 #include "busybox.h" 33 34 /* NOTE: If you vary HASH_PRIME sizes be aware, 35 * 1) Tweaking these will have a big effect on how much memory this program uses. 36 * 2) For computational efficiency these hash tables should be at least 20% 29 30 /* note: if you vary hash_prime sizes be aware, 31 * 1) tweaking these will have a big effect on how much memory this program uses. 32 * 2) for computational efficiency these hash tables should be at least 20% 37 33 * larger than the maximum number of elements stored in it. 38 * 3) All _HASH_PRIME's must be a prime number or chaos is assured, if your looking34 * 3) all _hash_prime's must be a prime number or chaos is assured, if your looking 39 35 * for a prime, try http://www.utm.edu/research/primes/lists/small/10000.txt 40 * 4) If you go bigger than 15 bits you may get into trouble (untested) as its41 * sometimes cast to an unsigned int, if you go to 16 bit you will overlap36 * 4) if you go bigger than 15 bits you may get into trouble (untested) as its 37 * sometimes cast to an unsigned, if you go to 16 bit you will overlap 42 38 * int's and chaos is assured, 16381 is the max prime for 14 bit field 43 39 */ … … 47 43 * as there a lot of duplicate version numbers */ 48 44 #define NAME_HASH_PRIME 16381 49 static char *name_hashtable[NAME_HASH_PRIME + 1];50 45 51 46 /* PACKAGE_HASH_PRIME, Maximum number of unique packages, … … 59 54 #define PACKAGE_HASH_PRIME 10007 60 55 typedef struct edge_s { 61 unsigned int operator:3;62 unsigned inttype:4;63 unsigned int name:14;64 unsigned int version:14;56 unsigned operator:4; /* was:3 */ 57 unsigned type:4; 58 unsigned name:16; /* was:14 */ 59 unsigned version:16; /* was:14 */ 65 60 } edge_t; 66 61 67 62 typedef struct common_node_s { 68 unsigned int name:14;69 unsigned int version:14;70 unsigned int num_of_edges:14;63 unsigned name:16; /* was:14 */ 64 unsigned version:16; /* was:14 */ 65 unsigned num_of_edges:16; /* was:14 */ 71 66 edge_t **edge; 72 67 } common_node_t; 73 static common_node_t *package_hashtable[PACKAGE_HASH_PRIME + 1];74 68 75 69 /* Currently it doesnt store packages that have state-status of not-installed … … 78 72 #define STATUS_HASH_PRIME 8191 79 73 typedef struct status_node_s { 80 unsigned int package:14;/* has to fit PACKAGE_HASH_PRIME */81 unsigned int status:14;/* has to fit STATUS_HASH_PRIME */74 unsigned package:16; /* was:14 */ /* has to fit PACKAGE_HASH_PRIME */ 75 unsigned status:16; /* was:14 */ /* has to fit STATUS_HASH_PRIME */ 82 76 } status_node_t; 83 static status_node_t *status_hashtable[STATUS_HASH_PRIME + 1]; 77 78 /* Were statically declared here, but such a big bss is nommu-unfriendly */ 79 static char **name_hashtable; /* [NAME_HASH_PRIME + 1] */ 80 static common_node_t **package_hashtable; /* [PACKAGE_HASH_PRIME + 1] */ 81 static status_node_t **status_hashtable; /* [STATUS_HASH_PRIME + 1] */ 84 82 85 83 /* Even numbers are for 'extras', like ored dependencies or null */ … … 107 105 }; 108 106 109 enum dpkg_opt_e {110 dpkg_opt_purge = 1,111 dpkg_opt_remove = 2,112 dpkg_opt_unpack = 4,113 dpkg_opt_configure = 8,114 dpkg_opt_install = 16,115 dpkg_opt_package_name = 32,116 dpkg_opt_filename = 64,117 dpkg_opt_list_installed = 128,118 dpkg_opt_force_ignore_depends = 256119 };120 121 107 typedef struct deb_file_s { 122 108 char *control_file; 123 109 char *filename; 124 unsigned int package:14;110 unsigned package:16; /* was:14 */ 125 111 } deb_file_t; 126 112 127 113 128 static void make_hash(const char *key, unsigned int *start, unsigned int*decrement, const int hash_prime)129 { 130 unsigned long inthash_num = key[0];114 static void make_hash(const char *key, unsigned *start, unsigned *decrement, const int hash_prime) 115 { 116 unsigned long hash_num = key[0]; 131 117 int len = strlen(key); 132 118 int i; … … 134 120 /* Maybe i should have uses a "proper" hashing algorithm here instead 135 121 * of making one up myself, seems to be working ok though. */ 136 for (i = 1; i < len; i++) {122 for (i = 1; i < len; i++) { 137 123 /* shifts the ascii based value and adds it to previous value 138 124 * shift amount is mod 24 because long int is 32 bit and data … … 141 127 hash_num += ((key[i] + key[i-1]) << ((key[i] * i) % 24)); 142 128 } 143 *start = (unsigned int) hash_num % hash_prime;144 *decrement = (unsigned int) 1 + (hash_num % (hash_prime - 1));129 *start = (unsigned) hash_num % hash_prime; 130 *decrement = (unsigned) 1 + (hash_num % (hash_prime - 1)); 145 131 } 146 132 … … 148 134 static int search_name_hashtable(const char *key) 149 135 { 150 unsigned int probe_address = 0; 151 unsigned int probe_decrement = 0; 152 // char *temp; 136 unsigned probe_address = 0; 137 unsigned probe_decrement = 0; 153 138 154 139 make_hash(key, &probe_address, &probe_decrement, NAME_HASH_PRIME); 155 while (name_hashtable[probe_address] != NULL) {140 while (name_hashtable[probe_address] != NULL) { 156 141 if (strcmp(name_hashtable[probe_address], key) == 0) { 157 return(probe_address); 158 } else { 159 probe_address -= probe_decrement; 160 if ((int)probe_address < 0) { 161 probe_address += NAME_HASH_PRIME; 162 } 163 } 164 } 165 name_hashtable[probe_address] = bb_xstrdup(key); 166 return(probe_address); 142 return probe_address; 143 } 144 probe_address -= probe_decrement; 145 if ((int)probe_address < 0) { 146 probe_address += NAME_HASH_PRIME; 147 } 148 } 149 name_hashtable[probe_address] = xstrdup(key); 150 return probe_address; 167 151 } 168 152 … … 170 154 * TODO make it consistent with search_name_hashtable 171 155 */ 172 static unsigned intsearch_status_hashtable(const char *key)173 { 174 unsigned intprobe_address = 0;175 unsigned intprobe_decrement = 0;156 static unsigned search_status_hashtable(const char *key) 157 { 158 unsigned probe_address = 0; 159 unsigned probe_decrement = 0; 176 160 177 161 make_hash(key, &probe_address, &probe_decrement, STATUS_HASH_PRIME); 178 while (status_hashtable[probe_address] != NULL) {162 while (status_hashtable[probe_address] != NULL) { 179 163 if (strcmp(key, name_hashtable[package_hashtable[status_hashtable[probe_address]->package]->name]) == 0) { 180 164 break; 181 } else { 182 probe_address -= probe_decrement; 183 if ((int)probe_address < 0) { 184 probe_address += STATUS_HASH_PRIME; 185 } 186 } 187 } 188 return(probe_address); 165 } 166 probe_address -= probe_decrement; 167 if ((int)probe_address < 0) { 168 probe_address += STATUS_HASH_PRIME; 169 } 170 } 171 return probe_address; 189 172 } 190 173 … … 201 184 int ver_num1; 202 185 int ver_num2; 203 int ret;204 186 205 187 if (version1 == NULL) { 206 version1 = bb_xstrdup("");188 version1 = xstrdup(""); 207 189 } 208 190 if (version2 == NULL) { 209 version2 = bb_xstrdup("");191 version2 = xstrdup(""); 210 192 } 211 193 upstream_len1 = strlen(version1); … … 215 197 /* Compare non-digit section */ 216 198 tmp_int = strcspn(&version1[len1], "0123456789"); 217 name1_char = bb_xstrndup(&version1[len1], tmp_int);199 name1_char = xstrndup(&version1[len1], tmp_int); 218 200 len1 += tmp_int; 219 201 tmp_int = strcspn(&version2[len2], "0123456789"); 220 name2_char = bb_xstrndup(&version2[len2], tmp_int);202 name2_char = xstrndup(&version2[len2], tmp_int); 221 203 len2 += tmp_int; 222 204 tmp_int = strcmp(name1_char, name2_char); … … 224 206 free(name2_char); 225 207 if (tmp_int != 0) { 226 ret = tmp_int; 227 goto cleanup_version_compare_part; 208 return tmp_int; 228 209 } 229 210 230 211 /* Compare digits */ 231 212 tmp_int = strspn(&version1[len1], "0123456789"); 232 name1_char = bb_xstrndup(&version1[len1], tmp_int);213 name1_char = xstrndup(&version1[len1], tmp_int); 233 214 len1 += tmp_int; 234 215 tmp_int = strspn(&version2[len2], "0123456789"); 235 name2_char = bb_xstrndup(&version2[len2], tmp_int);216 name2_char = xstrndup(&version2[len2], tmp_int); 236 217 len2 += tmp_int; 237 218 ver_num1 = atoi(name1_char); … … 240 221 free(name2_char); 241 222 if (ver_num1 < ver_num2) { 242 ret = -1; 243 goto cleanup_version_compare_part; 244 } 245 else if (ver_num1 > ver_num2) { 246 ret = 1; 247 goto cleanup_version_compare_part; 248 } 249 } 250 ret = 0; 251 cleanup_version_compare_part: 252 return(ret); 223 return -1; 224 } 225 if (ver_num1 > ver_num2) { 226 return 1; 227 } 228 } 229 return 0; 253 230 } 254 231 … … 257 234 * if ver1 > ver2 return 1, 258 235 */ 259 static int version_compare(const unsigned int ver1, const unsigned intver2)236 static int version_compare(const unsigned ver1, const unsigned ver2) 260 237 { 261 238 char *ch_ver1 = name_hashtable[ver1]; … … 285 262 } 286 263 if (epoch1 < epoch2) { 287 return (-1);264 return -1; 288 265 } 289 266 else if (epoch1 > epoch2) { 290 return (1);267 return 1; 291 268 } 292 269 293 270 /* Compare upstream version */ 294 upstream_ver1 = bb_xstrdup(ver1_ptr);295 upstream_ver2 = bb_xstrdup(ver2_ptr);271 upstream_ver1 = xstrdup(ver1_ptr); 272 upstream_ver2 = xstrdup(ver2_ptr); 296 273 297 274 /* Chop off debian version, and store for later use */ … … 307 284 } 308 285 result = version_compare_part(upstream_ver1, upstream_ver2); 286 if (!result) 287 /* Compare debian versions */ 288 result = version_compare_part(deb_ver1, deb_ver2); 309 289 310 290 free(upstream_ver1); 311 291 free(upstream_ver2); 312 313 if (result != 0) { 314 return(result); 315 } 316 317 /* Compare debian versions */ 318 return(version_compare_part(deb_ver1, deb_ver2)); 319 } 320 321 static int test_version(const unsigned int version1, const unsigned int version2, const unsigned int operator) 292 return result; 293 } 294 295 static int test_version(const unsigned version1, const unsigned version2, const unsigned operator) 322 296 { 323 297 const int version_result = version_compare(version1, version2); 324 switch(operator) { 325 case (VER_ANY): 326 return(TRUE); 327 case (VER_EQUAL): 328 if (version_result == 0) { 329 return(TRUE); 330 } 331 break; 332 case (VER_LESS): 333 if (version_result < 0) { 334 return(TRUE); 335 } 336 break; 337 case (VER_LESS_EQUAL): 338 if (version_result <= 0) { 339 return(TRUE); 340 } 341 break; 342 case (VER_MORE): 343 if (version_result > 0) { 344 return(TRUE); 345 } 346 break; 347 case (VER_MORE_EQUAL): 348 if (version_result >= 0) { 349 return(TRUE); 350 } 351 break; 352 } 353 return(FALSE); 354 } 355 356 357 static int search_package_hashtable(const unsigned int name, const unsigned int version, const unsigned int operator) 358 { 359 unsigned int probe_address = 0; 360 unsigned int probe_decrement = 0; 298 switch (operator) { 299 case VER_ANY: 300 return TRUE; 301 case VER_EQUAL: 302 return (version_result == 0); 303 case VER_LESS: 304 return (version_result < 0); 305 case VER_LESS_EQUAL: 306 return (version_result <= 0); 307 case VER_MORE: 308 return (version_result > 0); 309 case VER_MORE_EQUAL: 310 return (version_result >= 0); 311 } 312 return FALSE; 313 } 314 315 316 static int search_package_hashtable(const unsigned name, const unsigned version, const unsigned operator) 317 { 318 unsigned probe_address = 0; 319 unsigned probe_decrement = 0; 361 320 362 321 make_hash(name_hashtable[name], &probe_address, &probe_decrement, PACKAGE_HASH_PRIME); 363 while (package_hashtable[probe_address] != NULL) {322 while (package_hashtable[probe_address] != NULL) { 364 323 if (package_hashtable[probe_address]->name == name) { 365 324 if (operator == VER_ANY) { 366 return (probe_address);325 return probe_address; 367 326 } 368 327 if (test_version(package_hashtable[probe_address]->version, version, operator)) { 369 return (probe_address);328 return probe_address; 370 329 } 371 330 } … … 375 334 } 376 335 } 377 return (probe_address);336 return probe_address; 378 337 } 379 338 … … 394 353 * it simple for now until it proves to be a problem. 395 354 */ 396 static int search_for_provides(int needle, int start_at) { 355 static int search_for_provides(int needle, int start_at) 356 { 397 357 int i, j; 398 358 common_node_t *p; 399 359 for (i = start_at + 1; i < PACKAGE_HASH_PRIME; i++) { 400 360 p = package_hashtable[i]; 401 if ( p == NULL ) continue; 402 for(j = 0; j < p->num_of_edges; j++) 403 if ( p->edge[j]->type == EDGE_PROVIDES && p->edge[j]->name == needle ) 361 if (p == NULL) 362 continue; 363 for (j = 0; j < p->num_of_edges; j++) 364 if (p->edge[j]->type == EDGE_PROVIDES && p->edge[j]->name == needle) 404 365 return i; 405 366 } … … 427 388 * this alternative. 428 389 */ 429 static void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned intedge_type)430 { 431 char *line = bb_xstrdup(whole_line);390 static void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned edge_type) 391 { 392 char *line = xstrdup(whole_line); 432 393 char *line2; 433 394 char *line_ptr1 = NULL; … … 444 405 /* skip leading spaces */ 445 406 field += strspn(field, " "); 446 line2 = bb_xstrdup(field);407 line2 = xstrdup(field); 447 408 field2 = strtok_r(line2, "|", &line_ptr2); 448 if ( (edge_type == EDGE_DEPENDS || edge_type == EDGE_PRE_DEPENDS) && 449 (strcmp(field, field2) != 0)) { 450 or_edge = (edge_t *)xmalloc(sizeof(edge_t)); 409 or_edge = NULL; 410 if ((edge_type == EDGE_DEPENDS || edge_type == EDGE_PRE_DEPENDS) 411 && (strcmp(field, field2) != 0) 412 ) { 413 or_edge = xmalloc(sizeof(edge_t)); 451 414 or_edge->type = edge_type + 1; 452 } else {453 or_edge = NULL;454 }455 456 if ( or_edge ) {457 415 or_edge->name = search_name_hashtable(field); 458 or_edge->version = 0; // tracks the number of altenatives 459 416 or_edge->version = 0; // tracks the number of alternatives 460 417 add_edge_to_node(parent_node, or_edge); 461 418 } 462 419 463 420 do { 464 edge = (edge_t *)xmalloc(sizeof(edge_t));421 edge = xmalloc(sizeof(edge_t)); 465 422 edge->type = edge_type; 466 423 … … 476 433 } else { 477 434 /* Skip leading ' ' or '(' */ 478 version += strspn(field2, " "); 479 version += strspn(version, "("); 435 version += strspn(version, " ("); 480 436 /* Calculate length of any operator characters */ 481 437 offset_ch = strspn(version, "<=>"); … … 497 453 edge->operator = VER_MORE_EQUAL; 498 454 } else { 499 bb_error_msg_and_die(" Illegal operator\n");455 bb_error_msg_and_die("illegal operator"); 500 456 } 501 457 } … … 514 470 edge->name = search_name_hashtable(field2); 515 471 516 if ( or_edge)472 if (or_edge) 517 473 or_edge->version++; 518 474 519 475 add_edge_to_node(parent_node, edge); 520 } while ((field2 = strtok_r(NULL, "|", &line_ptr2)) != NULL); 476 field2 = strtok_r(NULL, "|", &line_ptr2); 477 } while (field2 != NULL); 478 521 479 free(line2); 522 } while ((field = strtok_r(NULL, ",", &line_ptr1)) != NULL); 480 field = strtok_r(NULL, ",", &line_ptr1); 481 } while (field != NULL); 482 523 483 free(line); 524 525 return;526 484 } 527 485 528 486 static void free_package(common_node_t *node) 529 487 { 530 unsigned shorti;488 unsigned i; 531 489 if (node) { 532 490 for (i = 0; i < node->num_of_edges; i++) { … … 538 496 } 539 497 540 static unsigned int fill_package_struct(char *control_buffer) 541 { 542 static const char *const field_names[] = { "Package", "Version", 543 "Pre-Depends", "Depends","Replaces", "Provides", 544 "Conflicts", "Suggests", "Recommends", "Enhances", 0 545 }; 546 547 common_node_t *new_node = (common_node_t *) xzalloc(sizeof(common_node_t)); 498 /* 499 * Gets the next package field from package_buffer, seperated into the field name 500 * and field value, it returns the int offset to the first character of the next field 501 */ 502 static int read_package_field(const char *package_buffer, char **field_name, char **field_value) 503 { 504 int offset_name_start = 0; 505 int offset_name_end = 0; 506 int offset_value_start = 0; 507 int offset_value_end = 0; 508 int offset = 0; 509 int next_offset; 510 int name_length; 511 int value_length; 512 int exit_flag = FALSE; 513 514 if (package_buffer == NULL) { 515 *field_name = NULL; 516 *field_value = NULL; 517 return -1; 518 } 519 while (1) { 520 next_offset = offset + 1; 521 switch (package_buffer[offset]) { 522 case '\0': 523 exit_flag = TRUE; 524 break; 525 case ':': 526 if (offset_name_end == 0) { 527 offset_name_end = offset; 528 offset_value_start = next_offset; 529 } 530 /* TODO: Name might still have trailing spaces if ':' isnt 531 * immediately after name */ 532 break; 533 case '\n': 534 /* TODO: The char next_offset may be out of bounds */ 535 if (package_buffer[next_offset] != ' ') { 536 exit_flag = TRUE; 537 break; 538 } 539 case '\t': 540 case ' ': 541 /* increment the value start point if its a just filler */ 542 if (offset_name_start == offset) { 543 offset_name_start++; 544 } 545 if (offset_value_start == offset) { 546 offset_value_start++; 547 } 548 break; 549 } 550 if (exit_flag) { 551 /* Check that the names are valid */ 552 offset_value_end = offset; 553 name_length = offset_name_end - offset_name_start; 554 value_length = offset_value_end - offset_value_start; 555 if (name_length == 0) { 556 break; 557 } 558 if ((name_length > 0) && (value_length > 0)) { 559 break; 560 } 561 562 /* If not valid, start fresh with next field */ 563 exit_flag = FALSE; 564 offset_name_start = offset + 1; 565 offset_name_end = 0; 566 offset_value_start = offset + 1; 567 offset_value_end = offset + 1; 568 offset++; 569 } 570 offset++; 571 } 572 *field_name = NULL; 573 if (name_length) { 574 *field_name = xstrndup(&package_buffer[offset_name_start], name_length); 575 } 576 *field_value = NULL; 577 if (value_length > 0) { 578 *field_value = xstrndup(&package_buffer[offset_value_start], value_length); 579 } 580 return next_offset; 581 } 582 583 static unsigned fill_package_struct(char *control_buffer) 584 { 585 static const char field_names[] ALIGN1 = 586 "Package\0""Version\0" 587 "Pre-Depends\0""Depends\0""Replaces\0""Provides\0" 588 "Conflicts\0""Suggests\0""Recommends\0""Enhances\0"; 589 590 common_node_t *new_node = xzalloc(sizeof(common_node_t)); 548 591 char *field_name; 549 592 char *field_value; … … 554 597 new_node->version = search_name_hashtable("unknown"); 555 598 while (field_start < buffer_length) { 556 unsigned shortfield_num;599 unsigned field_num; 557 600 558 601 field_start += read_package_field(&control_buffer[field_start], … … 560 603 561 604 if (field_name == NULL) { 562 goto fill_package_struct_cleanup; /* Oh no, the dreaded goto statement 563 } 564 565 field_num = compare_string_array(field_names, field_name);566 switch (field_num) {567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 } 598 fill_package_struct_cleanup:605 goto fill_package_struct_cleanup; /* Oh no, the dreaded goto statement! */ 606 } 607 608 field_num = index_in_strings(field_names, field_name); 609 switch (field_num) { 610 case 0: /* Package */ 611 new_node->name = search_name_hashtable(field_value); 612 break; 613 case 1: /* Version */ 614 new_node->version = search_name_hashtable(field_value); 615 break; 616 case 2: /* Pre-Depends */ 617 add_split_dependencies(new_node, field_value, EDGE_PRE_DEPENDS); 618 break; 619 case 3: /* Depends */ 620 add_split_dependencies(new_node, field_value, EDGE_DEPENDS); 621 break; 622 case 4: /* Replaces */ 623 add_split_dependencies(new_node, field_value, EDGE_REPLACES); 624 break; 625 case 5: /* Provides */ 626 add_split_dependencies(new_node, field_value, EDGE_PROVIDES); 627 break; 628 case 6: /* Conflicts */ 629 add_split_dependencies(new_node, field_value, EDGE_CONFLICTS); 630 break; 631 case 7: /* Suggests */ 632 add_split_dependencies(new_node, field_value, EDGE_SUGGESTS); 633 break; 634 case 8: /* Recommends */ 635 add_split_dependencies(new_node, field_value, EDGE_RECOMMENDS); 636 break; 637 case 9: /* Enhances */ 638 add_split_dependencies(new_node, field_value, EDGE_ENHANCES); 639 break; 640 } 641 fill_package_struct_cleanup: 599 642 free(field_name); 600 643 free(field_value); … … 603 646 if (new_node->version == search_name_hashtable("unknown")) { 604 647 free_package(new_node); 605 return (-1);648 return -1; 606 649 } 607 650 num = search_package_hashtable(new_node->name, new_node->version, VER_EQUAL); 608 if (package_hashtable[num] == NULL) { 609 package_hashtable[num] = new_node; 610 } else { 611 free_package(new_node); 612 } 613 return(num); 651 free_package(package_hashtable[num]); 652 package_hashtable[num] = new_node; 653 return num; 614 654 } 615 655 616 656 /* if num = 1, it returns the want status, 2 returns flag, 3 returns status */ 617 static unsigned int get_status(const unsigned intstatus_node, const int num)657 static unsigned get_status(const unsigned status_node, const int num) 618 658 { 619 659 char *status_string = name_hashtable[status_hashtable[status_node]->status]; 620 660 char *state_sub_string; 621 unsigned intstate_sub_num;661 unsigned state_sub_num; 622 662 int len; 623 663 int i; … … 630 670 status_string += strspn(status_string, " "); 631 671 } 632 len = strcspn(status_string, " \n \0");633 state_sub_string = bb_xstrndup(status_string, len);672 len = strcspn(status_string, " \n"); 673 state_sub_string = xstrndup(status_string, len); 634 674 state_sub_num = search_name_hashtable(state_sub_string); 635 675 free(state_sub_string); 636 return (state_sub_num);637 } 638 639 static void set_status(const unsigned intstatus_node_num, const char *new_value, const int position)640 { 641 const unsigned intnew_value_len = strlen(new_value);642 const unsigned intnew_value_num = search_name_hashtable(new_value);643 unsigned intwant = get_status(status_node_num, 1);644 unsigned intflag = get_status(status_node_num, 2);645 unsigned intstatus = get_status(status_node_num, 3);676 return state_sub_num; 677 } 678 679 static void set_status(const unsigned status_node_num, const char *new_value, const int position) 680 { 681 const unsigned new_value_len = strlen(new_value); 682 const unsigned new_value_num = search_name_hashtable(new_value); 683 unsigned want = get_status(status_node_num, 1); 684 unsigned flag = get_status(status_node_num, 2); 685 unsigned status = get_status(status_node_num, 3); 646 686 int want_len = strlen(name_hashtable[want]); 647 687 int flag_len = strlen(name_hashtable[flag]); … … 650 690 651 691 switch (position) { 652 case (1):692 case 1: 653 693 want = new_value_num; 654 694 want_len = new_value_len; 655 695 break; 656 case (2):696 case 2: 657 697 flag = new_value_num; 658 698 flag_len = new_value_len; 659 699 break; 660 case (3):700 case 3: 661 701 status = new_value_num; 662 702 status_len = new_value_len; … … 666 706 } 667 707 668 new_status = bb_xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]);708 new_status = xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]); 669 709 status_hashtable[status_node_num]->status = search_name_hashtable(new_status); 670 710 free(new_status); 671 return; 672 } 673 674 static const char *describe_status(int status_num){675 int status_want, status_state 676 if ( status_hashtable[status_num] == NULL || status_hashtable[status_num]->status == 0)677 return "is not installed or flagged to be installed \n";711 } 712 713 static const char *describe_status(int status_num) 714 { 715 int status_want, status_state; 716 if (status_hashtable[status_num] == NULL || status_hashtable[status_num]->status == 0) 717 return "is not installed or flagged to be installed"; 678 718 679 719 status_want = get_status(status_num, 1); 680 720 status_state = get_status(status_num, 3); 681 721 682 if ( status_state == search_name_hashtable("installed")) {683 if ( status_want == search_name_hashtable("install"))722 if (status_state == search_name_hashtable("installed")) { 723 if (status_want == search_name_hashtable("install")) 684 724 return "is installed"; 685 if ( status_want == search_name_hashtable("deinstall"))725 if (status_want == search_name_hashtable("deinstall")) 686 726 return "is marked to be removed"; 687 if ( status_want == search_name_hashtable("purge"))727 if (status_want == search_name_hashtable("purge")) 688 728 return "is marked to be purged"; 689 729 } 690 if ( status_want == search_name_hashtable("unknown"))730 if (status_want == search_name_hashtable("unknown")) 691 731 return "is in an indeterminate state"; 692 if ( status_want == search_name_hashtable("install"))732 if (status_want == search_name_hashtable("install")) 693 733 return "is marked to be installed"; 694 734 … … 703 743 char *status_line; 704 744 status_node_t *status_node = NULL; 705 unsigned intstatus_num;706 707 status_file = bb_xfopen(filename, "r");708 while ((control_buffer = fgets_str(status_file, "\n\n")) != NULL) {709 const unsigned intpackage_num = fill_package_struct(control_buffer);745 unsigned status_num; 746 747 status_file = xfopen(filename, "r"); 748 while ((control_buffer = xmalloc_fgets_str(status_file, "\n\n")) != NULL) { 749 const unsigned package_num = fill_package_struct(control_buffer); 710 750 if (package_num != -1) { 711 751 status_node = xmalloc(sizeof(status_node_t)); … … 715 755 status_line += 7; 716 756 status_line += strspn(status_line, " \n\t"); 717 status_line = bb_xstrndup(status_line, strcspn(status_line, "\n\0"));757 status_line = xstrndup(status_line, strcspn(status_line, "\n")); 718 758 status_node->status = search_name_hashtable(status_line); 719 759 free(status_line); … … 726 766 } 727 767 fclose(status_file); 728 return;729 768 } 730 769 … … 743 782 } 744 783 } 745 return;746 784 } 747 785 … … 749 787 static void write_status_file(deb_file_t **deb_file) 750 788 { 751 FILE *old_status_file = bb_xfopen("/var/lib/dpkg/status", "r");752 FILE *new_status_file = bb_xfopen("/var/lib/dpkg/status.udeb", "w");789 FILE *old_status_file = xfopen("/var/lib/dpkg/status", "r"); 790 FILE *new_status_file = xfopen("/var/lib/dpkg/status.udeb", "w"); 753 791 char *package_name; 754 792 char *status_from_file; … … 761 799 762 800 /* Update previously known packages */ 763 while ((control_buffer = fgets_str(old_status_file, "\n\n")) != NULL) { 764 if ((tmp_string = strstr(control_buffer, "Package:")) == NULL) { 801 while ((control_buffer = xmalloc_fgets_str(old_status_file, "\n\n")) != NULL) { 802 tmp_string = strstr(control_buffer, "Package:"); 803 if (tmp_string == NULL) { 765 804 continue; 766 805 } … … 768 807 tmp_string += 8; 769 808 tmp_string += strspn(tmp_string, " \n\t"); 770 package_name = bb_xstrndup(tmp_string, strcspn(tmp_string, "\n\0"));809 package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n")); 771 810 write_flag = FALSE; 772 811 tmp_string = strstr(control_buffer, "Status:"); … … 775 814 tmp_string += 7; 776 815 tmp_string += strspn(tmp_string, " \n\t"); 777 status_from_file = bb_xstrndup(tmp_string, strcspn(tmp_string, "\n"));816 status_from_file = xstrndup(tmp_string, strcspn(tmp_string, "\n")); 778 817 } else { 779 818 status_from_file = NULL; … … 787 826 /* New status isnt exactly the same as old status */ 788 827 const int state_status = get_status(status_num, 3); 789 if ((strcmp("installed", name_hashtable[state_status]) == 0) || 790 (strcmp("unpacked", name_hashtable[state_status]) == 0)) { 828 if ((strcmp("installed", name_hashtable[state_status]) == 0) 829 || (strcmp("unpacked", name_hashtable[state_status]) == 0) 830 ) { 791 831 /* We need to add the control file from the package */ 792 832 i = 0; 793 while (deb_file[i] != NULL) {833 while (deb_file[i] != NULL) { 794 834 if (strcmp(package_name, name_hashtable[package_hashtable[deb_file[i]->package]->name]) == 0) { 795 835 /* Write a status file entry with a modified status */ … … 797 837 write_buffer_no_status(new_status_file, deb_file[i]->control_file); 798 838 set_status(status_num, "ok", 2); 799 fprintf(new_status_file, "Status: %s\n\n", name_hashtable[status_hashtable[status_num]->status]); 839 fprintf(new_status_file, "Status: %s\n\n", 840 name_hashtable[status_hashtable[status_num]->status]); 800 841 write_flag = TRUE; 801 842 break; … … 805 846 /* This is temperary, debugging only */ 806 847 if (deb_file[i] == NULL) { 807 bb_error_msg_and_die("ALERT: Couldnt find a control file, your status file may be broken, status may be incorrect for %s", package_name); 848 bb_error_msg_and_die("ALERT: cannot find a control file, " 849 "your status file may be broken, status may be " 850 "incorrect for %s", package_name); 808 851 } 809 852 } … … 850 893 } 851 894 /* If the package from the status file wasnt handle above, do it now*/ 852 if (! 895 if (!write_flag) { 853 896 fprintf(new_status_file, "%s\n\n", control_buffer); 854 897 } … … 860 903 861 904 /* Write any new packages */ 862 for (i = 0; deb_file[i] != NULL; i++) {905 for (i = 0; deb_file[i] != NULL; i++) { 863 906 status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[i]->package]->name]); 864 907 if (strcmp("reinstreq", name_hashtable[get_status(status_num, 2)]) == 0) { … … 878 921 /* Its ok if renaming the status file fails because status 879 922 * file doesnt exist, maybe we are starting from scratch */ 880 bb_error_msg(" No status file found, creating new one");923 bb_error_msg("no status file found, creating new one"); 881 924 } 882 925 883 926 if (rename("/var/lib/dpkg/status.udeb", "/var/lib/dpkg/status") == -1) { 884 bb_error_msg_and_die("DANGER: Couldnt create status file, you need to manually repair your status file"); 927 bb_error_msg_and_die("DANGER: cannot create status file, " 928 "you need to manually repair your status file"); 885 929 } 886 930 } … … 900 944 * provides which cannot satisfy any dependency by itself. 901 945 */ 902 if ( status_hashtable[status_num] == NULL)946 if (status_hashtable[status_num] == NULL) 903 947 return 0; 904 948 … … 927 971 * installed package for conflicts*/ 928 972 while (deb_file[i] != NULL) { 929 const unsigned intpackage_num = deb_file[i]->package;973 const unsigned package_num = deb_file[i]->package; 930 974 conflicts = xrealloc(conflicts, sizeof(int) * (conflicts_num + 1)); 931 975 conflicts[conflicts_num] = package_num; … … 940 984 if (package_hashtable[conflicts_package_num] == NULL) { 941 985 /* create a new package */ 942 common_node_t *new_node = (common_node_t *)xzalloc(sizeof(common_node_t));986 common_node_t *new_node = xzalloc(sizeof(common_node_t)); 943 987 new_node->name = package_hashtable[package_num]->edge[j]->name; 944 988 new_node->version = package_hashtable[package_num]->edge[j]->version; … … 969 1013 970 1014 if (package_edge->type == EDGE_CONFLICTS) { 971 const unsigned intpackage_num =1015 const unsigned package_num = 972 1016 search_package_hashtable(package_edge->name, 973 1017 package_edge->version, … … 984 1028 985 1029 if (result) { 986 bb_error_msg_and_die(" Package %s conflicts with %s",1030 bb_error_msg_and_die("package %s conflicts with %s", 987 1031 name_hashtable[package_node->name], 988 1032 name_hashtable[package_edge->name]); … … 1005 1049 * no dependencies to check. 1006 1050 */ 1007 if ( package_node == NULL) continue;1051 if (package_node == NULL) continue; 1008 1052 1009 1053 status_num = search_status_hashtable(name_hashtable[package_node->name]); … … 1013 1057 * case there are no dependencies to check. 1014 1058 */ 1015 if ( status_hashtable[status_num] == NULL) continue;1059 if (status_hashtable[status_num] == NULL) continue; 1016 1060 1017 1061 /* If we don't want this package installed then we may … … 1021 1065 continue; 1022 1066 } 1023 1024 #if 01025 /* This might be needed so we don't complain about1026 * things which are broken but unrelated to the1027 * packages that are currently being installed1028 */1029 if (state_status == search_name_hashtable("installed"))1030 continue;1031 #endif1032 1067 1033 1068 /* This code is tested only for EDGE_DEPENDS, since I … … 1037 1072 for (j = 0; j < package_node->num_of_edges; j++) { 1038 1073 const edge_t *package_edge = package_node->edge[j]; 1039 unsigned int package_num; 1040 1041 if ( package_edge->type == EDGE_OR_PRE_DEPENDS || 1042 package_edge->type == EDGE_OR_DEPENDS ) { /* start an EDGE_OR_ list */ 1074 unsigned package_num; 1075 1076 if (package_edge->type == EDGE_OR_PRE_DEPENDS 1077 || package_edge->type == EDGE_OR_DEPENDS 1078 ) { /* start an EDGE_OR_ list */ 1043 1079 number_of_alternatives = package_edge->version; 1044 1080 root_of_alternatives = package_edge; 1045 1081 continue; 1046 } else if ( number_of_alternatives == 0 ) { /* not in the middle of an EDGE_OR_ list */ 1082 } 1083 if (number_of_alternatives == 0) { /* not in the middle of an EDGE_OR_ list */ 1047 1084 number_of_alternatives = 1; 1048 1085 root_of_alternatives = NULL; … … 1052 1089 1053 1090 if (package_edge->type == EDGE_PRE_DEPENDS || 1054 package_edge->type == EDGE_DEPENDS 1091 package_edge->type == EDGE_DEPENDS) { 1055 1092 int result=1; 1056 1093 status_num = 0; … … 1062 1099 * EDGE_PRE_DEPENDS == OR_PRE_DEPENDS -1 1063 1100 */ 1064 if ( 1065 bb_error_msg_and_die(" Fatal error. Package dependencies corrupt: %d != %d - 1 \n",1101 if (root_of_alternatives && package_edge->type != root_of_alternatives->type - 1) 1102 bb_error_msg_and_die("fatal error, package dependencies corrupt: %d != %d - 1", 1066 1103 package_edge->type, root_of_alternatives->type); 1067 1104 … … 1072 1109 int provider = -1; 1073 1110 1074 while ( (provider = search_for_provides(package_edge->name, provider) ) > -1) {1075 if ( package_hashtable[provider] == NULL) {1076 p rintf("Have a provider but no package information for it\n");1111 while ((provider = search_for_provides(package_edge->name, provider)) > -1) { 1112 if (package_hashtable[provider] == NULL) { 1113 puts("Have a provider but no package information for it"); 1077 1114 continue; 1078 1115 } 1079 1116 result = !package_satisfies_dependency(provider, package_edge->type); 1080 1117 1081 if ( result == 0)1118 if (result == 0) 1082 1119 break; 1083 1120 } … … 1087 1124 number_of_alternatives--; 1088 1125 if (result && number_of_alternatives == 0) { 1089 if ( root_of_alternatives)1126 if (root_of_alternatives) 1090 1127 bb_error_msg_and_die( 1091 " Package %s %sdepends on %s, "1128 "package %s %sdepends on %s, " 1092 1129 "which cannot be satisfied", 1093 1130 name_hashtable[package_node->name], 1094 1131 package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", 1095 1132 name_hashtable[root_of_alternatives->name]); 1096 else1097 bb_error_msg_and_die(1098 "Package %s %sdepends on %s, which %s\n",1099 name_hashtable[package_node->name],1100 package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "",1101 name_hashtable[package_edge->name],1102 describe_status(status_num));1103 } else if ( result == 0 && number_of_alternatives) {1133 bb_error_msg_and_die( 1134 "package %s %sdepends on %s, which %s\n", 1135 name_hashtable[package_node->name], 1136 package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", 1137 name_hashtable[package_edge->name], 1138 describe_status(status_num)); 1139 } 1140 if (result == 0 && number_of_alternatives) { 1104 1141 /* we've found a package which 1105 1142 * satisfies the dependency, … … 1114 1151 } 1115 1152 free(conflicts); 1116 return (TRUE);1153 return TRUE; 1117 1154 } 1118 1155 … … 1127 1164 list_stream = fopen(filename, "r"); 1128 1165 if (list_stream == NULL) { 1129 return (NULL);1130 } 1131 1132 while ((line = bb_get_chomped_line_from_file(list_stream)) != NULL) {1166 return NULL; 1167 } 1168 1169 while ((line = xmalloc_getline(list_stream)) != NULL) { 1133 1170 file_list = xrealloc(file_list, sizeof(char *) * (count + 2)); 1134 1171 file_list[count] = line; … … 1138 1175 1139 1176 if (count == 0) { 1140 return(NULL); 1141 } else { 1142 file_list[count] = NULL; 1143 return(file_list); 1144 } 1177 return NULL; 1178 } 1179 file_list[count] = NULL; 1180 return file_list; 1145 1181 } 1146 1182 … … 1149 1185 { 1150 1186 struct stat path_stat; 1151 int match_flag; 1152 int remove_flag = FALSE; 1153 int i,j; 1187 int remove_flag = 1; /* not removed anything yet */ 1188 int i, j; 1154 1189 1155 1190 if (remove_names == NULL) { 1156 return (FALSE);1191 return 0; 1157 1192 } 1158 1193 for (i = 0; remove_names[i] != NULL; i++) { 1159 match_flag = FALSE;1160 1194 if (exclude_names != NULL) { 1161 for (j = 0; exclude_names[j] != 0; j++) {1195 for (j = 0; exclude_names[j] != NULL; j++) { 1162 1196 if (strcmp(remove_names[i], exclude_names[j]) == 0) { 1163 match_flag = TRUE; 1164 break; 1197 goto skip; 1165 1198 } 1166 1199 } 1167 1200 } 1168 if (!match_flag) { 1169 if (lstat(remove_names[i], &path_stat) < 0) { 1170 continue; 1171 } 1172 if (S_ISDIR(path_stat.st_mode)) { 1173 if (rmdir(remove_names[i]) != -1) { 1174 remove_flag = TRUE; 1175 } 1176 } else { 1177 if (unlink(remove_names[i]) != -1) { 1178 remove_flag = TRUE; 1179 } 1180 } 1181 } 1182 } 1183 return(remove_flag); 1201 /* TODO: why we are checking lstat? we can just try rm/rmdir */ 1202 if (lstat(remove_names[i], &path_stat) < 0) { 1203 continue; 1204 } 1205 if (S_ISDIR(path_stat.st_mode)) { 1206 remove_flag &= rmdir(remove_names[i]); /* 0 if no error */ 1207 } else { 1208 remove_flag &= unlink(remove_names[i]); /* 0 if no error */ 1209 } 1210 skip: 1211 continue; 1212 } 1213 return (remove_flag == 0); 1184 1214 } 1185 1215 … … 1190 1220 int result; 1191 1221 1192 script_path = bb_xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type);1222 script_path = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type); 1193 1223 1194 1224 /* If the file doesnt exist is isnt a fatal */ 1195 1225 result = lstat(script_path, &path_stat) < 0 ? EXIT_SUCCESS : system(script_path); 1196 1226 free(script_path); 1197 return(result); 1198 } 1199 1200 static const char *all_control_files[] = {"preinst", "postinst", "prerm", "postrm", 1201 "list", "md5sums", "shlibs", "conffiles", "config", "templates", NULL }; 1227 return result; 1228 } 1229 1230 static const char *const all_control_files[] = { 1231 "preinst", "postinst", "prerm", "postrm", 1232 "list", "md5sums", "shlibs", "conffiles", 1233 "config", "templates", NULL 1234 }; 1202 1235 1203 1236 static char **all_control_list(const char *package_name) 1204 1237 { 1205 unsigned shorti = 0;1238 unsigned i = 0; 1206 1239 char **remove_files; 1207 1240 … … 1209 1242 remove_files = xzalloc(sizeof(all_control_files)); 1210 1243 while (all_control_files[i]) { 1211 remove_files[i] = bb_xasprintf("/var/lib/dpkg/info/%s.%s", package_name, all_control_files[i]);1244 remove_files[i] = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, all_control_files[i]); 1212 1245 i++; 1213 1246 } 1214 1247 1215 return (remove_files);1248 return remove_files; 1216 1249 } 1217 1250 1218 1251 static void free_array(char **array) 1219 1252 { 1220 1221 1253 if (array) { 1222 unsigned shorti = 0;1254 unsigned i = 0; 1223 1255 while (array[i]) { 1224 1256 free(array[i]); … … 1237 1269 int i; 1238 1270 1239 p rintf(" Name Version\n");1240 p rintf("+++-==============-==============\n");1271 puts(" Name Version"); 1272 puts("+++-==============-=============="); 1241 1273 1242 1274 /* go through status hash, dereference package hash and finally strings */ 1243 for (i=0; i<STATUS_HASH_PRIME+1; i++) { 1244 1245 if (status_hashtable[i]) { 1246 const char *stat_str; /* status string */ 1275 for (i = 0; i < STATUS_HASH_PRIME+1; i++) { 1276 if (status_hashtable[i]) { 1277 const char *stat_str; /* status string */ 1247 1278 const char *name_str; /* package name */ 1248 1279 const char *vers_str; /* version */ … … 1259 1290 1260 1291 /* get abbreviation for status field 2 */ 1261 for (j =0, spccnt=0; stat_str[j] && spccnt<2; j++) {1262 1292 for (j = 0, spccnt = 0; stat_str[j] && spccnt < 2; j++) { 1293 if (stat_str[j] == ' ') spccnt++; 1263 1294 } 1264 1295 s2 = stat_str[j]; … … 1267 1298 printf("%c%c %-14s %s\n", s1, s2, name_str, vers_str); 1268 1299 } 1269 1270 } 1271 1272 static void remove_package(const unsigned intpackage_num, int noisy)1300 } 1301 } 1302 1303 static void remove_package(const unsigned package_num, int noisy) 1273 1304 { 1274 1305 const char *package_name = name_hashtable[package_hashtable[package_num]->name]; 1275 1306 const char *package_version = name_hashtable[package_hashtable[package_num]->version]; 1276 const unsigned intstatus_num = search_status_hashtable(package_name);1307 const unsigned status_num = search_status_hashtable(package_name); 1277 1308 const int package_name_length = strlen(package_name); 1278 1309 char **remove_files; … … 1280 1311 char list_name[package_name_length + 25]; 1281 1312 char conffile_name[package_name_length + 30]; 1282 int return_value; 1283 1284 if ( noisy ) 1285 printf("Removing %s (%s) ...\n", package_name, package_version); 1313 1314 if (noisy) 1315 printf("Removing %s (%s)...\n", package_name, package_version); 1286 1316 1287 1317 /* run prerm script */ 1288 return_value = run_package_script(package_name, "prerm"); 1289 if (return_value == -1) { 1318 if (run_package_script(package_name, "prerm") != 0) { 1290 1319 bb_error_msg_and_die("script failed, prerm failure"); 1291 1320 } … … 1298 1327 exclude_files = create_list(conffile_name); 1299 1328 1300 /* Some directories can t be removed straight away, so do multiple passes */1301 while (remove_file_array(remove_files, exclude_files)) ;1329 /* Some directories can't be removed straight away, so do multiple passes */ 1330 while (remove_file_array(remove_files, exclude_files)) /*repeat */; 1302 1331 free_array(exclude_files); 1303 1332 free_array(remove_files); … … 1305 1334 /* Create a list of files in /var/lib/dpkg/info/<package>.* to keep */ 1306 1335 exclude_files = xzalloc(sizeof(char*) * 3); 1307 exclude_files[0] = bb_xstrdup(conffile_name);1308 exclude_files[1] = bb_xasprintf("/var/lib/dpkg/info/%s.postrm", package_name);1336 exclude_files[0] = xstrdup(conffile_name); 1337 exclude_files[1] = xasprintf("/var/lib/dpkg/info/%s.postrm", package_name); 1309 1338 1310 1339 /* Create a list of all /var/lib/dpkg/info/<package> files */ … … 1322 1351 } 1323 1352 1324 static void purge_package(const unsigned intpackage_num)1353 static void purge_package(const unsigned package_num) 1325 1354 { 1326 1355 const char *package_name = name_hashtable[package_hashtable[package_num]->name]; 1327 1356 const char *package_version = name_hashtable[package_hashtable[package_num]->version]; 1328 const unsigned intstatus_num = search_status_hashtable(package_name);1357 const unsigned status_num = search_status_hashtable(package_name); 1329 1358 char **remove_files; 1330 1359 char **exclude_files; 1331 1360 char list_name[strlen(package_name) + 25]; 1332 1361 1333 printf("Purging %s (%s) 1362 printf("Purging %s (%s)...\n", package_name, package_version); 1334 1363 1335 1364 /* run prerm script */ … … 1345 1374 1346 1375 /* Some directories cant be removed straight away, so do multiple passes */ 1347 while (remove_file_array(remove_files, exclude_files)) ;1376 while (remove_file_array(remove_files, exclude_files)) /* repeat */; 1348 1377 free_array(remove_files); 1349 1378 … … 1355 1384 1356 1385 /* run postrm script */ 1357 if (run_package_script(package_name, "postrm") == -1) {1358 bb_error_msg_and_die("postrm f ialure.. set status to what?");1386 if (run_package_script(package_name, "postrm") != 0) { 1387 bb_error_msg_and_die("postrm failure.. set status to what?"); 1359 1388 } 1360 1389 … … 1370 1399 ar_handle = init_handle(); 1371 1400 ar_handle->filter = filter_accept_list_reassign; 1372 ar_handle->src_fd = bb_xopen(filename, O_RDONLY);1373 1374 return (ar_handle);1401 ar_handle->src_fd = xopen(filename, O_RDONLY); 1402 1403 return ar_handle; 1375 1404 } 1376 1405 … … 1384 1413 1385 1414 /* We don't care about data.tar.* or debian-binary, just control.tar.* */ 1386 #if def CONFIG_FEATURE_DEB_TAR_GZ1387 llist_add_to(&(ar_handle->accept), "control.tar.gz");1415 #if ENABLE_FEATURE_DEB_TAR_GZ 1416 llist_add_to(&(ar_handle->accept), (char*)"control.tar.gz"); 1388 1417 #endif 1389 #if def CONFIG_FEATURE_DEB_TAR_BZ21390 llist_add_to(&(ar_handle->accept), "control.tar.bz2");1418 #if ENABLE_FEATURE_DEB_TAR_BZ2 1419 llist_add_to(&(ar_handle->accept), (char*)"control.tar.bz2"); 1391 1420 #endif 1392 1421 1393 1422 /* Assign the tar handle as a subarchive of the ar handle */ 1394 1423 ar_handle->sub_archive = tar_handle; 1395 1396 return;1397 1424 } 1398 1425 … … 1406 1433 1407 1434 /* We don't care about control.tar.* or debian-binary, just data.tar.* */ 1408 #if def CONFIG_FEATURE_DEB_TAR_GZ1409 llist_add_to(&(ar_handle->accept), "data.tar.gz");1435 #if ENABLE_FEATURE_DEB_TAR_GZ 1436 llist_add_to(&(ar_handle->accept), (char*)"data.tar.gz"); 1410 1437 #endif 1411 #if def CONFIG_FEATURE_DEB_TAR_BZ21412 llist_add_to(&(ar_handle->accept), "data.tar.bz2");1438 #if ENABLE_FEATURE_DEB_TAR_BZ2 1439 llist_add_to(&(ar_handle->accept), (char*)"data.tar.bz2"); 1413 1440 #endif 1414 1441 1415 1442 /* Assign the tar handle as a subarchive of the ar handle */ 1416 1443 ar_handle->sub_archive = tar_handle; 1417 1418 return;1419 1444 } 1420 1445 … … 1428 1453 close(ar_handle->src_fd); 1429 1454 1430 return (ar_handle->sub_archive->buffer);1455 return ar_handle->sub_archive->buffer; 1431 1456 } 1432 1457 … … 1437 1462 name_ptr += strspn(name_ptr, "./"); 1438 1463 if (name_ptr[0] != '\0') { 1439 archive_handle->file_header->name = bb_xasprintf("%s%s", archive_handle->buffer, name_ptr);1464 archive_handle->file_header->name = xasprintf("%s%s", archive_handle->buffer, name_ptr); 1440 1465 data_extract_all(archive_handle); 1441 1466 } 1442 return;1443 1467 } 1444 1468 … … 1446 1470 { 1447 1471 const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name]; 1448 const unsigned intstatus_num = search_status_hashtable(package_name);1449 const unsigned intstatus_package_num = status_hashtable[status_num]->package;1472 const unsigned status_num = search_status_hashtable(package_name); 1473 const unsigned status_package_num = status_hashtable[status_num]->package; 1450 1474 char *info_prefix; 1475 char *list_filename; 1451 1476 archive_handle_t *archive_handle; 1452 1477 FILE *out_stream; … … 1457 1482 if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) { 1458 1483 /* Package is already installed, remove old version first */ 1459 printf("Preparing to replace %s %s (using %s) 1484 printf("Preparing to replace %s %s (using %s)...\n", package_name, 1460 1485 name_hashtable[package_hashtable[status_package_num]->version], 1461 1486 deb_file->filename); 1462 1487 remove_package(status_package_num, 0); 1463 1488 } else { 1464 printf("Unpacking %s (from %s) 1489 printf("Unpacking %s (from %s)...\n", package_name, deb_file->filename); 1465 1490 } 1466 1491 1467 1492 /* Extract control.tar.gz to /var/lib/dpkg/info/<package>.filename */ 1468 info_prefix = bb_xasprintf("/var/lib/dpkg/info/%s.", package_name);1493 info_prefix = xasprintf("/var/lib/dpkg/info/%s.", package_name); 1469 1494 archive_handle = init_archive_deb_ar(deb_file->filename); 1470 1495 init_archive_deb_control(archive_handle); 1471 1496 1472 while (all_control_files[i]) {1473 char *c = bb_xasprintf("./%s", all_control_files[i]);1497 while (all_control_files[i]) { 1498 char *c = xasprintf("./%s", all_control_files[i]); 1474 1499 llist_add_to(&accept_list, c); 1475 1500 i++; … … 1485 1510 if (run_package_script(package_name, "preinst") != 0) { 1486 1511 /* when preinst returns exit code != 0 then quit installation process */ 1487 bb_error_msg_and_die("subprocess pre-installation script returned error .");1512 bb_error_msg_and_die("subprocess pre-installation script returned error"); 1488 1513 } 1489 1514 … … 1492 1517 init_archive_deb_data(archive_handle); 1493 1518 archive_handle->sub_archive->action_data = data_extract_all_prefix; 1494 archive_handle->sub_archive->buffer = "/";1519 archive_handle->sub_archive->buffer = (char*)"/"; /* huh? */ 1495 1520 archive_handle->sub_archive->flags |= ARCHIVE_EXTRACT_UNCONDITIONAL; 1496 1521 unpack_ar_archive(archive_handle); 1497 1522 1498 1523 /* Create the list file */ 1499 strcat(info_prefix, "list");1500 out_stream = bb_xfopen(info_prefix, "w");1524 list_filename = xasprintf("/var/lib/dpkg/info/%s.list", package_name); 1525 out_stream = xfopen(list_filename, "w"); 1501 1526 while (archive_handle->sub_archive->passed) { 1502 1527 /* the leading . has been stripped by data_extract_all_prefix already */ … … 1512 1537 1513 1538 free(info_prefix); 1539 free(list_filename); 1514 1540 } 1515 1541 … … 1520 1546 const int status_num = search_status_hashtable(package_name); 1521 1547 1522 printf("Setting up %s (%s) 1548 printf("Setting up %s (%s)...\n", package_name, package_version); 1523 1549 1524 1550 /* Run the postinst script */ 1525 1551 if (run_package_script(package_name, "postinst") != 0) { 1526 1552 /* TODO: handle failure gracefully */ 1527 bb_error_msg_and_die("post rmfailure.. set status to what?");1553 bb_error_msg_and_die("postinst failure.. set status to what?"); 1528 1554 } 1529 1555 /* Change status to reflect success */ … … 1532 1558 } 1533 1559 1560 int dpkg_main(int argc, char **argv); 1534 1561 int dpkg_main(int argc, char **argv) 1535 1562 { 1536 1563 deb_file_t **deb_file = NULL; 1537 1564 status_node_t *status_node; 1565 char *str_f; 1538 1566 int opt; 1539 1567 int package_num; 1540 int dpkg_opt = 0;1541 1568 int deb_count = 0; 1542 1569 int state_status; 1543 1570 int status_num; 1544 1571 int i; 1545 1546 while ((opt = getopt(argc, argv, "CF:ilPru")) != -1) { 1547 switch (opt) { 1548 case 'C': // equivalent to --configure in official dpkg 1549 dpkg_opt |= dpkg_opt_configure; 1550 dpkg_opt |= dpkg_opt_package_name; 1551 break; 1552 case 'F': // equivalent to --force in official dpkg 1553 if (strcmp(optarg, "depends") == 0) { 1554 dpkg_opt |= dpkg_opt_force_ignore_depends; 1555 } 1556 break; 1557 case 'i': 1558 dpkg_opt |= dpkg_opt_install; 1559 dpkg_opt |= dpkg_opt_filename; 1560 break; 1561 case 'l': 1562 dpkg_opt |= dpkg_opt_list_installed; 1563 break; 1564 case 'P': 1565 dpkg_opt |= dpkg_opt_purge; 1566 dpkg_opt |= dpkg_opt_package_name; 1567 break; 1568 case 'r': 1569 dpkg_opt |= dpkg_opt_remove; 1570 dpkg_opt |= dpkg_opt_package_name; 1571 break; 1572 case 'u': /* Equivalent to --unpack in official dpkg */ 1573 dpkg_opt |= dpkg_opt_unpack; 1574 dpkg_opt |= dpkg_opt_filename; 1575 break; 1576 default: 1577 bb_show_usage(); 1578 } 1579 } 1580 /* check for non-otion argument if expected */ 1581 if ((dpkg_opt == 0) || ((argc == optind) && !(dpkg_opt && dpkg_opt_list_installed))) { 1572 enum { 1573 OPT_configure = 0x1, 1574 OPT_force_ignore_depends = 0x2, 1575 OPT_install = 0x4, 1576 OPT_list_installed = 0x8, 1577 OPT_purge = 0x10, 1578 OPT_remove = 0x20, 1579 OPT_unpack = 0x40, 1580 }; 1581 1582 opt = getopt32(argv, "CF:ilPru", &str_f); 1583 //if (opt & OPT_configure) ... // -C 1584 if (opt & OPT_force_ignore_depends) { // -F (--force in official dpkg) 1585 if (strcmp(str_f, "depends")) 1586 opt &= ~OPT_force_ignore_depends; 1587 } 1588 //if (opt & OPT_install) ... // -i 1589 //if (opt & OPT_list_installed) ... // -l 1590 //if (opt & OPT_purge) ... // -P 1591 //if (opt & OPT_remove) ... // -r 1592 //if (opt & OPT_unpack) ... // -u (--unpack in official dpkg) 1593 argc -= optind; 1594 argv += optind; 1595 /* check for non-option argument if expected */ 1596 if (!opt || (!argc && !(opt && OPT_list_installed))) 1582 1597 bb_show_usage(); 1583 } 1598 1599 name_hashtable = xzalloc(sizeof(name_hashtable[0]) * (NAME_HASH_PRIME + 1)); 1600 package_hashtable = xzalloc(sizeof(package_hashtable[0]) * (PACKAGE_HASH_PRIME + 1)); 1601 status_hashtable = xzalloc(sizeof(status_hashtable[0]) * (STATUS_HASH_PRIME + 1)); 1584 1602 1585 1603 /* puts("(Reading database ... xxxxx files and directories installed.)"); */ … … 1587 1605 1588 1606 /* if the list action was given print the installed packages and exit */ 1589 if ( dpkg_opt & dpkg_opt_list_installed) {1607 if (opt & OPT_list_installed) { 1590 1608 list_packages(); 1591 return (EXIT_SUCCESS);1609 return EXIT_SUCCESS; 1592 1610 } 1593 1611 1594 1612 /* Read arguments and store relevant info in structs */ 1595 while ( optind < argc) {1613 while (*argv) { 1596 1614 /* deb_count = nb_elem - 1 and we need nb_elem + 1 to allocate terminal node [NULL pointer] */ 1597 deb_file = xrealloc(deb_file, sizeof(deb_file_t *) * (deb_count + 2)); 1598 deb_file[deb_count] = (deb_file_t *) xzalloc(sizeof(deb_file_t)); 1599 if (dpkg_opt & dpkg_opt_filename) { 1615 deb_file = xrealloc(deb_file, sizeof(deb_file[0]) * (deb_count + 2)); 1616 deb_file[deb_count] = xzalloc(sizeof(deb_file[0][0])); 1617 if (opt & (OPT_install | OPT_unpack)) { 1618 /* -i/-u: require filename */ 1600 1619 archive_handle_t *archive_handle; 1601 1620 llist_t *control_list = NULL; 1602 1621 1603 1622 /* Extract the control file */ 1604 llist_add_to(&control_list, "./control");1605 archive_handle = init_archive_deb_ar(argv[ optind]);1623 llist_add_to(&control_list, (char*)"./control"); 1624 archive_handle = init_archive_deb_ar(argv[0]); 1606 1625 init_archive_deb_control(archive_handle); 1607 1626 deb_file[deb_count]->control_file = deb_extract_control_file_to_buffer(archive_handle, control_list); 1608 1627 if (deb_file[deb_count]->control_file == NULL) { 1609 bb_error_msg_and_die(" Couldnt extract control file");1610 } 1611 deb_file[deb_count]->filename = bb_xstrdup(argv[optind]);1628 bb_error_msg_and_die("cannot extract control file"); 1629 } 1630 deb_file[deb_count]->filename = xstrdup(argv[0]); 1612 1631 package_num = fill_package_struct(deb_file[deb_count]->control_file); 1613 1632 1614 1633 if (package_num == -1) { 1615 bb_error_msg(" Invalid control file in %s", argv[optind]);1616 optind++;1634 bb_error_msg("invalid control file in %s", argv[0]); 1635 argv++; 1617 1636 continue; 1618 1637 } 1619 deb_file[deb_count]->package = (unsigned int) package_num;1638 deb_file[deb_count]->package = (unsigned) package_num; 1620 1639 1621 1640 /* Add the package to the status hashtable */ 1622 if ( (dpkg_opt & dpkg_opt_unpack) || (dpkg_opt & dpkg_opt_install)) {1641 if (opt & (OPT_unpack | OPT_install)) { 1623 1642 /* Try and find a currently installed version of this package */ 1624 1643 status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]); 1625 1644 /* If no previous entry was found initialise a new entry */ 1626 if ((status_hashtable[status_num] == NULL) || 1627 (status_hashtable[status_num]->status == 0)) { 1628 status_node = (status_node_t *) xmalloc(sizeof(status_node_t)); 1645 if (status_hashtable[status_num] == NULL 1646 || status_hashtable[status_num]->status == 0 1647 ) { 1648 status_node = xmalloc(sizeof(status_node_t)); 1629 1649 status_node->package = deb_file[deb_count]->package; 1630 1650 /* reinstreq isnt changed to "ok" until the package control info … … 1637 1657 } 1638 1658 } 1639 } 1640 else if (dpkg_opt & dpkg_opt_package_name) {1659 } else if (opt & (OPT_configure | OPT_purge | OPT_remove)) { 1660 /* -C/-p/-r: require package name */ 1641 1661 deb_file[deb_count]->package = search_package_hashtable( 1642 search_name_hashtable(argv[optind]),1643 search_name_hashtable("ANY"), VER_ANY);1662 search_name_hashtable(argv[0]), 1663 search_name_hashtable("ANY"), VER_ANY); 1644 1664 if (package_hashtable[deb_file[deb_count]->package] == NULL) { 1645 bb_error_msg_and_die(" Package %s is uninstalled or unknown\n", argv[optind]);1665 bb_error_msg_and_die("package %s is uninstalled or unknown", argv[0]); 1646 1666 } 1647 1667 package_num = deb_file[deb_count]->package; … … 1650 1670 1651 1671 /* check package status is "installed" */ 1652 if (dpkg_opt & dpkg_opt_remove) { 1653 if ((strcmp(name_hashtable[state_status], "not-installed") == 0) || 1654 (strcmp(name_hashtable[state_status], "config-files") == 0)) { 1655 bb_error_msg_and_die("%s is already removed.", name_hashtable[package_hashtable[package_num]->name]); 1672 if (opt & OPT_remove) { 1673 if (strcmp(name_hashtable[state_status], "not-installed") == 0 1674 || strcmp(name_hashtable[state_status], "config-files") == 0 1675 ) { 1676 bb_error_msg_and_die("%s is already removed", name_hashtable[package_hashtable[package_num]->name]); 1656 1677 } 1657 1678 set_status(status_num, "deinstall", 1); 1658 } 1659 else if (dpkg_opt & dpkg_opt_purge) { 1679 } else if (opt & OPT_purge) { 1660 1680 /* if package status is "conf-files" then its ok */ 1661 1681 if (strcmp(name_hashtable[state_status], "not-installed") == 0) { 1662 bb_error_msg_and_die("%s is already purged .", name_hashtable[package_hashtable[package_num]->name]);1682 bb_error_msg_and_die("%s is already purged", name_hashtable[package_hashtable[package_num]->name]); 1663 1683 } 1664 1684 set_status(status_num, "purge", 1); … … 1666 1686 } 1667 1687 deb_count++; 1668 optind++; 1669 } 1688 argv++; 1689 } 1690 if (!deb_count) 1691 bb_error_msg_and_die("no package files specified"); 1670 1692 deb_file[deb_count] = NULL; 1671 1693 1672 1694 /* Check that the deb file arguments are installable */ 1673 if ( (dpkg_opt & dpkg_opt_force_ignore_depends) != dpkg_opt_force_ignore_depends) {1695 if (!(opt & OPT_force_ignore_depends)) { 1674 1696 if (!check_deps(deb_file, 0, deb_count)) { 1675 bb_error_msg_and_die(" Dependency check failed");1697 bb_error_msg_and_die("dependency check failed"); 1676 1698 } 1677 1699 } … … 1680 1702 for (i = 0; i < deb_count; i++) { 1681 1703 /* Remove or purge packages */ 1682 if ( dpkg_opt & dpkg_opt_remove) {1704 if (opt & OPT_remove) { 1683 1705 remove_package(deb_file[i]->package, 1); 1684 1706 } 1685 else if ( dpkg_opt & dpkg_opt_purge) {1707 else if (opt & OPT_purge) { 1686 1708 purge_package(deb_file[i]->package); 1687 1709 } 1688 else if ( dpkg_opt & dpkg_opt_unpack) {1710 else if (opt & OPT_unpack) { 1689 1711 unpack_package(deb_file[i]); 1690 1712 } 1691 else if ( dpkg_opt & dpkg_opt_install) {1713 else if (opt & OPT_install) { 1692 1714 unpack_package(deb_file[i]); 1693 1715 /* package is configured in second pass below */ 1694 1716 } 1695 else if ( dpkg_opt & dpkg_opt_configure) {1717 else if (opt & OPT_configure) { 1696 1718 configure_package(deb_file[i]); 1697 1719 } 1698 1720 } 1699 1721 /* configure installed packages */ 1700 if ( dpkg_opt & dpkg_opt_install) {1722 if (opt & OPT_install) { 1701 1723 for (i = 0; i < deb_count; i++) 1702 1724 configure_package(deb_file[i]); … … 1705 1727 write_status_file(deb_file); 1706 1728 1707 for (i = 0; i < deb_count; i++) {1708 f ree(deb_file[i]->control_file);1709 free(deb_file[i]->filename);1710 free(deb_file[i]);1711 }1712 1713 free(deb_file); 1714 1715 for (i = 0; i < NAME_HASH_PRIME; i++) { 1716 f ree(name_hashtable[i]);1717 }1718 1719 for (i = 0; i < PACKAGE_HASH_PRIME; i++) { 1720 if (package_hashtable[i] != NULL) {1729 if (ENABLE_FEATURE_CLEAN_UP) { 1730 for (i = 0; i < deb_count; i++) { 1731 free(deb_file[i]->control_file); 1732 free(deb_file[i]->filename); 1733 free(deb_file[i]); 1734 } 1735 1736 free(deb_file); 1737 1738 for (i = 0; i < NAME_HASH_PRIME; i++) { 1739 free(name_hashtable[i]); 1740 } 1741 1742 for (i = 0; i < PACKAGE_HASH_PRIME; i++) { 1721 1743 free_package(package_hashtable[i]); 1722 1744 } 1723 } 1724 1725 for (i = 0; i < STATUS_HASH_PRIME; i++) { 1726 free(status_hashtable[i]); 1727 } 1728 1729 return(EXIT_SUCCESS); 1730 } 1731 1745 1746 for (i = 0; i < STATUS_HASH_PRIME; i++) { 1747 free(status_hashtable[i]); 1748 } 1749 1750 free(status_hashtable); 1751 free(package_hashtable); 1752 free(name_hashtable); 1753 } 1754 1755 return EXIT_SUCCESS; 1756 } -
branches/2.2.5/mindi-busybox/archival/dpkg_deb.c
r821 r1765 5 5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 6 6 */ 7 #include <fcntl.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <unistd.h> 11 7 #include "libbb.h" 12 8 #include "unarchive.h" 13 #include "busybox.h"14 9 15 10 #define DPKG_DEB_OPT_CONTENTS 1 … … 19 14 #define DPKG_DEB_OPT_EXTRACT_VERBOSE 16 20 15 16 int dpkg_deb_main(int argc, char **argv); 21 17 int dpkg_deb_main(int argc, char **argv) 22 18 { … … 24 20 archive_handle_t *tar_archive; 25 21 llist_t *control_tar_llist = NULL; 26 unsigned longopt;27 c har *extract_dir = NULL;22 unsigned opt; 23 const char *extract_dir = NULL; 28 24 short argcount = 1; 29 25 … … 36 32 ar_archive->filter = filter_accept_list_reassign; 37 33 38 #if def CONFIG_FEATURE_DEB_TAR_GZ39 llist_add_to(&(ar_archive->accept), "data.tar.gz");40 llist_add_to(&control_tar_llist, "control.tar.gz");34 #if ENABLE_FEATURE_DEB_TAR_GZ 35 llist_add_to(&(ar_archive->accept), (char*)"data.tar.gz"); 36 llist_add_to(&control_tar_llist, (char*)"control.tar.gz"); 41 37 #endif 42 38 43 #if def CONFIG_FEATURE_DEB_TAR_BZ244 llist_add_to(&(ar_archive->accept), "data.tar.bz2");45 llist_add_to(&control_tar_llist, "control.tar.bz2");39 #if ENABLE_FEATURE_DEB_TAR_BZ2 40 llist_add_to(&(ar_archive->accept), (char*)"data.tar.bz2"); 41 llist_add_to(&control_tar_llist, (char*)"control.tar.bz2"); 46 42 #endif 47 43 48 bb_opt_complementally = "?c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX";49 opt = bb_getopt_ulflags(argc,argv, "cefXx");44 opt_complementary = "?c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"; 45 opt = getopt32(argv, "cefXx"); 50 46 51 47 if (opt & DPKG_DEB_OPT_CONTENTS) { … … 66 62 * specific field to print */ 67 63 ar_archive->accept = control_tar_llist; 68 llist_add_to(&(tar_archive->accept), "./control");64 llist_add_to(&(tar_archive->accept), (char*)"./control"); 69 65 tar_archive->filter = filter_accept_list; 70 66 tar_archive->action_data = data_extract_to_stdout; … … 82 78 } 83 79 84 tar_archive->src_fd = ar_archive->src_fd = bb_xopen(argv[optind++], O_RDONLY);80 tar_archive->src_fd = ar_archive->src_fd = xopen(argv[optind++], O_RDONLY); 85 81 86 82 /* Workout where to extract the files */ … … 91 87 if (extract_dir) { 92 88 mkdir(extract_dir, 0777); /* bb_make_directory(extract_dir, 0777, 0) */ 93 bb_xchdir(extract_dir);89 xchdir(extract_dir); 94 90 } 95 91 unpack_ar_archive(ar_archive); 96 92 97 93 /* Cleanup */ 98 close 94 close(ar_archive->src_fd); 99 95 100 return (EXIT_SUCCESS);96 return EXIT_SUCCESS; 101 97 } -
branches/2.2.5/mindi-busybox/archival/gzip.c
r821 r1765 6 6 * 7 7 * Originally adjusted for busybox by Charles P. Wright <cpw@unix.asb.com> 8 * 9 * 10 * 8 * "this is a stripped down version of gzip I put into busybox, it does 9 * only standard in to standard out with -9 compression. It also requires 10 * the zcat module for some important functions." 11 11 * 12 12 * Adjusted further by Erik Andersen <andersen@codepoet.org> to support … … 17 17 */ 18 18 19 /* big objects in bss: 20 * 00000020 b bl_count 21 * 00000074 b base_length 22 * 00000078 b base_dist 23 * 00000078 b static_dtree 24 * 0000009c b bl_tree 25 * 000000f4 b dyn_dtree 26 * 00000100 b length_code 27 * 00000200 b dist_code 28 * 0000023d b depth 29 * 00000400 b flag_buf 30 * 0000047a b heap 31 * 00000480 b static_ltree 32 * 000008f4 b dyn_ltree 33 */ 34 35 /* TODO: full support for -v for DESKTOP 36 * "/usr/bin/gzip -v a bogus aa" should say: 37 a: 85.1% -- replaced with a.gz 38 gzip: bogus: No such file or directory 39 aa: 85.1% -- replaced with aa.gz 40 */ 41 42 #include "libbb.h" 43 44 45 /* =========================================================================== 46 */ 47 //#define DEBUG 1 48 /* Diagnostic functions */ 49 #ifdef DEBUG 50 # define Assert(cond,msg) { if (!(cond)) bb_error_msg(msg); } 51 # define Trace(x) fprintf x 52 # define Tracev(x) {if (verbose) fprintf x; } 53 # define Tracevv(x) {if (verbose > 1) fprintf x; } 54 # define Tracec(c,x) {if (verbose && (c)) fprintf x; } 55 # define Tracecv(c,x) {if (verbose > 1 && (c)) fprintf x; } 56 #else 57 # define Assert(cond,msg) 58 # define Trace(x) 59 # define Tracev(x) 60 # define Tracevv(x) 61 # define Tracec(c,x) 62 # define Tracecv(c,x) 63 #endif 64 65 66 /* =========================================================================== 67 */ 19 68 #define SMALL_MEM 20 21 #include <stdlib.h>22 #include <stdio.h>23 #include <string.h>24 #include <unistd.h>25 #include <errno.h>26 #include <sys/types.h>27 #include <signal.h>28 #include <utime.h>29 #include <ctype.h>30 #include <sys/types.h>31 #include <unistd.h>32 #include <dirent.h>33 #include <fcntl.h>34 #include <time.h>35 #include "busybox.h"36 37 typedef unsigned char uch;38 typedef unsigned short ush;39 typedef unsigned long ulg;40 41 /* Return codes from gzip */42 #define OK 043 #define ERROR 144 #define WARNING 245 46 /* Compression methods (see algorithm.doc) */47 /* Only STORED and DEFLATED are supported by this BusyBox module */48 #define STORED 049 /* methods 4 to 7 reserved */50 #define DEFLATED 851 52 /* To save memory for 16 bit systems, some arrays are overlaid between53 * the various modules:54 * deflate: prev+head window d_buf l_buf outbuf55 * unlzw: tab_prefix tab_suffix stack inbuf outbuf56 * For compression, input is done in window[]. For decompression, output57 * is done in window except for unlzw.58 */59 69 60 70 #ifndef INBUFSIZ … … 65 75 # endif 66 76 #endif 67 #define INBUF_EXTRA 64 /* required by unlzw() */68 77 69 78 #ifndef OUTBUFSIZ … … 74 83 # endif 75 84 #endif 76 #define OUTBUF_EXTRA 2048 /* required by unlzw() */77 85 78 86 #ifndef DIST_BUFSIZE … … 83 91 # endif 84 92 #endif 85 86 # define DECLARE(type, array, size) static type * array87 # define ALLOC(type, array, size) { \88 array = (type*)xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type)); \89 }90 # define FREE(array) {free(array), array=NULL;}91 92 #define tab_suffix window93 #define tab_prefix prev /* hash link (see deflate.c) */94 #define head (prev+WSIZE) /* hash head (see deflate.c) */95 96 static long bytes_in; /* number of input bytes */97 98 #define isize bytes_in99 /* for compatibility with old zip sources (to be cleaned) */100 101 typedef int file_t; /* Do not use stdio */102 103 #define NO_FILE (-1) /* in memory compression */104 105 106 #define PACK_MAGIC "\037\036" /* Magic header for packed files */107 #define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */108 #define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */109 #define LZH_MAGIC "\037\240" /* Magic header for SCO LZH Compress files */110 #define PKZIP_MAGIC "\120\113\003\004" /* Magic header for pkzip files */111 93 112 94 /* gzip flag byte */ … … 124 106 125 107 #ifndef WSIZE 126 # define WSIZE 0x8000 127 #endif 108 # define WSIZE 0x8000 /* window size--must be a power of two, and */ 109 #endif /* at least 32K for zip's deflate method */ 128 110 129 111 #define MIN_MATCH 3 … … 141 123 */ 142 124 143 /* put_byte is used for the compressed output */ 144 #define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\ 145 flush_outbuf();} 146 147 148 /* Output a 32 bit value to the bit stream, lsb first */ 149 #if 0 150 #define put_long(n) { \ 151 put_short((n) & 0xffff); \ 152 put_short(((ulg)(n)) >> 16); \ 153 } 125 #ifndef MAX_PATH_LEN 126 # define MAX_PATH_LEN 1024 /* max pathname length */ 154 127 #endif 155 128 156 129 #define seekable() 0 /* force sequential output */ 157 130 #define translate_eol 0 /* no option -a yet */ 158 159 /* Diagnostic functions */160 #ifdef DEBUG161 # define Assert(cond,msg) {if(!(cond)) bb_error_msg(msg);}162 # define Trace(x) fprintf x163 # define Tracev(x) {if (verbose) fprintf x ;}164 # define Tracevv(x) {if (verbose>1) fprintf x ;}165 # define Tracec(c,x) {if (verbose && (c)) fprintf x ;}166 # define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}167 #else168 # define Assert(cond,msg)169 # define Trace(x)170 # define Tracev(x)171 # define Tracevv(x)172 # define Tracec(c,x)173 # define Tracecv(c,x)174 #endif175 176 #define WARN(msg) {if (!quiet) fprintf msg ; \177 if (exit_code == OK) exit_code = WARNING;}178 179 #ifndef MAX_PATH_LEN180 # define MAX_PATH_LEN 1024 /* max pathname length */181 #endif182 183 184 /* from zip.c: */185 static int zip(int in, int out);186 static int file_read(char *buf, unsigned size);187 188 /* from deflate.c */189 static void lm_init(ush * flags);190 static ulg deflate(void);191 192 /* from trees.c */193 static void ct_init(ush * attr, int *methodp);194 static int ct_tally(int dist, int lc);195 static ulg flush_block(char *buf, ulg stored_len, int eof);196 197 /* from bits.c */198 static void bi_init(file_t zipfile);199 static void send_bits(int value, int length);200 static unsigned bi_reverse(unsigned value, int length);201 static void bi_windup(void);202 static void copy_block(char *buf, unsigned len, int header);203 static int (*read_buf) (char *buf, unsigned size);204 205 /* from util.c: */206 static void flush_outbuf(void);207 208 /* lzw.h -- define the lzw functions.209 * Copyright (C) 1992-1993 Jean-loup Gailly.210 * This is free software; you can redistribute it and/or modify it under the211 * terms of the GNU General Public License, see the file COPYING.212 */213 131 214 132 #ifndef BITS … … 227 145 */ 228 146 229 /* tailor.h -- target dependent definitions230 * Copyright (C) 1992-1993 Jean-loup Gailly.231 * This is free software; you can redistribute it and/or modify it under the232 * terms of the GNU General Public License, see the file COPYING.233 */234 235 /* The target dependent definitions should be defined here only.236 * The target dependent functions should be defined in tailor.c.237 */238 239 240 /* Common defaults */241 242 #ifndef OS_CODE243 # define OS_CODE 0x03 /* assume Unix */244 #endif245 246 #ifndef PATH_SEP247 # define PATH_SEP '/'248 #endif249 250 #ifndef OPTIONS_VAR251 # define OPTIONS_VAR "GZIP"252 #endif253 254 #ifndef Z_SUFFIX255 # define Z_SUFFIX ".gz"256 #endif257 258 147 #ifdef MAX_EXT_CHARS 259 148 # define MAX_SUFFIX MAX_EXT_CHARS … … 262 151 #endif 263 152 264 /* global buffers */ 265 266 DECLARE(uch, inbuf, INBUFSIZ + INBUF_EXTRA); 267 DECLARE(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA); 268 DECLARE(ush, d_buf, DIST_BUFSIZE); 269 DECLARE(uch, window, 2L * WSIZE); 270 DECLARE(ush, tab_prefix, 1L << BITS); 271 272 static int foreground; /* set if program run in foreground */ 273 static int method = DEFLATED; /* compression method */ 274 static int exit_code = OK; /* program exit code */ 275 static int part_nb; /* number of parts in .gz file */ 276 static long time_stamp; /* original time stamp (modification time) */ 277 static long ifile_size; /* input file size, -1 for devices (debug only) */ 278 static char z_suffix[MAX_SUFFIX + 1]; /* default suffix (can be set with --suffix) */ 279 static int z_len; /* strlen(z_suffix) */ 280 281 static int ifd; /* input file descriptor */ 282 static int ofd; /* output file descriptor */ 283 static unsigned insize; /* valid bytes in inbuf */ 284 static unsigned outcnt; /* bytes in output buffer */ 285 286 static uint32_t *crc_32_tab; 287 288 /* Output a 16 bit value, lsb first */ 289 static void put_short(ush w) 290 { 291 if (outcnt < OUTBUFSIZ - 2) { 292 outbuf[outcnt++] = (uch) ((w) & 0xff); 293 outbuf[outcnt++] = (uch) ((ush) (w) >> 8); 294 } else { 295 put_byte((uch) ((w) & 0xff)); 296 put_byte((uch) ((ush) (w) >> 8)); 297 } 298 } 299 300 /* ======================================================================== 301 * Signal and error handler. 302 */ 303 static void abort_gzip(int ATTRIBUTE_UNUSED ignored) 304 { 305 exit(ERROR); 306 } 307 308 /* =========================================================================== 309 * Clear input and output buffers 310 */ 311 static void clear_bufs(void) 312 { 313 outcnt = 0; 314 insize = 0; 315 bytes_in = 0L; 316 } 317 318 /* =========================================================================== 319 * Does the same as write(), but also handles partial pipe writes and checks 320 * for error return. 321 */ 322 static void write_buf(int fd, void *buf, unsigned cnt) 323 { 324 unsigned n; 325 326 while ((n = write(fd, buf, cnt)) != cnt) { 327 if (n == (unsigned) (-1)) bb_error_msg_and_die(bb_msg_write_error); 328 cnt -= n; 329 buf = (void *) ((char *) buf + n); 330 } 331 } 332 333 /* =========================================================================== 334 * Run a set of bytes through the crc shift register. If s is a NULL 335 * pointer, then initialize the crc shift register contents instead. 336 * Return the current crc in either case. 337 */ 338 static uint32_t updcrc(uch * s, unsigned n) 339 { 340 static uint32_t crc = ~0; /* shift register contents */ 341 uint32_t c; /* temporary variable */ 342 343 if (s == NULL) { 344 c = ~0; 345 } else { 346 c = crc; 347 if (n) 348 do { 349 c = crc_32_tab[((int) c ^ (*s++)) & 0xff] ^ (c >> 8); 350 } while (--n); 351 } 352 crc = c; 353 return ~c; 354 } 355 356 /* bits.c -- output variable-length bit strings 357 * Copyright (C) 1992-1993 Jean-loup Gailly 358 * This is free software; you can redistribute it and/or modify it under the 359 * terms of the GNU General Public License, see the file COPYING. 360 */ 361 362 363 /* 364 * PURPOSE 365 * 366 * Output variable-length bit strings. Compression can be done 367 * to a file or to memory. (The latter is not supported in this version.) 368 * 369 * DISCUSSION 370 * 371 * The PKZIP "deflate" file format interprets compressed file data 372 * as a sequence of bits. Multi-bit strings in the file may cross 373 * byte boundaries without restriction. 374 * 375 * The first bit of each byte is the low-order bit. 376 * 377 * The routines in this file allow a variable-length bit value to 378 * be output right-to-left (useful for literal values). For 379 * left-to-right output (useful for code strings from the tree routines), 380 * the bits must have been reversed first with bi_reverse(). 381 * 382 * For in-memory compression, the compressed bit stream goes directly 383 * into the requested output buffer. The input data is read in blocks 384 * by the mem_read() function. The buffer is limited to 64K on 16 bit 385 * machines. 386 * 387 * INTERFACE 388 * 389 * void bi_init (FILE *zipfile) 390 * Initialize the bit string routines. 391 * 392 * void send_bits (int value, int length) 393 * Write out a bit string, taking the source bits right to 394 * left. 395 * 396 * int bi_reverse (int value, int length) 397 * Reverse the bits of a bit string, taking the source bits left to 398 * right and emitting them right to left. 399 * 400 * void bi_windup (void) 401 * Write out any remaining bits in an incomplete byte. 402 * 403 * void copy_block(char *buf, unsigned len, int header) 404 * Copy a stored block to the zip file, storing first the length and 405 * its one's complement if requested. 406 * 407 */ 408 409 /* =========================================================================== 410 * Local data used by the "bit string" routines. 411 */ 412 413 static file_t zfile; /* output gzip file */ 414 415 static unsigned short bi_buf; 416 417 /* Output buffer. bits are inserted starting at the bottom (least significant 418 * bits). 419 */ 420 421 #define Buf_size (8 * 2*sizeof(char)) 422 /* Number of bits used within bi_buf. (bi_buf might be implemented on 423 * more than 16 bits on some systems.) 424 */ 425 426 static int bi_valid; 427 428 /* Current input function. Set to mem_read for in-memory compression */ 429 430 #ifdef DEBUG 431 ulg bits_sent; /* bit length of the compressed data */ 432 #endif 433 434 /* =========================================================================== 435 * Initialize the bit string routines. 436 */ 437 static void bi_init(file_t zipfile) 438 { 439 zfile = zipfile; 440 bi_buf = 0; 441 bi_valid = 0; 442 #ifdef DEBUG 443 bits_sent = 0L; 444 #endif 445 446 /* Set the defaults for file compression. They are set by memcompress 447 * for in-memory compression. 448 */ 449 if (zfile != NO_FILE) { 450 read_buf = file_read; 451 } 452 } 453 454 /* =========================================================================== 455 * Send a value on a given number of bits. 456 * IN assertion: length <= 16 and value fits in length bits. 457 */ 458 static void send_bits(int value, int length) 459 { 460 #ifdef DEBUG 461 Tracev((stderr, " l %2d v %4x ", length, value)); 462 Assert(length > 0 && length <= 15, "invalid length"); 463 bits_sent += (ulg) length; 464 #endif 465 /* If not enough room in bi_buf, use (valid) bits from bi_buf and 466 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) 467 * unused bits in value. 468 */ 469 if (bi_valid > (int) Buf_size - length) { 470 bi_buf |= (value << bi_valid); 471 put_short(bi_buf); 472 bi_buf = (ush) value >> (Buf_size - bi_valid); 473 bi_valid += length - Buf_size; 474 } else { 475 bi_buf |= value << bi_valid; 476 bi_valid += length; 477 } 478 } 479 480 /* =========================================================================== 481 * Reverse the first len bits of a code, using straightforward code (a faster 482 * method would use a table) 483 * IN assertion: 1 <= len <= 15 484 */ 485 static unsigned bi_reverse(unsigned code, int len) 486 { 487 register unsigned res = 0; 488 489 do { 490 res |= code & 1; 491 code >>= 1, res <<= 1; 492 } while (--len > 0); 493 return res >> 1; 494 } 495 496 /* =========================================================================== 497 * Write out any remaining bits in an incomplete byte. 498 */ 499 static void bi_windup(void) 500 { 501 if (bi_valid > 8) { 502 put_short(bi_buf); 503 } else if (bi_valid > 0) { 504 put_byte(bi_buf); 505 } 506 bi_buf = 0; 507 bi_valid = 0; 508 #ifdef DEBUG 509 bits_sent = (bits_sent + 7) & ~7; 510 #endif 511 } 512 513 /* =========================================================================== 514 * Copy a stored block to the zip file, storing first the length and its 515 * one's complement if requested. 516 */ 517 static void copy_block(char *buf, unsigned len, int header) 518 { 519 bi_windup(); /* align on byte boundary */ 520 521 if (header) { 522 put_short((ush) len); 523 put_short((ush) ~ len); 524 #ifdef DEBUG 525 bits_sent += 2 * 16; 526 #endif 527 } 528 #ifdef DEBUG 529 bits_sent += (ulg) len << 3; 530 #endif 531 while (len--) { 532 put_byte(*buf++); 533 } 534 } 535 536 /* deflate.c -- compress data using the deflation algorithm 537 * Copyright (C) 1992-1993 Jean-loup Gailly 538 * This is free software; you can redistribute it and/or modify it under the 539 * terms of the GNU General Public License, see the file COPYING. 540 */ 541 542 /* 543 * PURPOSE 544 * 545 * Identify new text as repetitions of old text within a fixed- 546 * length sliding window trailing behind the new text. 547 * 548 * DISCUSSION 549 * 550 * The "deflation" process depends on being able to identify portions 551 * of the input text which are identical to earlier input (within a 552 * sliding window trailing behind the input currently being processed). 553 * 554 * The most straightforward technique turns out to be the fastest for 555 * most input files: try all possible matches and select the longest. 556 * The key feature of this algorithm is that insertions into the string 557 * dictionary are very simple and thus fast, and deletions are avoided 558 * completely. Insertions are performed at each input character, whereas 559 * string matches are performed only when the previous match ends. So it 560 * is preferable to spend more time in matches to allow very fast string 561 * insertions and avoid deletions. The matching algorithm for small 562 * strings is inspired from that of Rabin & Karp. A brute force approach 563 * is used to find longer strings when a small match has been found. 564 * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze 565 * (by Leonid Broukhis). 566 * A previous version of this file used a more sophisticated algorithm 567 * (by Fiala and Greene) which is guaranteed to run in linear amortized 568 * time, but has a larger average cost, uses more memory and is patented. 569 * However the F&G algorithm may be faster for some highly redundant 570 * files if the parameter max_chain_length (described below) is too large. 571 * 572 * ACKNOWLEDGMENTS 573 * 574 * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and 575 * I found it in 'freeze' written by Leonid Broukhis. 576 * Thanks to many info-zippers for bug reports and testing. 577 * 578 * REFERENCES 579 * 580 * APPNOTE.TXT documentation file in PKZIP 1.93a distribution. 581 * 582 * A description of the Rabin and Karp algorithm is given in the book 583 * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. 584 * 585 * Fiala,E.R., and Greene,D.H. 586 * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 587 * 588 * INTERFACE 589 * 590 * void lm_init (int pack_level, ush *flags) 591 * Initialize the "longest match" routines for a new file 592 * 593 * ulg deflate (void) 594 * Processes a new input file and return its compressed length. Sets 595 * the compressed length, crc, deflate flags and internal file 596 * attributes. 597 */ 598 599 600 /* =========================================================================== 601 * Configuration parameters 602 */ 603 604 /* Compile with MEDIUM_MEM to reduce the memory requirements or 153 154 /* =========================================================================== 155 * Compile with MEDIUM_MEM to reduce the memory requirements or 605 156 * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the 606 157 * entire input file can be held in memory (not possible on 16 bit systems). … … 621 172 #endif 622 173 623 /* To save space (see unlzw.c), we overlay prev+head with tab_prefix and624 * window with tab_suffix. Check that we can do this:625 */626 #if (WSIZE<<1) > (1<<BITS)627 # error cannot overlay window with tab_suffix and prev with tab_prefix0628 #endif629 #if HASH_BITS > BITS-1630 # error cannot overlay head with tab_prefix1631 #endif632 174 #define HASH_SIZE (unsigned)(1<<HASH_BITS) 633 175 #define HASH_MASK (HASH_SIZE-1) 634 176 #define WMASK (WSIZE-1) 635 177 /* HASH_SIZE and WSIZE must be powers of two */ 636 #define NIL 0637 /* Tail of hash chains */638 #define FAST 4639 #define SLOW 2640 /* speed options for the general purpose bit flag */641 178 #ifndef TOO_FAR 642 179 # define TOO_FAR 4096 643 180 #endif 644 181 /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ 645 /* =========================================================================== 646 * Local data used by the "longest match" routines. 647 */ 182 183 184 /* =========================================================================== 185 * These types are not really 'char', 'short' and 'long' 186 */ 187 typedef uint8_t uch; 188 typedef uint16_t ush; 189 typedef uint32_t ulg; 190 typedef int32_t lng; 191 648 192 typedef ush Pos; 649 193 typedef unsigned IPos; 650 651 194 /* A Pos is an index in the character window. We use short instead of int to 652 195 * save space in the various tables. IPos is used only for parameter passing. 653 196 */ 654 197 655 /* DECLARE(uch, window, 2L*WSIZE); */ 198 enum { 199 WINDOW_SIZE = 2 * WSIZE, 200 /* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the 201 * input file length plus MIN_LOOKAHEAD. 202 */ 203 204 max_chain_length = 4096, 205 /* To speed up deflation, hash chains are never searched beyond this length. 206 * A higher limit improves compression ratio but degrades the speed. 207 */ 208 209 max_lazy_match = 258, 210 /* Attempt to find a better match only when the current match is strictly 211 * smaller than this value. This mechanism is used only for compression 212 * levels >= 4. 213 */ 214 215 max_insert_length = max_lazy_match, 216 /* Insert new strings in the hash table only if the match length 217 * is not greater than this length. This saves time but degrades compression. 218 * max_insert_length is used only for compression levels <= 3. 219 */ 220 221 good_match = 32, 222 /* Use a faster search when the previous match is longer than this */ 223 224 /* Values for max_lazy_match, good_match and max_chain_length, depending on 225 * the desired pack level (0..9). The values given below have been tuned to 226 * exclude worst case performance for pathological files. Better values may be 227 * found for specific files. 228 */ 229 230 nice_match = 258, /* Stop searching when current match exceeds this */ 231 /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 232 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different 233 * meaning. 234 */ 235 }; 236 237 238 struct globals { 239 240 lng block_start; 241 242 /* window position at the beginning of the current output block. Gets 243 * negative when the window is moved backwards. 244 */ 245 unsigned ins_h; /* hash index of string to be inserted */ 246 247 #define H_SHIFT ((HASH_BITS+MIN_MATCH-1) / MIN_MATCH) 248 /* Number of bits by which ins_h and del_h must be shifted at each 249 * input step. It must be such that after MIN_MATCH steps, the oldest 250 * byte no longer takes part in the hash key, that is: 251 * H_SHIFT * MIN_MATCH >= HASH_BITS 252 */ 253 254 unsigned prev_length; 255 256 /* Length of the best match at previous step. Matches not greater than this 257 * are discarded. This is used in the lazy match evaluation. 258 */ 259 260 unsigned strstart; /* start of string to insert */ 261 unsigned match_start; /* start of matching string */ 262 unsigned lookahead; /* number of valid bytes ahead in window */ 263 264 /* =========================================================================== 265 */ 266 #define DECLARE(type, array, size) \ 267 type * array 268 #define ALLOC(type, array, size) \ 269 array = xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type)); 270 #define FREE(array) \ 271 do { free(array); array = NULL; } while (0) 272 273 /* global buffers */ 274 275 /* buffer for literals or lengths */ 276 /* DECLARE(uch, l_buf, LIT_BUFSIZE); */ 277 DECLARE(uch, l_buf, INBUFSIZ); 278 279 DECLARE(ush, d_buf, DIST_BUFSIZE); 280 DECLARE(uch, outbuf, OUTBUFSIZ); 281 656 282 /* Sliding window. Input bytes are read into the second half of the window, 657 283 * and move to the first half later to keep a dictionary of at least WSIZE … … 663 289 * be less efficient). 664 290 */ 665 666 /* DECLARE(Pos, prev, WSIZE); */ 291 DECLARE(uch, window, 2L * WSIZE); 292 667 293 /* Link to older string with same hash index. To limit the size of this 668 294 * array to 64K, this link is maintained only for the last 32K strings. 669 295 * An index in this array is thus a window index modulo 32K. 670 296 */ 671 672 /* DECLARE(Pos, head, 1<<HASH_BITS); */ 673 /* Heads of the hash chains or NIL. */ 674 675 static const ulg window_size = (ulg) 2 * WSIZE; 676 677 /* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the 678 * input file length plus MIN_LOOKAHEAD. 679 */ 680 681 static long block_start; 682 683 /* window position at the beginning of the current output block. Gets 684 * negative when the window is moved backwards. 685 */ 686 687 static unsigned ins_h; /* hash index of string to be inserted */ 688 689 #define H_SHIFT ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH) 690 /* Number of bits by which ins_h and del_h must be shifted at each 691 * input step. It must be such that after MIN_MATCH steps, the oldest 692 * byte no longer takes part in the hash key, that is: 693 * H_SHIFT * MIN_MATCH >= HASH_BITS 694 */ 695 696 static unsigned int prev_length; 697 698 /* Length of the best match at previous step. Matches not greater than this 699 * are discarded. This is used in the lazy match evaluation. 700 */ 701 702 static unsigned strstart; /* start of string to insert */ 703 static unsigned match_start; /* start of matching string */ 704 static int eofile; /* flag set at end of input file */ 705 static unsigned lookahead; /* number of valid bytes ahead in window */ 706 707 enum { 708 max_chain_length = 4096, 709 710 /* To speed up deflation, hash chains are never searched beyond this length. 711 * A higher limit improves compression ratio but degrades the speed. 712 */ 713 714 max_lazy_match = 258, 715 716 /* Attempt to find a better match only when the current match is strictly 717 * smaller than this value. This mechanism is used only for compression 718 * levels >= 4. 719 */ 720 max_insert_length = max_lazy_match, 721 /* Insert new strings in the hash table only if the match length 722 * is not greater than this length. This saves time but degrades compression. 723 * max_insert_length is used only for compression levels <= 3. 724 */ 725 726 good_match = 32, 727 728 /* Use a faster search when the previous match is longer than this */ 729 730 731 /* Values for max_lazy_match, good_match and max_chain_length, depending on 732 * the desired pack level (0..9). The values given below have been tuned to 733 * exclude worst case performance for pathological files. Better values may be 734 * found for specific files. 735 */ 736 737 nice_match = 258 /* Stop searching when current match exceeds this */ 738 739 /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 740 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different 741 * meaning. 742 */ 297 /* DECLARE(Pos, prev, WSIZE); */ 298 DECLARE(ush, prev, 1L << BITS); 299 300 /* Heads of the hash chains or 0. */ 301 /* DECLARE(Pos, head, 1<<HASH_BITS); */ 302 #define head (G1.prev + WSIZE) /* hash head (see deflate.c) */ 303 304 /* number of input bytes */ 305 ulg isize; /* only 32 bits stored in .gz file */ 306 307 /* bbox always use stdin/stdout */ 308 #define ifd STDIN_FILENO /* input file descriptor */ 309 #define ofd STDOUT_FILENO /* output file descriptor */ 310 311 #ifdef DEBUG 312 unsigned insize; /* valid bytes in l_buf */ 313 #endif 314 unsigned outcnt; /* bytes in output buffer */ 315 316 smallint eofile; /* flag set at end of input file */ 317 318 /* =========================================================================== 319 * Local data used by the "bit string" routines. 320 */ 321 322 unsigned short bi_buf; 323 324 /* Output buffer. bits are inserted starting at the bottom (least significant 325 * bits). 326 */ 327 328 #undef BUF_SIZE 329 #define BUF_SIZE (8 * sizeof(G1.bi_buf)) 330 /* Number of bits used within bi_buf. (bi_buf might be implemented on 331 * more than 16 bits on some systems.) 332 */ 333 334 int bi_valid; 335 336 /* Current input function. Set to mem_read for in-memory compression */ 337 338 #ifdef DEBUG 339 ulg bits_sent; /* bit length of the compressed data */ 340 #endif 341 342 uint32_t *crc_32_tab; 343 uint32_t crc; /* shift register contents */ 743 344 }; 744 345 745 #define EQUAL 0 746 /* result of memcmp for equal strings */ 747 748 /* =========================================================================== 749 * Prototypes for local functions. 750 */ 751 static void fill_window(void); 752 753 static int longest_match(IPos cur_match); 754 346 #define G1 (*(ptr_to_globals - 1)) 347 348 349 /* =========================================================================== 350 * Write the output buffer outbuf[0..outcnt-1] and update bytes_out. 351 * (used for the compressed data only) 352 */ 353 static void flush_outbuf(void) 354 { 355 if (G1.outcnt == 0) 356 return; 357 358 xwrite(ofd, (char *) G1.outbuf, G1.outcnt); 359 G1.outcnt = 0; 360 } 361 362 363 /* =========================================================================== 364 */ 365 /* put_8bit is used for the compressed output */ 366 #define put_8bit(c) \ 367 do { \ 368 G1.outbuf[G1.outcnt++] = (c); \ 369 if (G1.outcnt == OUTBUFSIZ) flush_outbuf(); \ 370 } while (0) 371 372 /* Output a 16 bit value, lsb first */ 373 static void put_16bit(ush w) 374 { 375 if (G1.outcnt < OUTBUFSIZ - 2) { 376 G1.outbuf[G1.outcnt++] = w; 377 G1.outbuf[G1.outcnt++] = w >> 8; 378 } else { 379 put_8bit(w); 380 put_8bit(w >> 8); 381 } 382 } 383 384 static void put_32bit(ulg n) 385 { 386 put_16bit(n); 387 put_16bit(n >> 16); 388 } 389 390 /* =========================================================================== 391 * Clear input and output buffers 392 */ 393 static void clear_bufs(void) 394 { 395 G1.outcnt = 0; 755 396 #ifdef DEBUG 756 static void check_match(IPos start, IPos match, int length); 757 #endif 758 759 /* =========================================================================== 760 * Update a hash value with the given input byte 761 * IN assertion: all calls to to UPDATE_HASH are made with consecutive 762 * input characters, so that a running hash key can be computed from the 763 * previous key instead of complete recalculation each time. 764 */ 765 #define UPDATE_HASH(h,c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK) 766 767 /* =========================================================================== 768 * Insert string s in the dictionary and set match_head to the previous head 769 * of the hash chain (the most recent string with same hash key). Return 770 * the previous length of the hash chain. 771 * IN assertion: all calls to to INSERT_STRING are made with consecutive 772 * input characters and the first MIN_MATCH bytes of s are valid 773 * (except for the last MIN_MATCH-1 bytes of the input file). 774 */ 775 #define INSERT_STRING(s, match_head) \ 776 (UPDATE_HASH(ins_h, window[(s) + MIN_MATCH-1]), \ 777 prev[(s) & WMASK] = match_head = head[ins_h], \ 778 head[ins_h] = (s)) 779 780 /* =========================================================================== 781 * Initialize the "longest match" routines for a new file 782 */ 783 static void lm_init(ush * flags) 784 { 785 register unsigned j; 786 787 /* Initialize the hash table. */ 788 memset(head, 0, HASH_SIZE * sizeof(*head)); 789 /* prev will be initialized on the fly */ 790 791 *flags |= SLOW; 792 /* ??? reduce max_chain_length for binary files */ 793 794 strstart = 0; 795 block_start = 0L; 796 797 lookahead = read_buf((char *) window, 798 sizeof(int) <= 2 ? (unsigned) WSIZE : 2 * WSIZE); 799 800 if (lookahead == 0 || lookahead == (unsigned) EOF) { 801 eofile = 1, lookahead = 0; 802 return; 803 } 804 eofile = 0; 805 /* Make sure that we always have enough lookahead. This is important 806 * if input comes from a device such as a tty. 807 */ 808 while (lookahead < MIN_LOOKAHEAD && !eofile) 809 fill_window(); 810 811 ins_h = 0; 812 for (j = 0; j < MIN_MATCH - 1; j++) 813 UPDATE_HASH(ins_h, window[j]); 814 /* If lookahead < MIN_MATCH, ins_h is garbage, but this is 815 * not important since only literal bytes will be emitted. 816 */ 817 } 397 G1.insize = 0; 398 #endif 399 G1.isize = 0; 400 } 401 402 403 /* =========================================================================== 404 * Run a set of bytes through the crc shift register. If s is a NULL 405 * pointer, then initialize the crc shift register contents instead. 406 * Return the current crc in either case. 407 */ 408 static uint32_t updcrc(uch * s, unsigned n) 409 { 410 uint32_t c = G1.crc; 411 while (n) { 412 c = G1.crc_32_tab[(uch)(c ^ *s++)] ^ (c >> 8); 413 n--; 414 } 415 G1.crc = c; 416 return c; 417 } 418 419 420 /* =========================================================================== 421 * Read a new buffer from the current input file, perform end-of-line 422 * translation, and update the crc and input file size. 423 * IN assertion: size >= 2 (for end-of-line translation) 424 */ 425 static unsigned file_read(void *buf, unsigned size) 426 { 427 unsigned len; 428 429 Assert(G1.insize == 0, "l_buf not empty"); 430 431 len = safe_read(ifd, buf, size); 432 if (len == (unsigned)(-1) || len == 0) 433 return len; 434 435 updcrc(buf, len); 436 G1.isize += len; 437 return len; 438 } 439 440 441 /* =========================================================================== 442 * Send a value on a given number of bits. 443 * IN assertion: length <= 16 and value fits in length bits. 444 */ 445 static void send_bits(int value, int length) 446 { 447 #ifdef DEBUG 448 Tracev((stderr, " l %2d v %4x ", length, value)); 449 Assert(length > 0 && length <= 15, "invalid length"); 450 G1.bits_sent += length; 451 #endif 452 /* If not enough room in bi_buf, use (valid) bits from bi_buf and 453 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) 454 * unused bits in value. 455 */ 456 if (G1.bi_valid > (int) BUF_SIZE - length) { 457 G1.bi_buf |= (value << G1.bi_valid); 458 put_16bit(G1.bi_buf); 459 G1.bi_buf = (ush) value >> (BUF_SIZE - G1.bi_valid); 460 G1.bi_valid += length - BUF_SIZE; 461 } else { 462 G1.bi_buf |= value << G1.bi_valid; 463 G1.bi_valid += length; 464 } 465 } 466 467 468 /* =========================================================================== 469 * Reverse the first len bits of a code, using straightforward code (a faster 470 * method would use a table) 471 * IN assertion: 1 <= len <= 15 472 */ 473 static unsigned bi_reverse(unsigned code, int len) 474 { 475 unsigned res = 0; 476 477 while (1) { 478 res |= code & 1; 479 if (--len <= 0) return res; 480 code >>= 1; 481 res <<= 1; 482 } 483 } 484 485 486 /* =========================================================================== 487 * Write out any remaining bits in an incomplete byte. 488 */ 489 static void bi_windup(void) 490 { 491 if (G1.bi_valid > 8) { 492 put_16bit(G1.bi_buf); 493 } else if (G1.bi_valid > 0) { 494 put_8bit(G1.bi_buf); 495 } 496 G1.bi_buf = 0; 497 G1.bi_valid = 0; 498 #ifdef DEBUG 499 G1.bits_sent = (G1.bits_sent + 7) & ~7; 500 #endif 501 } 502 503 504 /* =========================================================================== 505 * Copy a stored block to the zip file, storing first the length and its 506 * one's complement if requested. 507 */ 508 static void copy_block(char *buf, unsigned len, int header) 509 { 510 bi_windup(); /* align on byte boundary */ 511 512 if (header) { 513 put_16bit(len); 514 put_16bit(~len); 515 #ifdef DEBUG 516 G1.bits_sent += 2 * 16; 517 #endif 518 } 519 #ifdef DEBUG 520 G1.bits_sent += (ulg) len << 3; 521 #endif 522 while (len--) { 523 put_8bit(*buf++); 524 } 525 } 526 527 528 /* =========================================================================== 529 * Fill the window when the lookahead becomes insufficient. 530 * Updates strstart and lookahead, and sets eofile if end of input file. 531 * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 532 * OUT assertions: at least one byte has been read, or eofile is set; 533 * file reads are performed for at least two bytes (required for the 534 * translate_eol option). 535 */ 536 static void fill_window(void) 537 { 538 unsigned n, m; 539 unsigned more = WINDOW_SIZE - G1.lookahead - G1.strstart; 540 /* Amount of free space at the end of the window. */ 541 542 /* If the window is almost full and there is insufficient lookahead, 543 * move the upper half to the lower one to make room in the upper half. 544 */ 545 if (more == (unsigned) -1) { 546 /* Very unlikely, but possible on 16 bit machine if strstart == 0 547 * and lookahead == 1 (input done one byte at time) 548 */ 549 more--; 550 } else if (G1.strstart >= WSIZE + MAX_DIST) { 551 /* By the IN assertion, the window is not empty so we can't confuse 552 * more == 0 with more == 64K on a 16 bit machine. 553 */ 554 Assert(WINDOW_SIZE == 2 * WSIZE, "no sliding with BIG_MEM"); 555 556 memcpy(G1.window, G1.window + WSIZE, WSIZE); 557 G1.match_start -= WSIZE; 558 G1.strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ 559 560 G1.block_start -= WSIZE; 561 562 for (n = 0; n < HASH_SIZE; n++) { 563 m = head[n]; 564 head[n] = (Pos) (m >= WSIZE ? m - WSIZE : 0); 565 } 566 for (n = 0; n < WSIZE; n++) { 567 m = G1.prev[n]; 568 G1.prev[n] = (Pos) (m >= WSIZE ? m - WSIZE : 0); 569 /* If n is not on any hash chain, prev[n] is garbage but 570 * its value will never be used. 571 */ 572 } 573 more += WSIZE; 574 } 575 /* At this point, more >= 2 */ 576 if (!G1.eofile) { 577 n = file_read(G1.window + G1.strstart + G1.lookahead, more); 578 if (n == 0 || n == (unsigned) -1) { 579 G1.eofile = 1; 580 } else { 581 G1.lookahead += n; 582 } 583 } 584 } 585 818 586 819 587 /* =========================================================================== … … 833 601 { 834 602 unsigned chain_length = max_chain_length; /* max hash chain length */ 835 register uch *scan = window + strstart; /* current string */ 836 register uch *match; /* matched string */ 837 register int len; /* length of current match */ 838 int best_len = prev_length; /* best match length so far */ 839 IPos limit = 840 strstart > (IPos) MAX_DIST ? strstart - (IPos) MAX_DIST : NIL; 603 uch *scan = G1.window + G1.strstart; /* current string */ 604 uch *match; /* matched string */ 605 int len; /* length of current match */ 606 int best_len = G1.prev_length; /* best match length so far */ 607 IPos limit = G1.strstart > (IPos) MAX_DIST ? G1.strstart - (IPos) MAX_DIST : 0; 841 608 /* Stop when cur_match becomes <= limit. To simplify the code, 842 609 * we prevent matches with the string of window index 0. … … 849 616 # error Code too clever 850 617 #endif 851 register uch *strend = window +strstart + MAX_MATCH;852 registeruch scan_end1 = scan[best_len - 1];853 registeruch scan_end = scan[best_len];618 uch *strend = G1.window + G1.strstart + MAX_MATCH; 619 uch scan_end1 = scan[best_len - 1]; 620 uch scan_end = scan[best_len]; 854 621 855 622 /* Do not waste too much time if we already have a good match: */ 856 if ( prev_length >= good_match) {623 if (G1.prev_length >= good_match) { 857 624 chain_length >>= 2; 858 625 } 859 Assert( strstart <= window_size- MIN_LOOKAHEAD, "insufficient lookahead");626 Assert(G1.strstart <= WINDOW_SIZE - MIN_LOOKAHEAD, "insufficient lookahead"); 860 627 861 628 do { 862 Assert(cur_match < strstart, "no future");863 match = window + cur_match;629 Assert(cur_match < G1.strstart, "no future"); 630 match = G1.window + cur_match; 864 631 865 632 /* Skip to next match if the match length cannot increase … … 892 659 893 660 if (len > best_len) { 894 match_start = cur_match;661 G1.match_start = cur_match; 895 662 best_len = len; 896 663 if (len >= nice_match) … … 899 666 scan_end = scan[best_len]; 900 667 } 901 } while ((cur_match = prev[cur_match & WMASK]) > limit668 } while ((cur_match = G1.prev[cur_match & WMASK]) > limit 902 669 && --chain_length != 0); 903 670 … … 905 672 } 906 673 674 907 675 #ifdef DEBUG 908 676 /* =========================================================================== … … 912 680 { 913 681 /* check that the match is indeed a match */ 914 if (memcmp((char *) window + match, 915 (char *) window + start, length) != EQUAL) { 682 if (memcmp(G1.window + match, G1.window + start, length) != 0) { 916 683 bb_error_msg(" start %d, match %d, length %d", start, match, length); 917 684 bb_error_msg("invalid match"); … … 920 687 bb_error_msg("\\[%d,%d]", start - match, length); 921 688 do { 922 putc( window[start++], stderr);689 putc(G1.window[start++], stderr); 923 690 } while (--length != 0); 924 691 } 925 692 } 926 693 #else 927 # define check_match(start, match, length) 928 #endif 929 930 /* =========================================================================== 931 * Fill the window when the lookahead becomes insufficient. 932 * Updates strstart and lookahead, and sets eofile if end of input file. 933 * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 934 * OUT assertions: at least one byte has been read, or eofile is set; 935 * file reads are performed for at least two bytes (required for the 936 * translate_eol option). 937 */ 938 static void fill_window(void) 939 { 940 register unsigned n, m; 941 unsigned more = 942 (unsigned) (window_size - (ulg) lookahead - (ulg) strstart); 943 /* Amount of free space at the end of the window. */ 944 945 /* If the window is almost full and there is insufficient lookahead, 946 * move the upper half to the lower one to make room in the upper half. 947 */ 948 if (more == (unsigned) EOF) { 949 /* Very unlikely, but possible on 16 bit machine if strstart == 0 950 * and lookahead == 1 (input done one byte at time) 951 */ 952 more--; 953 } else if (strstart >= WSIZE + MAX_DIST) { 954 /* By the IN assertion, the window is not empty so we can't confuse 955 * more == 0 with more == 64K on a 16 bit machine. 956 */ 957 Assert(window_size == (ulg) 2 * WSIZE, "no sliding with BIG_MEM"); 958 959 memcpy((char *) window, (char *) window + WSIZE, (unsigned) WSIZE); 960 match_start -= WSIZE; 961 strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ 962 963 block_start -= (long) WSIZE; 964 965 for (n = 0; n < HASH_SIZE; n++) { 966 m = head[n]; 967 head[n] = (Pos) (m >= WSIZE ? m - WSIZE : NIL); 968 } 969 for (n = 0; n < WSIZE; n++) { 970 m = prev[n]; 971 prev[n] = (Pos) (m >= WSIZE ? m - WSIZE : NIL); 972 /* If n is not on any hash chain, prev[n] is garbage but 973 * its value will never be used. 974 */ 975 } 976 more += WSIZE; 977 } 978 /* At this point, more >= 2 */ 979 if (!eofile) { 980 n = read_buf((char *) window + strstart + lookahead, more); 981 if (n == 0 || n == (unsigned) EOF) { 982 eofile = 1; 983 } else { 984 lookahead += n; 985 } 986 } 987 } 988 989 /* =========================================================================== 990 * Flush the current block, with given end-of-file flag. 991 * IN assertion: strstart is set to the end of the current match. 992 */ 993 #define FLUSH_BLOCK(eof) \ 994 flush_block(block_start >= 0L ? (char*)&window[(unsigned)block_start] : \ 995 (char*)NULL, (long)strstart - block_start, (eof)) 996 997 /* =========================================================================== 998 * Same as above, but achieves better compression. We use a lazy 999 * evaluation for matches: a match is finally adopted only if there is 1000 * no better match at the next window position. 1001 */ 1002 static ulg deflate(void) 1003 { 1004 IPos hash_head; /* head of hash chain */ 1005 IPos prev_match; /* previous match */ 1006 int flush; /* set if current block must be flushed */ 1007 int match_available = 0; /* set if previous match exists */ 1008 register unsigned match_length = MIN_MATCH - 1; /* length of best match */ 1009 1010 /* Process the input block. */ 1011 while (lookahead != 0) { 1012 /* Insert the string window[strstart .. strstart+2] in the 1013 * dictionary, and set hash_head to the head of the hash chain: 1014 */ 1015 INSERT_STRING(strstart, hash_head); 1016 1017 /* Find the longest match, discarding those <= prev_length. 1018 */ 1019 prev_length = match_length, prev_match = match_start; 1020 match_length = MIN_MATCH - 1; 1021 1022 if (hash_head != NIL && prev_length < max_lazy_match && 1023 strstart - hash_head <= MAX_DIST) { 1024 /* To simplify the code, we prevent matches with the string 1025 * of window index 0 (in particular we have to avoid a match 1026 * of the string with itself at the start of the input file). 1027 */ 1028 match_length = longest_match(hash_head); 1029 /* longest_match() sets match_start */ 1030 if (match_length > lookahead) 1031 match_length = lookahead; 1032 1033 /* Ignore a length 3 match if it is too distant: */ 1034 if (match_length == MIN_MATCH && strstart - match_start > TOO_FAR) { 1035 /* If prev_match is also MIN_MATCH, match_start is garbage 1036 * but we will ignore the current match anyway. 1037 */ 1038 match_length--; 1039 } 1040 } 1041 /* If there was a match at the previous step and the current 1042 * match is not better, output the previous match: 1043 */ 1044 if (prev_length >= MIN_MATCH && match_length <= prev_length) { 1045 1046 check_match(strstart - 1, prev_match, prev_length); 1047 1048 flush = 1049 ct_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH); 1050 1051 /* Insert in hash table all strings up to the end of the match. 1052 * strstart-1 and strstart are already inserted. 1053 */ 1054 lookahead -= prev_length - 1; 1055 prev_length -= 2; 1056 do { 1057 strstart++; 1058 INSERT_STRING(strstart, hash_head); 1059 /* strstart never exceeds WSIZE-MAX_MATCH, so there are 1060 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH 1061 * these bytes are garbage, but it does not matter since the 1062 * next lookahead bytes will always be emitted as literals. 1063 */ 1064 } while (--prev_length != 0); 1065 match_available = 0; 1066 match_length = MIN_MATCH - 1; 1067 strstart++; 1068 if (flush) 1069 FLUSH_BLOCK(0), block_start = strstart; 1070 1071 } else if (match_available) { 1072 /* If there was no match at the previous position, output a 1073 * single literal. If there was a match but the current match 1074 * is longer, truncate the previous match to a single literal. 1075 */ 1076 Tracevv((stderr, "%c", window[strstart - 1])); 1077 if (ct_tally(0, window[strstart - 1])) { 1078 FLUSH_BLOCK(0), block_start = strstart; 1079 } 1080 strstart++; 1081 lookahead--; 1082 } else { 1083 /* There is no previous match to compare with, wait for 1084 * the next step to decide. 1085 */ 1086 match_available = 1; 1087 strstart++; 1088 lookahead--; 1089 } 1090 Assert(strstart <= isize && lookahead <= isize, "a bit too far"); 1091 1092 /* Make sure that we always have enough lookahead, except 1093 * at the end of the input file. We need MAX_MATCH bytes 1094 * for the next match, plus MIN_MATCH bytes to insert the 1095 * string following the next match. 1096 */ 1097 while (lookahead < MIN_LOOKAHEAD && !eofile) 1098 fill_window(); 1099 } 1100 if (match_available) 1101 ct_tally(0, window[strstart - 1]); 1102 1103 return FLUSH_BLOCK(1); /* eof */ 1104 } 1105 1106 /* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface 1107 * Copyright (C) 1992-1993 Jean-loup Gailly 1108 * The unzip code was written and put in the public domain by Mark Adler. 1109 * Portions of the lzw code are derived from the public domain 'compress' 1110 * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies, 1111 * Ken Turkowski, Dave Mack and Peter Jannesen. 1112 * 1113 * See the license_msg below and the file COPYING for the software license. 1114 * See the file algorithm.doc for the compression algorithms and file formats. 1115 */ 1116 1117 /* Compress files with zip algorithm and 'compress' interface. 1118 * See usage() and help() functions below for all options. 1119 * Outputs: 1120 * file.gz: compressed file with same mode, owner, and utimes 1121 * or stdout with -c option or if stdin used as input. 1122 * If the output file name had to be truncated, the original name is kept 1123 * in the compressed file. 1124 */ 1125 1126 /* configuration */ 1127 1128 typedef struct dirent dir_type; 1129 1130 /* ======================================================================== */ 1131 int gzip_main(int argc, char **argv) 1132 { 1133 int result; 1134 int inFileNum; 1135 int outFileNum; 1136 struct stat statBuf; 1137 char *delFileName; 1138 int tostdout = 0; 1139 int force = 0; 1140 int opt; 1141 1142 while ((opt = getopt(argc, argv, "cf123456789dq")) != -1) { 1143 switch (opt) { 1144 case 'c': 1145 tostdout = 1; 1146 break; 1147 case 'f': 1148 force = 1; 1149 break; 1150 /* Ignore 1-9 (compression level) options */ 1151 case '1': 1152 case '2': 1153 case '3': 1154 case '4': 1155 case '5': 1156 case '6': 1157 case '7': 1158 case '8': 1159 case '9': 1160 break; 1161 case 'q': 1162 break; 1163 #ifdef CONFIG_GUNZIP 1164 case 'd': 1165 optind = 1; 1166 return gunzip_main(argc, argv); 1167 #endif 1168 default: 1169 bb_show_usage(); 1170 } 1171 } 1172 1173 foreground = signal(SIGINT, SIG_IGN) != SIG_IGN; 1174 if (foreground) { 1175 (void) signal(SIGINT, abort_gzip); 1176 } 1177 #ifdef SIGTERM 1178 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { 1179 (void) signal(SIGTERM, abort_gzip); 1180 } 1181 #endif 1182 #ifdef SIGHUP 1183 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { 1184 (void) signal(SIGHUP, abort_gzip); 1185 } 1186 #endif 1187 1188 strncpy(z_suffix, Z_SUFFIX, sizeof(z_suffix) - 1); 1189 z_len = strlen(z_suffix); 1190 1191 /* Allocate all global buffers (for DYN_ALLOC option) */ 1192 ALLOC(uch, inbuf, INBUFSIZ + INBUF_EXTRA); 1193 ALLOC(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA); 1194 ALLOC(ush, d_buf, DIST_BUFSIZE); 1195 ALLOC(uch, window, 2L * WSIZE); 1196 ALLOC(ush, tab_prefix, 1L << BITS); 1197 1198 /* Initialise the CRC32 table */ 1199 crc_32_tab = bb_crc32_filltable(0); 1200 1201 clear_bufs(); 1202 part_nb = 0; 1203 1204 if (optind == argc) { 1205 time_stamp = 0; 1206 ifile_size = -1L; 1207 zip(STDIN_FILENO, STDOUT_FILENO); 1208 } else { 1209 int i; 1210 1211 for (i = optind; i < argc; i++) { 1212 char *path = NULL; 1213 1214 clear_bufs(); 1215 if (strcmp(argv[i], "-") == 0) { 1216 time_stamp = 0; 1217 ifile_size = -1L; 1218 inFileNum = STDIN_FILENO; 1219 outFileNum = STDOUT_FILENO; 1220 } else { 1221 inFileNum = bb_xopen3(argv[i], O_RDONLY, 0); 1222 if (fstat(inFileNum, &statBuf) < 0) 1223 bb_perror_msg_and_die("%s", argv[i]); 1224 time_stamp = statBuf.st_ctime; 1225 ifile_size = statBuf.st_size; 1226 1227 if (!tostdout) { 1228 path = xmalloc(strlen(argv[i]) + 4); 1229 strcpy(path, argv[i]); 1230 strcat(path, ".gz"); 1231 1232 /* Open output file */ 1233 #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) && defined O_NOFOLLOW 1234 outFileNum = 1235 open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW); 1236 #else 1237 outFileNum = open(path, O_RDWR | O_CREAT | O_EXCL); 1238 #endif 1239 if (outFileNum < 0) { 1240 bb_perror_msg("%s", path); 1241 free(path); 1242 continue; 1243 } 1244 1245 /* Set permissions on the file */ 1246 fchmod(outFileNum, statBuf.st_mode); 1247 } else 1248 outFileNum = STDOUT_FILENO; 1249 } 1250 1251 if (path == NULL && isatty(outFileNum) && force == 0) { 1252 bb_error_msg 1253 ("compressed data not written to a terminal. Use -f to force compression."); 1254 free(path); 1255 continue; 1256 } 1257 1258 result = zip(inFileNum, outFileNum); 1259 1260 if (path != NULL) { 1261 close(inFileNum); 1262 close(outFileNum); 1263 1264 /* Delete the original file */ 1265 if (result == OK) 1266 delFileName = argv[i]; 1267 else 1268 delFileName = path; 1269 1270 if (unlink(delFileName) < 0) 1271 bb_perror_msg("%s", delFileName); 1272 } 1273 1274 free(path); 1275 } 1276 } 1277 1278 return (exit_code); 1279 } 694 # define check_match(start, match, length) ((void)0) 695 #endif 696 1280 697 1281 698 /* trees.c -- output deflated data using Huffman coding … … 1285 702 */ 1286 703 1287 /* 1288 * PURPOSE 1289 * 704 /* PURPOSE 1290 705 * Encode various sets of source values using variable-length 1291 706 * binary code trees. 1292 707 * 1293 708 * DISCUSSION 1294 *1295 709 * The PKZIP "deflation" process uses several Huffman trees. The more 1296 710 * common source values are represented by shorter bit sequences. … … 1304 718 * 1305 719 * REFERENCES 1306 *1307 720 * Lynch, Thomas J. 1308 721 * Data Compression: Techniques and Applications, pp. 53-55. … … 1318 731 * 1319 732 * INTERFACE 733 * void ct_init() 734 * Allocate the match buffer, initialize the various tables [and save 735 * the location of the internal file attribute (ascii/binary) and 736 * method (DEFLATE/STORE) -- deleted in bbox] 1320 737 * 1321 * void ct_init (ush *attr, int *methodp) 1322 * Allocate the match buffer, initialize the various tables and save 1323 * the location of the internal file attribute (ascii/binary) and 1324 * method (DEFLATE/STORE) 1325 * 1326 * void ct_tally (int dist, int lc); 738 * void ct_tally(int dist, int lc); 1327 739 * Save the match info and tally the frequency counts. 1328 740 * 1329 * long flush_block(char *buf, ulg stored_len, int eof)741 * ulg flush_block(char *buf, ulg stored_len, int eof) 1330 742 * Determine the best encoding for the current block: dynamic trees, 1331 743 * static trees or store, and output the encoded block to the zip 1332 744 * file. Returns the total compressed length for the file so far. 1333 *1334 */1335 1336 /* ===========================================================================1337 * Constants1338 745 */ 1339 746 … … 1362 769 /* number of codes used to transfer the bit lengths */ 1363 770 1364 typedef uch extra_bits_t;1365 1366 771 /* extra bits for each length code */ 1367 static const extra_bits_t extra_lbits[LENGTH_CODES]1368 = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,772 static const uint8_t extra_lbits[LENGTH_CODES] ALIGN1 = { 773 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 1369 774 4, 4, 5, 5, 5, 5, 0 1370 775 }; 1371 776 1372 777 /* extra bits for each distance code */ 1373 static const extra_bits_t extra_dbits[D_CODES]1374 = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,778 static const uint8_t extra_dbits[D_CODES] ALIGN1 = { 779 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 1375 780 10, 10, 11, 11, 12, 12, 13, 13 1376 781 }; 1377 782 1378 783 /* extra bits for each bit length code */ 1379 static const extra_bits_t extra_blbits[BL_CODES] 1380 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 }; 784 static const uint8_t extra_blbits[BL_CODES] ALIGN1 = { 785 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 }; 786 787 /* number of codes at each bit length for an optimal tree */ 788 static const uint8_t bl_order[BL_CODES] ALIGN1 = { 789 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; 1381 790 1382 791 #define STORED_BLOCK 0 … … 1419 828 * if we rely on DIST_BUFSIZE == LIT_BUFSIZE. 1420 829 */ 1421 #if LIT_BUFSIZE > INBUFSIZ1422 #error cannot overlay l_buf and inbuf1423 #endif1424 830 #define REP_3_6 16 1425 831 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ … … 1430 836 1431 837 /* =========================================================================== 1432 * Local data 1433 */ 1434 838 */ 1435 839 /* Data structure describing a single value and its code string. */ 1436 840 typedef struct ct_data { … … 1450 854 #define Len dl.len 1451 855 1452 #define HEAP_SIZE (2*L_CODES +1)856 #define HEAP_SIZE (2*L_CODES + 1) 1453 857 /* maximum heap size */ 1454 1455 static ct_data dyn_ltree[HEAP_SIZE]; /* literal and length tree */1456 static ct_data dyn_dtree[2 * D_CODES + 1]; /* distance tree */1457 1458 static ct_data static_ltree[L_CODES + 2];1459 1460 /* The static literal tree. Since the bit lengths are imposed, there is no1461 * need for the L_CODES extra codes used during heap construction. However1462 * The codes 286 and 287 are needed to build a canonical tree (see ct_init1463 * below).1464 */1465 1466 static ct_data static_dtree[D_CODES];1467 1468 /* The static distance tree. (Actually a trivial tree since all codes use1469 * 5 bits.)1470 */1471 1472 static ct_data bl_tree[2 * BL_CODES + 1];1473 1474 /* Huffman tree for the bit lengths */1475 858 1476 859 typedef struct tree_desc { 1477 860 ct_data *dyn_tree; /* the dynamic tree */ 1478 861 ct_data *static_tree; /* corresponding static tree or NULL */ 1479 const extra_bits_t *extra_bits; /* extra bits for each code or NULL */862 const uint8_t *extra_bits; /* extra bits for each code or NULL */ 1480 863 int extra_base; /* base index for extra_bits */ 1481 864 int elems; /* max number of elements in the tree */ … … 1484 867 } tree_desc; 1485 868 1486 static tree_desc l_desc = 1487 { dyn_ltree, static_ltree, extra_lbits, LITERALS + 1, L_CODES, 1488 MAX_BITS, 0 1489 }; 1490 1491 static tree_desc d_desc = 1492 { dyn_dtree, static_dtree, extra_dbits, 0, D_CODES, MAX_BITS, 0 }; 1493 1494 static tree_desc bl_desc = 1495 { bl_tree, (ct_data *) 0, extra_blbits, 0, BL_CODES, MAX_BL_BITS, 1496 0 1497 }; 1498 1499 1500 static ush bl_count[MAX_BITS + 1]; 1501 1502 /* number of codes at each bit length for an optimal tree */ 1503 1504 static const uch bl_order[BL_CODES] 1505 = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; 869 struct globals2 { 870 871 ush heap[HEAP_SIZE]; /* heap used to build the Huffman trees */ 872 int heap_len; /* number of elements in the heap */ 873 int heap_max; /* element of largest frequency */ 874 875 /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. 876 * The same heap array is used to build all trees. 877 */ 878 879 ct_data dyn_ltree[HEAP_SIZE]; /* literal and length tree */ 880 ct_data dyn_dtree[2 * D_CODES + 1]; /* distance tree */ 881 882 ct_data static_ltree[L_CODES + 2]; 883 884 /* The static literal tree. Since the bit lengths are imposed, there is no 885 * need for the L_CODES extra codes used during heap construction. However 886 * The codes 286 and 287 are needed to build a canonical tree (see ct_init 887 * below). 888 */ 889 890 ct_data static_dtree[D_CODES]; 891 892 /* The static distance tree. (Actually a trivial tree since all codes use 893 * 5 bits.) 894 */ 895 896 ct_data bl_tree[2 * BL_CODES + 1]; 897 898 /* Huffman tree for the bit lengths */ 899 900 tree_desc l_desc; 901 tree_desc d_desc; 902 tree_desc bl_desc; 903 904 ush bl_count[MAX_BITS + 1]; 1506 905 1507 906 /* The lengths of the bit length codes are sent in order of decreasing … … 1509 908 */ 1510 909 1511 static int heap[2 * L_CODES + 1]; /* heap used to build the Huffman trees */ 1512 static int heap_len; /* number of elements in the heap */ 1513 static int heap_max; /* element of largest frequency */ 1514 1515 /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. 1516 * The same heap array is used to build all trees. 1517 */ 1518 1519 static uch depth[2 * L_CODES + 1]; 910 uch depth[2 * L_CODES + 1]; 1520 911 1521 912 /* Depth of each subtree used as tie breaker for trees of equal frequency */ 1522 913 1523 staticuch length_code[MAX_MATCH - MIN_MATCH + 1];914 uch length_code[MAX_MATCH - MIN_MATCH + 1]; 1524 915 1525 916 /* length code for each normalized match length (0 == MIN_MATCH) */ 1526 917 1527 staticuch dist_code[512];918 uch dist_code[512]; 1528 919 1529 920 /* distance codes. The first 256 values correspond to the distances … … 1532 923 */ 1533 924 1534 staticint base_length[LENGTH_CODES];925 int base_length[LENGTH_CODES]; 1535 926 1536 927 /* First normalized length for each code (0 = MIN_MATCH) */ 1537 928 1538 staticint base_dist[D_CODES];929 int base_dist[D_CODES]; 1539 930 1540 931 /* First normalized distance for each code (0 = distance of 1) */ 1541 932 1542 #define l_buf inbuf 1543 /* DECLARE(uch, l_buf, LIT_BUFSIZE); buffer for literals or lengths */ 1544 1545 /* DECLARE(ush, d_buf, DIST_BUFSIZE); buffer for distances */ 1546 1547 static uch flag_buf[(LIT_BUFSIZE / 8)]; 933 uch flag_buf[LIT_BUFSIZE / 8]; 1548 934 1549 935 /* flag_buf is a bit array distinguishing literals from lengths in … … 1551 937 */ 1552 938 1553 static unsigned last_lit;/* running index in l_buf */1554 static unsigned last_dist;/* running index in d_buf */1555 static unsigned last_flags;/* running index in flag_buf */1556 static uch flags;/* current flags not yet saved in flag_buf */1557 static uch flag_bit;/* current bit used in flags */939 unsigned last_lit; /* running index in l_buf */ 940 unsigned last_dist; /* running index in d_buf */ 941 unsigned last_flags; /* running index in flag_buf */ 942 uch flags; /* current flags not yet saved in flag_buf */ 943 uch flag_bit; /* current bit used in flags */ 1558 944 1559 945 /* bits are filled in flags starting at bit 0 (least significant). … … 1562 948 */ 1563 949 1564 static ulg opt_len; /* bit length of current block with optimal trees */ 1565 static ulg static_len; /* bit length of current block with static trees */ 1566 1567 static ulg compressed_len; /* total bit length of compressed file */ 1568 1569 1570 static ush *file_type; /* pointer to UNKNOWN, BINARY or ASCII */ 1571 static int *file_method; /* pointer to DEFLATE or STORE */ 1572 1573 /* =========================================================================== 1574 * Local (static) routines in this file. 1575 */ 1576 1577 static void init_block(void); 1578 static void pqdownheap(ct_data * tree, int k); 1579 static void gen_bitlen(tree_desc * desc); 950 ulg opt_len; /* bit length of current block with optimal trees */ 951 ulg static_len; /* bit length of current block with static trees */ 952 953 ulg compressed_len; /* total bit length of compressed file */ 954 }; 955 956 #define G2ptr ((struct globals2*)(ptr_to_globals)) 957 #define G2 (*G2ptr) 958 959 960 /* =========================================================================== 961 */ 1580 962 static void gen_codes(ct_data * tree, int max_code); 1581 963 static void build_tree(tree_desc * desc); … … 1585 967 static void send_all_trees(int lcodes, int dcodes, int blcodes); 1586 968 static void compress_block(ct_data * ltree, ct_data * dtree); 1587 static void set_file_type(void);1588 969 1589 970 1590 971 #ifndef DEBUG 1591 # define send_code(c, tree) send_bits(tree[c].Code, tree[c].Len) 1592 /* Send a code of the given tree. c and tree must not have side effects */ 1593 1594 #else /* DEBUG */ 1595 # define send_code(c, tree) \ 1596 { if (verbose>1) bb_error_msg("\ncd %3d ",(c)); \ 1597 send_bits(tree[c].Code, tree[c].Len); } 1598 #endif 1599 1600 #define d_code(dist) \ 1601 ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) 972 /* Send a code of the given tree. c and tree must not have side effects */ 973 # define SEND_CODE(c, tree) send_bits(tree[c].Code, tree[c].Len) 974 #else 975 # define SEND_CODE(c, tree) \ 976 { \ 977 if (verbose > 1) bb_error_msg("\ncd %3d ",(c)); \ 978 send_bits(tree[c].Code, tree[c].Len); \ 979 } 980 #endif 981 982 #define D_CODE(dist) \ 983 ((dist) < 256 ? G2.dist_code[dist] : G2.dist_code[256 + ((dist)>>7)]) 1602 984 /* Mapping from a distance to a distance code. dist is the distance - 1 and 1603 985 * must not have side effects. dist_code[256] and dist_code[257] are never 1604 986 * used. 1605 */ 1606 1607 /* the arguments must not have side effects */ 1608 1609 /* =========================================================================== 1610 * Allocate the match buffer, initialize the various tables and save the 1611 * location of the internal file attribute (ascii/binary) and method 1612 * (DEFLATE/STORE). 1613 */ 1614 static void ct_init(ush * attr, int *methodp) 1615 { 1616 int n; /* iterates over tree elements */ 1617 int bits; /* bit counter */ 1618 int length; /* length value */ 1619 int code; /* code value */ 1620 int dist; /* distance index */ 1621 1622 file_type = attr; 1623 file_method = methodp; 1624 compressed_len = 0L; 1625 1626 if (static_dtree[0].Len != 0) 1627 return; /* ct_init already called */ 1628 1629 /* Initialize the mapping length (0..255) -> length code (0..28) */ 1630 length = 0; 1631 for (code = 0; code < LENGTH_CODES - 1; code++) { 1632 base_length[code] = length; 1633 for (n = 0; n < (1 << extra_lbits[code]); n++) { 1634 length_code[length++] = (uch) code; 1635 } 1636 } 1637 Assert(length == 256, "ct_init: length != 256"); 1638 /* Note that the length 255 (match length 258) can be represented 1639 * in two different ways: code 284 + 5 bits or code 285, so we 1640 * overwrite length_code[255] to use the best encoding: 1641 */ 1642 length_code[length - 1] = (uch) code; 1643 1644 /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ 1645 dist = 0; 1646 for (code = 0; code < 16; code++) { 1647 base_dist[code] = dist; 1648 for (n = 0; n < (1 << extra_dbits[code]); n++) { 1649 dist_code[dist++] = (uch) code; 1650 } 1651 } 1652 Assert(dist == 256, "ct_init: dist != 256"); 1653 dist >>= 7; /* from now on, all distances are divided by 128 */ 1654 for (; code < D_CODES; code++) { 1655 base_dist[code] = dist << 7; 1656 for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { 1657 dist_code[256 + dist++] = (uch) code; 1658 } 1659 } 1660 Assert(dist == 256, "ct_init: 256+dist != 512"); 1661 1662 /* Construct the codes of the static literal tree */ 1663 for (bits = 0; bits <= MAX_BITS; bits++) 1664 bl_count[bits] = 0; 1665 n = 0; 1666 while (n <= 143) 1667 static_ltree[n++].Len = 8, bl_count[8]++; 1668 while (n <= 255) 1669 static_ltree[n++].Len = 9, bl_count[9]++; 1670 while (n <= 279) 1671 static_ltree[n++].Len = 7, bl_count[7]++; 1672 while (n <= 287) 1673 static_ltree[n++].Len = 8, bl_count[8]++; 1674 /* Codes 286 and 287 do not exist, but we must include them in the 1675 * tree construction to get a canonical Huffman tree (longest code 1676 * all ones) 1677 */ 1678 gen_codes((ct_data *) static_ltree, L_CODES + 1); 1679 1680 /* The static distance tree is trivial: */ 1681 for (n = 0; n < D_CODES; n++) { 1682 static_dtree[n].Len = 5; 1683 static_dtree[n].Code = bi_reverse(n, 5); 1684 } 1685 1686 /* Initialize the first block of the first file: */ 1687 init_block(); 1688 } 987 * The arguments must not have side effects. 988 */ 989 1689 990 1690 991 /* =========================================================================== … … 1693 994 static void init_block(void) 1694 995 { 1695 int n; 996 int n; /* iterates over tree elements */ 1696 997 1697 998 /* Initialize the trees. */ 1698 999 for (n = 0; n < L_CODES; n++) 1699 dyn_ltree[n].Freq = 0;1000 G2.dyn_ltree[n].Freq = 0; 1700 1001 for (n = 0; n < D_CODES; n++) 1701 dyn_dtree[n].Freq = 0;1002 G2.dyn_dtree[n].Freq = 0; 1702 1003 for (n = 0; n < BL_CODES; n++) 1703 bl_tree[n].Freq = 0; 1704 1705 dyn_ltree[END_BLOCK].Freq = 1; 1706 opt_len = static_len = 0L; 1707 last_lit = last_dist = last_flags = 0; 1708 flags = 0; 1709 flag_bit = 1; 1710 } 1711 1712 #define SMALLEST 1 1713 /* Index within the heap array of least frequent node in the Huffman tree */ 1714 1715 1716 /* =========================================================================== 1717 * Remove the smallest element from the heap and recreate the heap with 1718 * one less element. Updates heap and heap_len. 1719 */ 1720 #define pqremove(tree, top) \ 1721 {\ 1722 top = heap[SMALLEST]; \ 1723 heap[SMALLEST] = heap[heap_len--]; \ 1724 pqdownheap(tree, SMALLEST); \ 1725 } 1726 1727 /* =========================================================================== 1728 * Compares to subtrees, using the tree depth as tie breaker when 1729 * the subtrees have equal frequency. This minimizes the worst case length. 1730 */ 1731 #define smaller(tree, n, m) \ 1732 (tree[n].Freq < tree[m].Freq || \ 1733 (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) 1004 G2.bl_tree[n].Freq = 0; 1005 1006 G2.dyn_ltree[END_BLOCK].Freq = 1; 1007 G2.opt_len = G2.static_len = 0; 1008 G2.last_lit = G2.last_dist = G2.last_flags = 0; 1009 G2.flags = 0; 1010 G2.flag_bit = 1; 1011 } 1012 1734 1013 1735 1014 /* =========================================================================== … … 1739 1018 * two sons). 1740 1019 */ 1020 1021 /* Compares to subtrees, using the tree depth as tie breaker when 1022 * the subtrees have equal frequency. This minimizes the worst case length. */ 1023 #define SMALLER(tree, n, m) \ 1024 (tree[n].Freq < tree[m].Freq \ 1025 || (tree[n].Freq == tree[m].Freq && G2.depth[n] <= G2.depth[m])) 1026 1741 1027 static void pqdownheap(ct_data * tree, int k) 1742 1028 { 1743 int v = heap[k];1029 int v = G2.heap[k]; 1744 1030 int j = k << 1; /* left son of k */ 1745 1031 1746 while (j <= heap_len) {1032 while (j <= G2.heap_len) { 1747 1033 /* Set j to the smallest of the two sons: */ 1748 if (j < heap_len && smaller(tree, heap[j + 1],heap[j]))1034 if (j < G2.heap_len && SMALLER(tree, G2.heap[j + 1], G2.heap[j])) 1749 1035 j++; 1750 1036 1751 1037 /* Exit if v is smaller than both sons */ 1752 if ( smaller(tree, v,heap[j]))1038 if (SMALLER(tree, v, G2.heap[j])) 1753 1039 break; 1754 1040 1755 1041 /* Exchange v with the smallest son */ 1756 heap[k] =heap[j];1042 G2.heap[k] = G2.heap[j]; 1757 1043 k = j; 1758 1044 … … 1760 1046 j <<= 1; 1761 1047 } 1762 heap[k] = v; 1763 } 1048 G2.heap[k] = v; 1049 } 1050 1764 1051 1765 1052 /* =========================================================================== … … 1776 1063 { 1777 1064 ct_data *tree = desc->dyn_tree; 1778 const extra_bits_t *extra = desc->extra_bits;1065 const uint8_t *extra = desc->extra_bits; 1779 1066 int base = desc->extra_base; 1780 1067 int max_code = desc->max_code; … … 1789 1076 1790 1077 for (bits = 0; bits <= MAX_BITS; bits++) 1791 bl_count[bits] = 0;1078 G2.bl_count[bits] = 0; 1792 1079 1793 1080 /* In a first pass, compute the optimal bit lengths (which may 1794 1081 * overflow in the case of the bit length tree). 1795 1082 */ 1796 tree[ heap[heap_max]].Len = 0; /* root of the heap */1797 1798 for (h = heap_max + 1; h < HEAP_SIZE; h++) {1799 n = heap[h];1083 tree[G2.heap[G2.heap_max]].Len = 0; /* root of the heap */ 1084 1085 for (h = G2.heap_max + 1; h < HEAP_SIZE; h++) { 1086 n = G2.heap[h]; 1800 1087 bits = tree[tree[n].Dad].Len + 1; 1801 if (bits > max_length) 1802 bits = max_length, overflow++; 1088 if (bits > max_length) { 1089 bits = max_length; 1090 overflow++; 1091 } 1803 1092 tree[n].Len = (ush) bits; 1804 1093 /* We overwrite tree[n].Dad which is no longer needed */ … … 1807 1096 continue; /* not a leaf node */ 1808 1097 1809 bl_count[bits]++;1098 G2.bl_count[bits]++; 1810 1099 xbits = 0; 1811 1100 if (n >= base) 1812 1101 xbits = extra[n - base]; 1813 1102 f = tree[n].Freq; 1814 opt_len += (ulg) f *(bits + xbits);1103 G2.opt_len += (ulg) f *(bits + xbits); 1815 1104 1816 1105 if (stree) 1817 static_len += (ulg) f *(stree[n].Len + xbits);1106 G2.static_len += (ulg) f * (stree[n].Len + xbits); 1818 1107 } 1819 1108 if (overflow == 0) … … 1826 1115 do { 1827 1116 bits = max_length - 1; 1828 while ( bl_count[bits] == 0)1117 while (G2.bl_count[bits] == 0) 1829 1118 bits--; 1830 bl_count[bits]--; /* move one leaf down the tree */1831 bl_count[bits + 1] += 2; /* move one overflow item as its brother */1832 bl_count[max_length]--;1119 G2.bl_count[bits]--; /* move one leaf down the tree */ 1120 G2.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ 1121 G2.bl_count[max_length]--; 1833 1122 /* The brother of the overflow item also moves one step up, 1834 1123 * but this does not affect bl_count[max_length] … … 1843 1132 */ 1844 1133 for (bits = max_length; bits != 0; bits--) { 1845 n = bl_count[bits];1134 n = G2.bl_count[bits]; 1846 1135 while (n != 0) { 1847 m = heap[--h];1136 m = G2.heap[--h]; 1848 1137 if (m > max_code) 1849 1138 continue; 1850 1139 if (tree[m].Len != (unsigned) bits) { 1851 Trace((stderr, "code %d bits %d->%d\n", m, tree[m].Len, 1852 bits)); 1853 opt_len += 1854 ((long) bits - (long) tree[m].Len) * (long) tree[m].Freq; 1855 tree[m].Len = (ush) bits; 1140 Trace((stderr, "code %d bits %d->%d\n", m, tree[m].Len, bits)); 1141 G2.opt_len += ((int32_t) bits - tree[m].Len) * tree[m].Freq; 1142 tree[m].Len = bits; 1856 1143 } 1857 1144 n--; … … 1859 1146 } 1860 1147 } 1148 1861 1149 1862 1150 /* =========================================================================== … … 1879 1167 */ 1880 1168 for (bits = 1; bits <= MAX_BITS; bits++) { 1881 next_code[bits] = code = (code + bl_count[bits - 1]) << 1;1169 next_code[bits] = code = (code + G2.bl_count[bits - 1]) << 1; 1882 1170 } 1883 1171 /* Check that the bit counts in bl_count are consistent. The last code 1884 1172 * must be all ones. 1885 1173 */ 1886 Assert(code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,1174 Assert(code + G2.bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, 1887 1175 "inconsistent bit counts"); 1888 1176 Tracev((stderr, "\ngen_codes: max_code %d ", max_code)); … … 1896 1184 tree[n].Code = bi_reverse(next_code[len]++, len); 1897 1185 1898 Tracec(tree != static_ltree,1186 Tracec(tree != G2.static_ltree, 1899 1187 (stderr, "\nn %3d %c l %2d c %4x (%x) ", n, 1900 1188 (isgraph(n) ? n : ' '), len, tree[n].Code, … … 1902 1190 } 1903 1191 } 1192 1904 1193 1905 1194 /* =========================================================================== … … 1911 1200 * also updated if stree is not null. The field max_code is set. 1912 1201 */ 1202 1203 /* Remove the smallest element from the heap and recreate the heap with 1204 * one less element. Updates heap and heap_len. */ 1205 1206 #define SMALLEST 1 1207 /* Index within the heap array of least frequent node in the Huffman tree */ 1208 1209 #define PQREMOVE(tree, top) \ 1210 do { \ 1211 top = G2.heap[SMALLEST]; \ 1212 G2.heap[SMALLEST] = G2.heap[G2.heap_len--]; \ 1213 pqdownheap(tree, SMALLEST); \ 1214 } while (0) 1215 1913 1216 static void build_tree(tree_desc * desc) 1914 1217 { … … 1924 1227 * heap[0] is not used. 1925 1228 */ 1926 heap_len = 0, heap_max = HEAP_SIZE; 1229 G2.heap_len = 0; 1230 G2.heap_max = HEAP_SIZE; 1927 1231 1928 1232 for (n = 0; n < elems; n++) { 1929 1233 if (tree[n].Freq != 0) { 1930 heap[++heap_len] = max_code = n;1931 depth[n] = 0;1234 G2.heap[++G2.heap_len] = max_code = n; 1235 G2.depth[n] = 0; 1932 1236 } else { 1933 1237 tree[n].Len = 0; … … 1940 1244 * two codes of non zero frequency. 1941 1245 */ 1942 while ( heap_len < 2) {1943 int new = heap[++heap_len] = (max_code < 2 ? ++max_code : 0);1246 while (G2.heap_len < 2) { 1247 int new = G2.heap[++G2.heap_len] = (max_code < 2 ? ++max_code : 0); 1944 1248 1945 1249 tree[new].Freq = 1; 1946 depth[new] = 0;1947 opt_len--;1250 G2.depth[new] = 0; 1251 G2.opt_len--; 1948 1252 if (stree) 1949 static_len -= stree[new].Len;1253 G2.static_len -= stree[new].Len; 1950 1254 /* new is 0 or 1 so it does not have extra bits */ 1951 1255 } … … 1955 1259 * establish sub-heaps of increasing lengths: 1956 1260 */ 1957 for (n = heap_len / 2; n >= 1; n--)1261 for (n = G2.heap_len / 2; n >= 1; n--) 1958 1262 pqdownheap(tree, n); 1959 1263 … … 1962 1266 */ 1963 1267 do { 1964 pqremove(tree, n); /* n = node of least frequency */1965 m = heap[SMALLEST]; /* m = node of next least frequency */1966 1967 heap[--heap_max] = n; /* keep the nodes sorted by frequency */1968 heap[--heap_max] = m;1268 PQREMOVE(tree, n); /* n = node of least frequency */ 1269 m = G2.heap[SMALLEST]; /* m = node of next least frequency */ 1270 1271 G2.heap[--G2.heap_max] = n; /* keep the nodes sorted by frequency */ 1272 G2.heap[--G2.heap_max] = m; 1969 1273 1970 1274 /* Create a new node father of n and m */ 1971 1275 tree[node].Freq = tree[n].Freq + tree[m].Freq; 1972 depth[node] = (uch) (MAX(depth[n], depth[m]) + 1);1276 G2.depth[node] = MAX(G2.depth[n], G2.depth[m]) + 1; 1973 1277 tree[n].Dad = tree[m].Dad = (ush) node; 1974 1278 #ifdef DUMP_BL_TREE 1975 if (tree == bl_tree) {1279 if (tree == G2.bl_tree) { 1976 1280 bb_error_msg("\nnode %d(%d), sons %d(%d) %d(%d)", 1977 1281 node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); … … 1979 1283 #endif 1980 1284 /* and insert the new node in the heap */ 1981 heap[SMALLEST] = node++;1285 G2.heap[SMALLEST] = node++; 1982 1286 pqdownheap(tree, SMALLEST); 1983 1287 1984 } while ( heap_len >= 2);1985 1986 heap[--heap_max] =heap[SMALLEST];1288 } while (G2.heap_len >= 2); 1289 1290 G2.heap[--G2.heap_max] = G2.heap[SMALLEST]; 1987 1291 1988 1292 /* At this point, the fields freq and dad are set. We can now … … 1994 1298 gen_codes((ct_data *) tree, max_code); 1995 1299 } 1300 1996 1301 1997 1302 /* =========================================================================== … … 2011 1316 int min_count = 4; /* min repeat count */ 2012 1317 2013 if (nextlen == 0) 2014 max_count = 138, min_count = 3; 2015 tree[max_code + 1].Len = (ush) 0xffff; /* guard */ 1318 if (nextlen == 0) { 1319 max_count = 138; 1320 min_count = 3; 1321 } 1322 tree[max_code + 1].Len = 0xffff; /* guard */ 2016 1323 2017 1324 for (n = 0; n <= max_code; n++) { 2018 1325 curlen = nextlen; 2019 1326 nextlen = tree[n + 1].Len; 2020 if (++count < max_count && curlen == nextlen) {1327 if (++count < max_count && curlen == nextlen) 2021 1328 continue; 2022 } else if (count < min_count) { 2023 bl_tree[curlen].Freq += count; 1329 1330 if (count < min_count) { 1331 G2.bl_tree[curlen].Freq += count; 2024 1332 } else if (curlen != 0) { 2025 1333 if (curlen != prevlen) 2026 bl_tree[curlen].Freq++;2027 bl_tree[REP_3_6].Freq++;1334 G2.bl_tree[curlen].Freq++; 1335 G2.bl_tree[REP_3_6].Freq++; 2028 1336 } else if (count <= 10) { 2029 bl_tree[REPZ_3_10].Freq++;1337 G2.bl_tree[REPZ_3_10].Freq++; 2030 1338 } else { 2031 bl_tree[REPZ_11_138].Freq++;1339 G2.bl_tree[REPZ_11_138].Freq++; 2032 1340 } 2033 1341 count = 0; 2034 1342 prevlen = curlen; 1343 1344 max_count = 7; 1345 min_count = 4; 2035 1346 if (nextlen == 0) { 2036 max_count = 138, min_count = 3; 1347 max_count = 138; 1348 min_count = 3; 2037 1349 } else if (curlen == nextlen) { 2038 max_count = 6, min_count = 3; 2039 } else { 2040 max_count = 7, min_count = 4; 1350 max_count = 6; 1351 min_count = 3; 2041 1352 } 2042 1353 } 2043 1354 } 1355 2044 1356 2045 1357 /* =========================================================================== … … 2068 1380 } else if (count < min_count) { 2069 1381 do { 2070 send_code(curlen, bl_tree); 2071 } while (--count != 0); 2072 1382 SEND_CODE(curlen, G2.bl_tree); 1383 } while (--count); 2073 1384 } else if (curlen != 0) { 2074 1385 if (curlen != prevlen) { 2075 send_code(curlen,bl_tree);1386 SEND_CODE(curlen, G2.bl_tree); 2076 1387 count--; 2077 1388 } 2078 1389 Assert(count >= 3 && count <= 6, " 3_6?"); 2079 send_code(REP_3_6,bl_tree);1390 SEND_CODE(REP_3_6, G2.bl_tree); 2080 1391 send_bits(count - 3, 2); 2081 2082 1392 } else if (count <= 10) { 2083 send_code(REPZ_3_10,bl_tree);1393 SEND_CODE(REPZ_3_10, G2.bl_tree); 2084 1394 send_bits(count - 3, 3); 2085 2086 1395 } else { 2087 send_code(REPZ_11_138,bl_tree);1396 SEND_CODE(REPZ_11_138, G2.bl_tree); 2088 1397 send_bits(count - 11, 7); 2089 1398 } … … 2091 1400 prevlen = curlen; 2092 1401 if (nextlen == 0) { 2093 max_count = 138, min_count = 3; 1402 max_count = 138; 1403 min_count = 3; 2094 1404 } else if (curlen == nextlen) { 2095 max_count = 6, min_count = 3; 1405 max_count = 6; 1406 min_count = 3; 2096 1407 } else { 2097 max_count = 7, min_count = 4; 1408 max_count = 7; 1409 min_count = 4; 2098 1410 } 2099 1411 } 2100 1412 } 1413 2101 1414 2102 1415 /* =========================================================================== … … 2109 1422 2110 1423 /* Determine the bit length frequencies for literal and distance trees */ 2111 scan_tree( (ct_data *) dyn_ltree,l_desc.max_code);2112 scan_tree( (ct_data *) dyn_dtree,d_desc.max_code);1424 scan_tree(G2.dyn_ltree, G2.l_desc.max_code); 1425 scan_tree(G2.dyn_dtree, G2.d_desc.max_code); 2113 1426 2114 1427 /* Build the bit length tree: */ 2115 build_tree( (tree_desc *) (&bl_desc));1428 build_tree(&G2.bl_desc); 2116 1429 /* opt_len now includes the length of the tree representations, except 2117 1430 * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. … … 2123 1436 */ 2124 1437 for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) { 2125 if ( bl_tree[bl_order[max_blindex]].Len != 0)1438 if (G2.bl_tree[bl_order[max_blindex]].Len != 0) 2126 1439 break; 2127 1440 } 2128 1441 /* Update opt_len to include the bit length tree and counts */ 2129 opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;2130 Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", opt_len,static_len));1442 G2.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; 1443 Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", G2.opt_len, G2.static_len)); 2131 1444 2132 1445 return max_blindex; 2133 1446 } 1447 2134 1448 2135 1449 /* =========================================================================== … … 2151 1465 for (rank = 0; rank < blcodes; rank++) { 2152 1466 Tracev((stderr, "\nbl code %2d ", bl_order[rank])); 2153 send_bits(bl_tree[bl_order[rank]].Len, 3); 2154 } 2155 Tracev((stderr, "\nbl tree: sent %ld", bits_sent)); 2156 2157 send_tree((ct_data *) dyn_ltree, lcodes - 1); /* send the literal tree */ 2158 Tracev((stderr, "\nlit tree: sent %ld", bits_sent)); 2159 2160 send_tree((ct_data *) dyn_dtree, dcodes - 1); /* send the distance tree */ 2161 Tracev((stderr, "\ndist tree: sent %ld", bits_sent)); 2162 } 1467 send_bits(G2.bl_tree[bl_order[rank]].Len, 3); 1468 } 1469 Tracev((stderr, "\nbl tree: sent %ld", G1.bits_sent)); 1470 1471 send_tree((ct_data *) G2.dyn_ltree, lcodes - 1); /* send the literal tree */ 1472 Tracev((stderr, "\nlit tree: sent %ld", G1.bits_sent)); 1473 1474 send_tree((ct_data *) G2.dyn_dtree, dcodes - 1); /* send the distance tree */ 1475 Tracev((stderr, "\ndist tree: sent %ld", G1.bits_sent)); 1476 } 1477 1478 1479 /* =========================================================================== 1480 * Save the match info and tally the frequency counts. Return true if 1481 * the current block must be flushed. 1482 */ 1483 static int ct_tally(int dist, int lc) 1484 { 1485 G1.l_buf[G2.last_lit++] = lc; 1486 if (dist == 0) { 1487 /* lc is the unmatched char */ 1488 G2.dyn_ltree[lc].Freq++; 1489 } else { 1490 /* Here, lc is the match length - MIN_MATCH */ 1491 dist--; /* dist = match distance - 1 */ 1492 Assert((ush) dist < (ush) MAX_DIST 1493 && (ush) lc <= (ush) (MAX_MATCH - MIN_MATCH) 1494 && (ush) D_CODE(dist) < (ush) D_CODES, "ct_tally: bad match" 1495 ); 1496 1497 G2.dyn_ltree[G2.length_code[lc] + LITERALS + 1].Freq++; 1498 G2.dyn_dtree[D_CODE(dist)].Freq++; 1499 1500 G1.d_buf[G2.last_dist++] = dist; 1501 G2.flags |= G2.flag_bit; 1502 } 1503 G2.flag_bit <<= 1; 1504 1505 /* Output the flags if they fill a byte: */ 1506 if ((G2.last_lit & 7) == 0) { 1507 G2.flag_buf[G2.last_flags++] = G2.flags; 1508 G2.flags = 0; 1509 G2.flag_bit = 1; 1510 } 1511 /* Try to guess if it is profitable to stop the current block here */ 1512 if ((G2.last_lit & 0xfff) == 0) { 1513 /* Compute an upper bound for the compressed length */ 1514 ulg out_length = G2.last_lit * 8L; 1515 ulg in_length = (ulg) G1.strstart - G1.block_start; 1516 int dcode; 1517 1518 for (dcode = 0; dcode < D_CODES; dcode++) { 1519 out_length += G2.dyn_dtree[dcode].Freq * (5L + extra_dbits[dcode]); 1520 } 1521 out_length >>= 3; 1522 Trace((stderr, 1523 "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", 1524 G2.last_lit, G2.last_dist, in_length, out_length, 1525 100L - out_length * 100L / in_length)); 1526 if (G2.last_dist < G2.last_lit / 2 && out_length < in_length / 2) 1527 return 1; 1528 } 1529 return (G2.last_lit == LIT_BUFSIZE - 1 || G2.last_dist == DIST_BUFSIZE); 1530 /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K 1531 * on 16 bit machines and because stored blocks are restricted to 1532 * 64K-1 bytes. 1533 */ 1534 } 1535 1536 /* =========================================================================== 1537 * Send the block data compressed using the given Huffman trees 1538 */ 1539 static void compress_block(ct_data * ltree, ct_data * dtree) 1540 { 1541 unsigned dist; /* distance of matched string */ 1542 int lc; /* match length or unmatched char (if dist == 0) */ 1543 unsigned lx = 0; /* running index in l_buf */ 1544 unsigned dx = 0; /* running index in d_buf */ 1545 unsigned fx = 0; /* running index in flag_buf */ 1546 uch flag = 0; /* current flags */ 1547 unsigned code; /* the code to send */ 1548 int extra; /* number of extra bits to send */ 1549 1550 if (G2.last_lit != 0) do { 1551 if ((lx & 7) == 0) 1552 flag = G2.flag_buf[fx++]; 1553 lc = G1.l_buf[lx++]; 1554 if ((flag & 1) == 0) { 1555 SEND_CODE(lc, ltree); /* send a literal byte */ 1556 Tracecv(isgraph(lc), (stderr, " '%c' ", lc)); 1557 } else { 1558 /* Here, lc is the match length - MIN_MATCH */ 1559 code = G2.length_code[lc]; 1560 SEND_CODE(code + LITERALS + 1, ltree); /* send the length code */ 1561 extra = extra_lbits[code]; 1562 if (extra != 0) { 1563 lc -= G2.base_length[code]; 1564 send_bits(lc, extra); /* send the extra length bits */ 1565 } 1566 dist = G1.d_buf[dx++]; 1567 /* Here, dist is the match distance - 1 */ 1568 code = D_CODE(dist); 1569 Assert(code < D_CODES, "bad d_code"); 1570 1571 SEND_CODE(code, dtree); /* send the distance code */ 1572 extra = extra_dbits[code]; 1573 if (extra != 0) { 1574 dist -= G2.base_dist[code]; 1575 send_bits(dist, extra); /* send the extra distance bits */ 1576 } 1577 } /* literal or match pair ? */ 1578 flag >>= 1; 1579 } while (lx < G2.last_lit); 1580 1581 SEND_CODE(END_BLOCK, ltree); 1582 } 1583 2163 1584 2164 1585 /* =========================================================================== … … 2169 1590 static ulg flush_block(char *buf, ulg stored_len, int eof) 2170 1591 { 2171 ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ 2172 int max_blindex; /* index of last bit length code of non zero freq */ 2173 2174 flag_buf[last_flags] = flags; /* Save the flags for the last 8 items */ 2175 2176 /* Check if the file is ascii or binary */ 2177 if (*file_type == (ush) UNKNOWN) 2178 set_file_type(); 1592 ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ 1593 int max_blindex; /* index of last bit length code of non zero freq */ 1594 1595 G2.flag_buf[G2.last_flags] = G2.flags; /* Save the flags for the last 8 items */ 2179 1596 2180 1597 /* Construct the literal and distance trees */ 2181 build_tree( (tree_desc *) (&l_desc));2182 Tracev((stderr, "\nlit data: dyn %ld, stat %ld", opt_len,static_len));2183 2184 build_tree( (tree_desc *) (&d_desc));2185 Tracev((stderr, "\ndist data: dyn %ld, stat %ld", opt_len,static_len));1598 build_tree(&G2.l_desc); 1599 Tracev((stderr, "\nlit data: dyn %ld, stat %ld", G2.opt_len, G2.static_len)); 1600 1601 build_tree(&G2.d_desc); 1602 Tracev((stderr, "\ndist data: dyn %ld, stat %ld", G2.opt_len, G2.static_len)); 2186 1603 /* At this point, opt_len and static_len are the total bit lengths of 2187 1604 * the compressed block data, excluding the tree representations. … … 2194 1611 2195 1612 /* Determine the best encoding. Compute first the block length in bytes */ 2196 opt_lenb = ( opt_len + 3 + 7) >> 3;2197 static_lenb = ( static_len + 3 + 7) >> 3;1613 opt_lenb = (G2.opt_len + 3 + 7) >> 3; 1614 static_lenb = (G2.static_len + 3 + 7) >> 3; 2198 1615 2199 1616 Trace((stderr, 2200 1617 "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", 2201 opt_lenb, opt_len, static_lenb,static_len, stored_len,2202 last_lit,last_dist));1618 opt_lenb, G2.opt_len, static_lenb, G2.static_len, stored_len, 1619 G2.last_lit, G2.last_dist)); 2203 1620 2204 1621 if (static_lenb <= opt_lenb) … … 2209 1626 * the whole file is transformed into a stored file: 2210 1627 */ 2211 if (stored_len <= opt_lenb && eof && compressed_len == 0L && seekable()) {1628 if (stored_len <= opt_lenb && eof && G2.compressed_len == 0L && seekable()) { 2212 1629 /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ 2213 if (buf == (char *) 0)1630 if (buf == NULL) 2214 1631 bb_error_msg("block vanished"); 2215 1632 2216 1633 copy_block(buf, (unsigned) stored_len, 0); /* without header */ 2217 compressed_len = stored_len << 3; 2218 *file_method = STORED; 2219 2220 } else if (stored_len + 4 <= opt_lenb && buf != (char *) 0) { 1634 G2.compressed_len = stored_len << 3; 1635 1636 } else if (stored_len + 4 <= opt_lenb && buf != NULL) { 2221 1637 /* 4: two words for the lengths */ 2222 1638 /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. … … 2227 1643 */ 2228 1644 send_bits((STORED_BLOCK << 1) + eof, 3); /* send block type */ 2229 compressed_len = (compressed_len + 3 + 7) & ~7L;2230 compressed_len += (stored_len + 4) << 3;1645 G2.compressed_len = (G2.compressed_len + 3 + 7) & ~7L; 1646 G2.compressed_len += (stored_len + 4) << 3; 2231 1647 2232 1648 copy_block(buf, (unsigned) stored_len, 1); /* with header */ … … 2234 1650 } else if (static_lenb == opt_lenb) { 2235 1651 send_bits((STATIC_TREES << 1) + eof, 3); 2236 compress_block((ct_data *) static_ltree, (ct_data *)static_dtree);2237 compressed_len += 3 +static_len;1652 compress_block((ct_data *) G2.static_ltree, (ct_data *) G2.static_dtree); 1653 G2.compressed_len += 3 + G2.static_len; 2238 1654 } else { 2239 1655 send_bits((DYN_TREES << 1) + eof, 3); 2240 send_all_trees( l_desc.max_code + 1,d_desc.max_code + 1,1656 send_all_trees(G2.l_desc.max_code + 1, G2.d_desc.max_code + 1, 2241 1657 max_blindex + 1); 2242 compress_block((ct_data *) dyn_ltree, (ct_data *)dyn_dtree);2243 compressed_len += 3 +opt_len;2244 } 2245 Assert( compressed_len ==bits_sent, "bad compressed size");1658 compress_block((ct_data *) G2.dyn_ltree, (ct_data *) G2.dyn_dtree); 1659 G2.compressed_len += 3 + G2.opt_len; 1660 } 1661 Assert(G2.compressed_len == G1.bits_sent, "bad compressed size"); 2246 1662 init_block(); 2247 1663 2248 1664 if (eof) { 2249 1665 bi_windup(); 2250 compressed_len += 7; /* align on byte boundary */ 2251 } 2252 Tracev((stderr, "\ncomprlen %lu(%lu) ", compressed_len >> 3, 2253 compressed_len - 7 * eof)); 2254 2255 return compressed_len >> 3; 2256 } 2257 2258 /* =========================================================================== 2259 * Save the match info and tally the frequency counts. Return true if 2260 * the current block must be flushed. 2261 */ 2262 static int ct_tally(int dist, int lc) 2263 { 2264 l_buf[last_lit++] = (uch) lc; 2265 if (dist == 0) { 2266 /* lc is the unmatched char */ 2267 dyn_ltree[lc].Freq++; 2268 } else { 2269 /* Here, lc is the match length - MIN_MATCH */ 2270 dist--; /* dist = match distance - 1 */ 2271 Assert((ush) dist < (ush) MAX_DIST && 2272 (ush) lc <= (ush) (MAX_MATCH - MIN_MATCH) && 2273 (ush) d_code(dist) < (ush) D_CODES, "ct_tally: bad match"); 2274 2275 dyn_ltree[length_code[lc] + LITERALS + 1].Freq++; 2276 dyn_dtree[d_code(dist)].Freq++; 2277 2278 d_buf[last_dist++] = (ush) dist; 2279 flags |= flag_bit; 2280 } 2281 flag_bit <<= 1; 2282 2283 /* Output the flags if they fill a byte: */ 2284 if ((last_lit & 7) == 0) { 2285 flag_buf[last_flags++] = flags; 2286 flags = 0, flag_bit = 1; 2287 } 2288 /* Try to guess if it is profitable to stop the current block here */ 2289 if ((last_lit & 0xfff) == 0) { 2290 /* Compute an upper bound for the compressed length */ 2291 ulg out_length = (ulg) last_lit * 8L; 2292 ulg in_length = (ulg) strstart - block_start; 2293 int dcode; 2294 2295 for (dcode = 0; dcode < D_CODES; dcode++) { 2296 out_length += 2297 (ulg) dyn_dtree[dcode].Freq * (5L + extra_dbits[dcode]); 1666 G2.compressed_len += 7; /* align on byte boundary */ 1667 } 1668 Tracev((stderr, "\ncomprlen %lu(%lu) ", G2.compressed_len >> 3, 1669 G2.compressed_len - 7 * eof)); 1670 1671 return G2.compressed_len >> 3; 1672 } 1673 1674 1675 /* =========================================================================== 1676 * Update a hash value with the given input byte 1677 * IN assertion: all calls to to UPDATE_HASH are made with consecutive 1678 * input characters, so that a running hash key can be computed from the 1679 * previous key instead of complete recalculation each time. 1680 */ 1681 #define UPDATE_HASH(h, c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK) 1682 1683 1684 /* =========================================================================== 1685 * Same as above, but achieves better compression. We use a lazy 1686 * evaluation for matches: a match is finally adopted only if there is 1687 * no better match at the next window position. 1688 * 1689 * Processes a new input file and return its compressed length. Sets 1690 * the compressed length, crc, deflate flags and internal file 1691 * attributes. 1692 */ 1693 1694 /* Flush the current block, with given end-of-file flag. 1695 * IN assertion: strstart is set to the end of the current match. */ 1696 #define FLUSH_BLOCK(eof) \ 1697 flush_block( \ 1698 G1.block_start >= 0L \ 1699 ? (char*)&G1.window[(unsigned)G1.block_start] \ 1700 : (char*)NULL, \ 1701 (ulg)G1.strstart - G1.block_start, \ 1702 (eof) \ 1703 ) 1704 1705 /* Insert string s in the dictionary and set match_head to the previous head 1706 * of the hash chain (the most recent string with same hash key). Return 1707 * the previous length of the hash chain. 1708 * IN assertion: all calls to to INSERT_STRING are made with consecutive 1709 * input characters and the first MIN_MATCH bytes of s are valid 1710 * (except for the last MIN_MATCH-1 bytes of the input file). */ 1711 #define INSERT_STRING(s, match_head) \ 1712 do { \ 1713 UPDATE_HASH(G1.ins_h, G1.window[(s) + MIN_MATCH-1]); \ 1714 G1.prev[(s) & WMASK] = match_head = head[G1.ins_h]; \ 1715 head[G1.ins_h] = (s); \ 1716 } while (0) 1717 1718 static ulg deflate(void) 1719 { 1720 IPos hash_head; /* head of hash chain */ 1721 IPos prev_match; /* previous match */ 1722 int flush; /* set if current block must be flushed */ 1723 int match_available = 0; /* set if previous match exists */ 1724 unsigned match_length = MIN_MATCH - 1; /* length of best match */ 1725 1726 /* Process the input block. */ 1727 while (G1.lookahead != 0) { 1728 /* Insert the string window[strstart .. strstart+2] in the 1729 * dictionary, and set hash_head to the head of the hash chain: 1730 */ 1731 INSERT_STRING(G1.strstart, hash_head); 1732 1733 /* Find the longest match, discarding those <= prev_length. 1734 */ 1735 G1.prev_length = match_length; 1736 prev_match = G1.match_start; 1737 match_length = MIN_MATCH - 1; 1738 1739 if (hash_head != 0 && G1.prev_length < max_lazy_match 1740 && G1.strstart - hash_head <= MAX_DIST 1741 ) { 1742 /* To simplify the code, we prevent matches with the string 1743 * of window index 0 (in particular we have to avoid a match 1744 * of the string with itself at the start of the input file). 1745 */ 1746 match_length = longest_match(hash_head); 1747 /* longest_match() sets match_start */ 1748 if (match_length > G1.lookahead) 1749 match_length = G1.lookahead; 1750 1751 /* Ignore a length 3 match if it is too distant: */ 1752 if (match_length == MIN_MATCH && G1.strstart - G1.match_start > TOO_FAR) { 1753 /* If prev_match is also MIN_MATCH, G1.match_start is garbage 1754 * but we will ignore the current match anyway. 1755 */ 1756 match_length--; 1757 } 2298 1758 } 2299 out_length >>= 3; 2300 Trace((stderr, 2301 "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", 2302 last_lit, last_dist, in_length, out_length, 2303 100L - out_length * 100L / in_length)); 2304 if (last_dist < last_lit / 2 && out_length < in_length / 2) 2305 return 1; 2306 } 2307 return (last_lit == LIT_BUFSIZE - 1 || last_dist == DIST_BUFSIZE); 2308 /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K 2309 * on 16 bit machines and because stored blocks are restricted to 2310 * 64K-1 bytes. 2311 */ 2312 } 2313 2314 /* =========================================================================== 2315 * Send the block data compressed using the given Huffman trees 2316 */ 2317 static void compress_block(ct_data * ltree, ct_data * dtree) 2318 { 2319 unsigned dist; /* distance of matched string */ 2320 int lc; /* match length or unmatched char (if dist == 0) */ 2321 unsigned lx = 0; /* running index in l_buf */ 2322 unsigned dx = 0; /* running index in d_buf */ 2323 unsigned fx = 0; /* running index in flag_buf */ 2324 uch flag = 0; /* current flags */ 2325 unsigned code; /* the code to send */ 2326 int extra; /* number of extra bits to send */ 2327 2328 if (last_lit != 0) 2329 do { 2330 if ((lx & 7) == 0) 2331 flag = flag_buf[fx++]; 2332 lc = l_buf[lx++]; 2333 if ((flag & 1) == 0) { 2334 send_code(lc, ltree); /* send a literal byte */ 2335 Tracecv(isgraph(lc), (stderr, " '%c' ", lc)); 2336 } else { 2337 /* Here, lc is the match length - MIN_MATCH */ 2338 code = length_code[lc]; 2339 send_code(code + LITERALS + 1, ltree); /* send the length code */ 2340 extra = extra_lbits[code]; 2341 if (extra != 0) { 2342 lc -= base_length[code]; 2343 send_bits(lc, extra); /* send the extra length bits */ 2344 } 2345 dist = d_buf[dx++]; 2346 /* Here, dist is the match distance - 1 */ 2347 code = d_code(dist); 2348 Assert(code < D_CODES, "bad d_code"); 2349 2350 send_code(code, dtree); /* send the distance code */ 2351 extra = extra_dbits[code]; 2352 if (extra != 0) { 2353 dist -= base_dist[code]; 2354 send_bits(dist, extra); /* send the extra distance bits */ 2355 } 2356 } /* literal or match pair ? */ 2357 flag >>= 1; 2358 } while (lx < last_lit); 2359 2360 send_code(END_BLOCK, ltree); 2361 } 2362 2363 /* =========================================================================== 2364 * Set the file type to ASCII or BINARY, using a crude approximation: 2365 * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. 2366 * IN assertion: the fields freq of dyn_ltree are set and the total of all 2367 * frequencies does not exceed 64K (to fit in an int on 16 bit machines). 2368 */ 2369 static void set_file_type(void) 2370 { 2371 int n = 0; 2372 unsigned ascii_freq = 0; 2373 unsigned bin_freq = 0; 2374 2375 while (n < 7) 2376 bin_freq += dyn_ltree[n++].Freq; 2377 while (n < 128) 2378 ascii_freq += dyn_ltree[n++].Freq; 2379 while (n < LITERALS) 2380 bin_freq += dyn_ltree[n++].Freq; 2381 *file_type = bin_freq > (ascii_freq >> 2) ? BINARY : ASCII; 2382 if (*file_type == BINARY && translate_eol) { 2383 bb_error_msg("-l used on binary file"); 2384 } 2385 } 2386 2387 /* zip.c -- compress files to the gzip or pkzip format 2388 * Copyright (C) 1992-1993 Jean-loup Gailly 2389 * This is free software; you can redistribute it and/or modify it under the 2390 * terms of the GNU General Public License, see the file COPYING. 2391 */ 2392 2393 2394 static uint32_t crc; /* crc on uncompressed file data */ 2395 static long header_bytes; /* number of bytes in gzip header */ 2396 2397 static void put_long(ulg n) 2398 { 2399 put_short((n) & 0xffff); 2400 put_short(((ulg) (n)) >> 16); 2401 } 2402 2403 /* put_header_byte is used for the compressed output 2404 * - for the initial 4 bytes that can't overflow the buffer. 2405 */ 2406 #define put_header_byte(c) {outbuf[outcnt++]=(uch)(c);} 1759 /* If there was a match at the previous step and the current 1760 * match is not better, output the previous match: 1761 */ 1762 if (G1.prev_length >= MIN_MATCH && match_length <= G1.prev_length) { 1763 check_match(G1.strstart - 1, prev_match, G1.prev_length); 1764 flush = ct_tally(G1.strstart - 1 - prev_match, G1.prev_length - MIN_MATCH); 1765 1766 /* Insert in hash table all strings up to the end of the match. 1767 * strstart-1 and strstart are already inserted. 1768 */ 1769 G1.lookahead -= G1.prev_length - 1; 1770 G1.prev_length -= 2; 1771 do { 1772 G1.strstart++; 1773 INSERT_STRING(G1.strstart, hash_head); 1774 /* strstart never exceeds WSIZE-MAX_MATCH, so there are 1775 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH 1776 * these bytes are garbage, but it does not matter since the 1777 * next lookahead bytes will always be emitted as literals. 1778 */ 1779 } while (--G1.prev_length != 0); 1780 match_available = 0; 1781 match_length = MIN_MATCH - 1; 1782 G1.strstart++; 1783 if (flush) { 1784 FLUSH_BLOCK(0); 1785 G1.block_start = G1.strstart; 1786 } 1787 } else if (match_available) { 1788 /* If there was no match at the previous position, output a 1789 * single literal. If there was a match but the current match 1790 * is longer, truncate the previous match to a single literal. 1791 */ 1792 Tracevv((stderr, "%c", G1.window[G1.strstart - 1])); 1793 if (ct_tally(0, G1.window[G1.strstart - 1])) { 1794 FLUSH_BLOCK(0); 1795 G1.block_start = G1.strstart; 1796 } 1797 G1.strstart++; 1798 G1.lookahead--; 1799 } else { 1800 /* There is no previous match to compare with, wait for 1801 * the next step to decide. 1802 */ 1803 match_available = 1; 1804 G1.strstart++; 1805 G1.lookahead--; 1806 } 1807 Assert(G1.strstart <= G1.isize && lookahead <= G1.isize, "a bit too far"); 1808 1809 /* Make sure that we always have enough lookahead, except 1810 * at the end of the input file. We need MAX_MATCH bytes 1811 * for the next match, plus MIN_MATCH bytes to insert the 1812 * string following the next match. 1813 */ 1814 while (G1.lookahead < MIN_LOOKAHEAD && !G1.eofile) 1815 fill_window(); 1816 } 1817 if (match_available) 1818 ct_tally(0, G1.window[G1.strstart - 1]); 1819 1820 return FLUSH_BLOCK(1); /* eof */ 1821 } 1822 1823 1824 /* =========================================================================== 1825 * Initialize the bit string routines. 1826 */ 1827 static void bi_init(void) 1828 { 1829 G1.bi_buf = 0; 1830 G1.bi_valid = 0; 1831 #ifdef DEBUG 1832 G1.bits_sent = 0L; 1833 #endif 1834 } 1835 1836 1837 /* =========================================================================== 1838 * Initialize the "longest match" routines for a new file 1839 */ 1840 static void lm_init(ush * flagsp) 1841 { 1842 unsigned j; 1843 1844 /* Initialize the hash table. */ 1845 memset(head, 0, HASH_SIZE * sizeof(*head)); 1846 /* prev will be initialized on the fly */ 1847 1848 /* speed options for the general purpose bit flag */ 1849 *flagsp |= 2; /* FAST 4, SLOW 2 */ 1850 /* ??? reduce max_chain_length for binary files */ 1851 1852 G1.strstart = 0; 1853 G1.block_start = 0L; 1854 1855 G1.lookahead = file_read(G1.window, 1856 sizeof(int) <= 2 ? (unsigned) WSIZE : 2 * WSIZE); 1857 1858 if (G1.lookahead == 0 || G1.lookahead == (unsigned) -1) { 1859 G1.eofile = 1; 1860 G1.lookahead = 0; 1861 return; 1862 } 1863 G1.eofile = 0; 1864 /* Make sure that we always have enough lookahead. This is important 1865 * if input comes from a device such as a tty. 1866 */ 1867 while (G1.lookahead < MIN_LOOKAHEAD && !G1.eofile) 1868 fill_window(); 1869 1870 G1.ins_h = 0; 1871 for (j = 0; j < MIN_MATCH - 1; j++) 1872 UPDATE_HASH(G1.ins_h, G1.window[j]); 1873 /* If lookahead < MIN_MATCH, ins_h is garbage, but this is 1874 * not important since only literal bytes will be emitted. 1875 */ 1876 } 1877 1878 1879 /* =========================================================================== 1880 * Allocate the match buffer, initialize the various tables and save the 1881 * location of the internal file attribute (ascii/binary) and method 1882 * (DEFLATE/STORE). 1883 * One callsite in zip() 1884 */ 1885 static void ct_init(void) 1886 { 1887 int n; /* iterates over tree elements */ 1888 int length; /* length value */ 1889 int code; /* code value */ 1890 int dist; /* distance index */ 1891 1892 G2.compressed_len = 0L; 1893 1894 #ifdef NOT_NEEDED 1895 if (G2.static_dtree[0].Len != 0) 1896 return; /* ct_init already called */ 1897 #endif 1898 1899 /* Initialize the mapping length (0..255) -> length code (0..28) */ 1900 length = 0; 1901 for (code = 0; code < LENGTH_CODES - 1; code++) { 1902 G2.base_length[code] = length; 1903 for (n = 0; n < (1 << extra_lbits[code]); n++) { 1904 G2.length_code[length++] = code; 1905 } 1906 } 1907 Assert(length == 256, "ct_init: length != 256"); 1908 /* Note that the length 255 (match length 258) can be represented 1909 * in two different ways: code 284 + 5 bits or code 285, so we 1910 * overwrite length_code[255] to use the best encoding: 1911 */ 1912 G2.length_code[length - 1] = code; 1913 1914 /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ 1915 dist = 0; 1916 for (code = 0; code < 16; code++) { 1917 G2.base_dist[code] = dist; 1918 for (n = 0; n < (1 << extra_dbits[code]); n++) { 1919 G2.dist_code[dist++] = code; 1920 } 1921 } 1922 Assert(dist == 256, "ct_init: dist != 256"); 1923 dist >>= 7; /* from now on, all distances are divided by 128 */ 1924 for (; code < D_CODES; code++) { 1925 G2.base_dist[code] = dist << 7; 1926 for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { 1927 G2.dist_code[256 + dist++] = code; 1928 } 1929 } 1930 Assert(dist == 256, "ct_init: 256+dist != 512"); 1931 1932 /* Construct the codes of the static literal tree */ 1933 /* already zeroed - it's in bss 1934 for (n = 0; n <= MAX_BITS; n++) 1935 G2.bl_count[n] = 0; */ 1936 1937 n = 0; 1938 while (n <= 143) { 1939 G2.static_ltree[n++].Len = 8; 1940 G2.bl_count[8]++; 1941 } 1942 while (n <= 255) { 1943 G2.static_ltree[n++].Len = 9; 1944 G2.bl_count[9]++; 1945 } 1946 while (n <= 279) { 1947 G2.static_ltree[n++].Len = 7; 1948 G2.bl_count[7]++; 1949 } 1950 while (n <= 287) { 1951 G2.static_ltree[n++].Len = 8; 1952 G2.bl_count[8]++; 1953 } 1954 /* Codes 286 and 287 do not exist, but we must include them in the 1955 * tree construction to get a canonical Huffman tree (longest code 1956 * all ones) 1957 */ 1958 gen_codes((ct_data *) G2.static_ltree, L_CODES + 1); 1959 1960 /* The static distance tree is trivial: */ 1961 for (n = 0; n < D_CODES; n++) { 1962 G2.static_dtree[n].Len = 5; 1963 G2.static_dtree[n].Code = bi_reverse(n, 5); 1964 } 1965 1966 /* Initialize the first block of the first file: */ 1967 init_block(); 1968 } 1969 2407 1970 2408 1971 /* =========================================================================== 2409 1972 * Deflate in to out. 2410 1973 * IN assertions: the input and output buffers are cleared. 2411 * The variables time_stamp and save_orig_name are initialized. 2412 */ 2413 static int zip(int in, int out) 2414 { 2415 uch my_flags = 0; /* general purpose bit flags */ 2416 ush attr = 0; /* ascii/binary flag */ 2417 ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ 2418 2419 ifd = in; 2420 ofd = out; 2421 outcnt = 0; 1974 */ 1975 1976 static void zip(ulg time_stamp) 1977 { 1978 ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ 1979 1980 G1.outcnt = 0; 2422 1981 2423 1982 /* Write the header to the gzip file. See algorithm.doc for the format */ 2424 2425 2426 method = DEFLATED; 2427 put_header_byte(GZIP_MAGIC[0]); /* magic header */ 2428 put_header_byte(GZIP_MAGIC[1]); 2429 put_header_byte(DEFLATED); /* compression method */ 2430 2431 put_header_byte(my_flags); /* general flags */ 2432 put_long(time_stamp); 1983 /* magic header for gzip files: 1F 8B */ 1984 /* compression method: 8 (DEFLATED) */ 1985 /* general flags: 0 */ 1986 put_32bit(0x00088b1f); 1987 put_32bit(time_stamp); 2433 1988 2434 1989 /* Write deflated file to zip file */ 2435 crc = updcrc(0, 0);2436 2437 bi_init( out);2438 ct_init( &attr, &method);1990 G1.crc = ~0; 1991 1992 bi_init(); 1993 ct_init(); 2439 1994 lm_init(&deflate_flags); 2440 1995 2441 put_byte((uch) deflate_flags); /* extra flags */ 2442 put_byte(OS_CODE); /* OS identifier */ 2443 2444 header_bytes = (long) outcnt; 2445 2446 (void) deflate(); 1996 put_8bit(deflate_flags); /* extra flags */ 1997 put_8bit(3); /* OS identifier = 3 (Unix) */ 1998 1999 deflate(); 2447 2000 2448 2001 /* Write the crc and uncompressed size */ 2449 put_long(crc); 2450 put_long(isize); 2451 header_bytes += 2 * sizeof(long); 2002 put_32bit(~G1.crc); 2003 put_32bit(G1.isize); 2452 2004 2453 2005 flush_outbuf(); 2454 return OK; 2455 } 2456 2457 2458 /* =========================================================================== 2459 * Read a new buffer from the current input file, perform end-of-line 2460 * translation, and update the crc and input file size. 2461 * IN assertion: size >= 2 (for end-of-line translation) 2462 */ 2463 static int file_read(char *buf, unsigned size) 2464 { 2465 unsigned len; 2466 2467 Assert(insize == 0, "inbuf not empty"); 2468 2469 len = read(ifd, buf, size); 2470 if (len == (unsigned) (-1) || len == 0) 2471 return (int) len; 2472 2473 crc = updcrc((uch *) buf, len); 2474 isize += (ulg) len; 2475 return (int) len; 2476 } 2477 2478 /* =========================================================================== 2479 * Write the output buffer outbuf[0..outcnt-1] and update bytes_out. 2480 * (used for the compressed data only) 2481 */ 2482 static void flush_outbuf(void) 2483 { 2484 if (outcnt == 0) 2485 return; 2486 2487 write_buf(ofd, (char *) outbuf, outcnt); 2488 outcnt = 0; 2489 } 2006 } 2007 2008 2009 /* ======================================================================== */ 2010 static 2011 char* make_new_name_gzip(char *filename) 2012 { 2013 return xasprintf("%s.gz", filename); 2014 } 2015 2016 static 2017 USE_DESKTOP(long long) int pack_gzip(void) 2018 { 2019 struct stat s; 2020 2021 clear_bufs(); 2022 s.st_ctime = 0; 2023 fstat(STDIN_FILENO, &s); 2024 zip(s.st_ctime); 2025 return 0; 2026 } 2027 2028 int gzip_main(int argc, char **argv); 2029 int gzip_main(int argc, char **argv) 2030 { 2031 unsigned opt; 2032 2033 /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ 2034 opt = getopt32(argv, "cfv" USE_GUNZIP("d") "q123456789" ); 2035 option_mask32 &= 0x7; /* Clear -d, ignore -q, -0..9 */ 2036 //if (opt & 0x1) // -c 2037 //if (opt & 0x2) // -f 2038 //if (opt & 0x4) // -v 2039 #if ENABLE_GUNZIP /* gunzip_main may not be visible... */ 2040 if (opt & 0x8) { // -d 2041 return gunzip_main(argc, argv); 2042 } 2043 #endif 2044 argv += optind; 2045 2046 PTR_TO_GLOBALS = xzalloc(sizeof(struct globals) + sizeof(struct globals2)) 2047 + sizeof(struct globals); 2048 G2.l_desc.dyn_tree = G2.dyn_ltree; 2049 G2.l_desc.static_tree = G2.static_ltree; 2050 G2.l_desc.extra_bits = extra_lbits; 2051 G2.l_desc.extra_base = LITERALS + 1; 2052 G2.l_desc.elems = L_CODES; 2053 G2.l_desc.max_length = MAX_BITS; 2054 //G2.l_desc.max_code = 0; 2055 2056 G2.d_desc.dyn_tree = G2.dyn_dtree; 2057 G2.d_desc.static_tree = G2.static_dtree; 2058 G2.d_desc.extra_bits = extra_dbits; 2059 //G2.d_desc.extra_base = 0; 2060 G2.d_desc.elems = D_CODES; 2061 G2.d_desc.max_length = MAX_BITS; 2062 //G2.d_desc.max_code = 0; 2063 2064 G2.bl_desc.dyn_tree = G2.bl_tree; 2065 //G2.bl_desc.static_tree = NULL; 2066 G2.bl_desc.extra_bits = extra_blbits, 2067 //G2.bl_desc.extra_base = 0; 2068 G2.bl_desc.elems = BL_CODES; 2069 G2.bl_desc.max_length = MAX_BL_BITS; 2070 //G2.bl_desc.max_code = 0; 2071 2072 /* Allocate all global buffers (for DYN_ALLOC option) */ 2073 ALLOC(uch, G1.l_buf, INBUFSIZ); 2074 ALLOC(uch, G1.outbuf, OUTBUFSIZ); 2075 ALLOC(ush, G1.d_buf, DIST_BUFSIZE); 2076 ALLOC(uch, G1.window, 2L * WSIZE); 2077 ALLOC(ush, G1.prev, 1L << BITS); 2078 2079 /* Initialise the CRC32 table */ 2080 G1.crc_32_tab = crc32_filltable(NULL, 0); 2081 2082 return bbunpack(argv, make_new_name_gzip, pack_gzip); 2083 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/archive_xread_all_eof.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU Library General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 15 4 */ 16 5 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 6 #include "libbb.h" 20 7 #include "unarchive.h" 21 #include "libbb.h"22 8 23 ssize_t archive_xread_all_eof(archive_handle_t *archive_handle, unsigned char *buf, size_t count) 9 ssize_t archive_xread_all_eof(archive_handle_t *archive_handle, 10 unsigned char *buf, size_t count) 24 11 { 25 12 ssize_t size; 26 13 27 size = bb_full_read(archive_handle->src_fd, buf, count); 28 if ((size != 0) && (size != count)) { 29 bb_perror_msg_and_die("Short read, read %ld of %ld", (long)size, (long)count); 14 size = full_read(archive_handle->src_fd, buf, count); 15 if (size != 0 && size != count) { 16 bb_error_msg_and_die("short read: %u of %u", 17 (unsigned)size, (unsigned)count); 30 18 } 31 return (size);19 return size; 32 20 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/check_header_gzip.c
r821 r1765 1 #include <stdlib.h> 2 #include <unistd.h> 1 /* vi: set sw=4 ts=4: */ 2 /* 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 4 */ 5 3 6 #include "libbb.h" 4 #include "unarchive.h" /* for external decl of check_header_gzip */7 #include "unarchive.h" /* for external decl of check_header_gzip_or_die */ 5 8 6 void check_header_gzip (int src_fd)9 void check_header_gzip_or_die(int src_fd) 7 10 { 8 11 union { … … 14 17 unsigned char xtra_flags; 15 18 unsigned char os_flags; 16 } format ed;19 } formatted; 17 20 } header; 18 21 19 bb_xread_all(src_fd, header.raw, 8);22 xread(src_fd, header.raw, 8); 20 23 21 24 /* Check the compression method */ 22 if (header.format ed.method != 8) {23 bb_error_msg_and_die(" Unknown compression method %d",24 header.format ed.method);25 if (header.formatted.method != 8) { 26 bb_error_msg_and_die("unknown compression method %d", 27 header.formatted.method); 25 28 } 26 29 27 if (header.format ed.flags & 0x04) {30 if (header.formatted.flags & 0x04) { 28 31 /* bit 2 set: extra field present */ 29 unsigned charextra_short;32 unsigned extra_short; 30 33 31 extra_short = bb_xread_char(src_fd) + (bb_xread_char(src_fd) << 8);34 extra_short = xread_char(src_fd) + (xread_char(src_fd) << 8); 32 35 while (extra_short > 0) { 33 36 /* Ignore extra field */ 34 bb_xread_char(src_fd);37 xread_char(src_fd); 35 38 extra_short--; 36 39 } … … 38 41 39 42 /* Discard original name if any */ 40 if (header.format ed.flags & 0x08) {43 if (header.formatted.flags & 0x08) { 41 44 /* bit 3 set: original file name present */ 42 while (bb_xread_char(src_fd) != 0);45 while (xread_char(src_fd) != 0); 43 46 } 44 47 45 48 /* Discard file comment if any */ 46 if (header.format ed.flags & 0x10) {49 if (header.formatted.flags & 0x10) { 47 50 /* bit 4 set: file comment present */ 48 while (bb_xread_char(src_fd) != 0);51 while (xread_char(src_fd) != 0); 49 52 } 50 53 51 54 /* Read the header checksum */ 52 if (header.format ed.flags & 0x02) {53 bb_xread_char(src_fd);54 bb_xread_char(src_fd);55 if (header.formatted.flags & 0x02) { 56 xread_char(src_fd); 57 xread_char(src_fd); 55 58 } 56 57 return;58 59 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/data_align.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 15 4 */ 16 5 17 #include <sys/types.h> 18 19 #include <errno.h> 20 #include <unistd.h> 6 //#include <sys/types.h> 21 7 22 8 #include "libbb.h" … … 29 15 archive_handle->seek(archive_handle, skip_amount); 30 16 archive_handle->offset += skip_amount; 31 32 return;33 17 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/data_extract_all.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 15 4 */ 16 17 #include <sys/types.h>18 19 #include <errno.h>20 #include <fcntl.h>21 #include <stdlib.h>22 #include <string.h>23 #include <utime.h>24 #include <unistd.h>25 #include <stdlib.h>26 5 27 6 #include "libbb.h" … … 35 14 36 15 if (archive_handle->flags & ARCHIVE_CREATE_LEADING_DIRS) { 37 char *name = bb_xstrdup(file_header->name);38 bb_make_directory 16 char *name = xstrdup(file_header->name); 17 bb_make_directory(dirname(name), -1, FILEUTILS_RECUR); 39 18 free(name); 40 19 } … … 43 22 if (archive_handle->flags & ARCHIVE_EXTRACT_UNCONDITIONAL) { 44 23 /* Remove the existing entry if it exists */ 45 if (((file_header->mode & S_IFMT) != S_IFDIR) && (unlink(file_header->name) == -1) && (errno != ENOENT)) { 46 bb_perror_msg_and_die("Couldnt remove old file"); 24 if (((file_header->mode & S_IFMT) != S_IFDIR) 25 && (unlink(file_header->name) == -1) 26 && (errno != ENOENT) 27 ) { 28 bb_perror_msg_and_die("cannot remove old file %s", 29 file_header->name); 47 30 } 48 31 } … … 52 35 if (lstat(file_header->name, &statbuf) == -1) { 53 36 if (errno != ENOENT) { 54 bb_perror_msg_and_die(" Couldnt stat old file");37 bb_perror_msg_and_die("cannot stat old file"); 55 38 } 56 39 } 57 40 else if (statbuf.st_mtime <= file_header->mtime) { 58 41 if (!(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { 59 bb_error_msg("%s not created: newer or same age file exists", file_header->name); 42 bb_error_msg("%s not created: newer or " 43 "same age file exists", file_header->name); 60 44 } 61 45 data_skip(archive_handle); … … 63 47 } 64 48 else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) { 65 bb_perror_msg_and_die("Couldnt remove old file %s", file_header->name); 49 bb_perror_msg_and_die("cannot remove old file %s", 50 file_header->name); 66 51 } 67 52 } … … 69 54 /* Handle hard links separately 70 55 * We identified hard links as regular files of size 0 with a symlink */ 71 if (S_ISREG(file_header->mode) && (file_header->link_name) && (file_header->size == 0)) { 56 if (S_ISREG(file_header->mode) && (file_header->link_target) 57 && (file_header->size == 0) 58 ) { 72 59 /* hard link */ 73 res = link(file_header->link_ name, file_header->name);60 res = link(file_header->link_target, file_header->name); 74 61 if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { 75 bb_perror_msg("Couldnt create hard link"); 62 bb_perror_msg("cannot create %slink " 63 "from %s to %s", "hard", 64 file_header->name, 65 file_header->link_target); 76 66 } 77 67 } else { 78 68 /* Create the filesystem entry */ 79 switch(file_header->mode & S_IFMT) { 80 case S_IFREG: { 81 /* Regular file */ 82 dst_fd = bb_xopen(file_header->name, O_WRONLY | O_CREAT | O_EXCL); 83 bb_copyfd_size(archive_handle->src_fd, dst_fd, file_header->size); 84 close(dst_fd); 85 break; 86 } 87 case S_IFDIR: 88 res = mkdir(file_header->name, file_header->mode); 89 if ((errno != EISDIR) && (res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { 90 bb_perror_msg("extract_archive: %s", file_header->name); 91 } 92 break; 93 case S_IFLNK: 94 /* Symlink */ 95 res = symlink(file_header->link_name, file_header->name); 96 if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { 97 bb_perror_msg("Cannot create symlink from %s to '%s'", file_header->name, file_header->link_name); 98 } 99 break; 100 case S_IFSOCK: 101 case S_IFBLK: 102 case S_IFCHR: 103 case S_IFIFO: 104 res = mknod(file_header->name, file_header->mode, file_header->device); 105 if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { 106 bb_perror_msg("Cannot create node %s", file_header->name); 107 } 108 break; 109 default: 110 bb_error_msg_and_die("Unrecognised file type"); 69 switch (file_header->mode & S_IFMT) { 70 case S_IFREG: { 71 /* Regular file */ 72 dst_fd = xopen3(file_header->name, O_WRONLY | O_CREAT | O_EXCL, 73 file_header->mode); 74 bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size); 75 close(dst_fd); 76 break; 77 } 78 case S_IFDIR: 79 res = mkdir(file_header->name, file_header->mode); 80 if ((res == -1) && (errno != EISDIR) 81 && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET) 82 ) { 83 bb_perror_msg("cannot make dir %s", file_header->name); 84 } 85 break; 86 case S_IFLNK: 87 /* Symlink */ 88 res = symlink(file_header->link_target, file_header->name); 89 if ((res == -1) 90 && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET) 91 ) { 92 bb_perror_msg("cannot create %slink " 93 "from %s to %s", "sym", 94 file_header->name, 95 file_header->link_target); 96 } 97 break; 98 case S_IFSOCK: 99 case S_IFBLK: 100 case S_IFCHR: 101 case S_IFIFO: 102 res = mknod(file_header->name, file_header->mode, file_header->device); 103 if ((res == -1) 104 && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET) 105 ) { 106 bb_perror_msg("cannot create node %s", file_header->name); 107 } 108 break; 109 default: 110 bb_error_msg_and_die("unrecognized file type"); 111 111 } 112 112 } … … 115 115 lchown(file_header->name, file_header->uid, file_header->gid); 116 116 } 117 if (!(archive_handle->flags & ARCHIVE_NOPRESERVE_PERM) && 118 (file_header->mode & S_IFMT) != S_IFLNK) 119 { 120 chmod(file_header->name, file_header->mode); 121 } 122 123 if (archive_handle->flags & ARCHIVE_PRESERVE_DATE) { 124 struct utimbuf t; 125 t.actime = t.modtime = file_header->mtime; 126 utime(file_header->name, &t); 117 if ((file_header->mode & S_IFMT) != S_IFLNK) { 118 /* uclibc has no lchmod, glibc is even stranger - 119 * it has lchmod which seems to do nothing! 120 * so we use chmod... */ 121 if (!(archive_handle->flags & ARCHIVE_NOPRESERVE_PERM)) { 122 chmod(file_header->name, file_header->mode); 123 } 124 /* same for utime */ 125 if (archive_handle->flags & ARCHIVE_PRESERVE_DATE) { 126 struct utimbuf t; 127 t.actime = t.modtime = file_header->mtime; 128 utime(file_header->name, &t); 129 } 127 130 } 128 131 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/data_extract_to_buffer.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * Copyright 2002 Glenn McGrath … … 10 11 void data_extract_to_buffer(archive_handle_t *archive_handle) 11 12 { 12 constunsigned int size = archive_handle->file_header->size;13 unsigned int size = archive_handle->file_header->size; 13 14 14 15 archive_handle->buffer = xzalloc(size + 1); 15 16 archive_xread_all(archive_handle, archive_handle->buffer, size); 16 xread(archive_handle->src_fd, archive_handle->buffer, size); 17 17 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/data_extract_to_stdout.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 15 4 */ 16 5 6 #include "libbb.h" 17 7 #include "unarchive.h" 18 #include <unistd.h>19 8 20 9 void data_extract_to_stdout(archive_handle_t *archive_handle) 21 10 { 22 bb_copyfd_size(archive_handle->src_fd, STDOUT_FILENO, archive_handle->file_header->size); 11 bb_copyfd_exact_size(archive_handle->src_fd, 12 STDOUT_FILENO, 13 archive_handle->file_header->size); 23 14 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/data_skip.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 15 4 */ 16 5 17 #include <sys/types.h> 18 #include <errno.h> 19 #include <unistd.h> 20 #include <stdlib.h> 6 #include "libbb.h" 21 7 #include "unarchive.h" 22 #include "libbb.h"23 8 24 9 void data_skip(archive_handle_t *archive_handle) -
branches/2.2.5/mindi-busybox/archival/libunarchive/decompress_bunzip2.c
r821 r1765 29 29 */ 30 30 31 #include <setjmp.h>32 #include <stdio.h>33 #include <stdlib.h>34 #include <string.h>35 #include <unistd.h>36 #include <limits.h>37 38 31 #include "libbb.h" 39 40 32 #include "unarchive.h" 41 33 42 34 /* Constants for Huffman coding */ 43 #define MAX_GROUPS 44 #define GROUP_SIZE 50/* 64 would have been more efficient */45 #define MAX_HUFCODE_BITS 20/* Longest Huffman code allowed */46 #define MAX_SYMBOLS 258/* 256 literals + RUNA + RUNB */47 #define SYMBOL_RUNA 48 #define SYMBOL_RUNB 35 #define MAX_GROUPS 6 36 #define GROUP_SIZE 50 /* 64 would have been more efficient */ 37 #define MAX_HUFCODE_BITS 20 /* Longest Huffman code allowed */ 38 #define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */ 39 #define SYMBOL_RUNA 0 40 #define SYMBOL_RUNB 1 49 41 50 42 /* Status return values */ 51 #define RETVAL_OK 52 #define RETVAL_LAST_BLOCK 53 #define RETVAL_NOT_BZIP_DATA 54 #define RETVAL_UNEXPECTED_INPUT_EOF 55 #define RETVAL_UNEXPECTED_OUTPUT_EOF 56 #define RETVAL_DATA_ERROR 57 #define RETVAL_OUT_OF_MEMORY 58 #define RETVAL_OBSOLETE_INPUT 43 #define RETVAL_OK 0 44 #define RETVAL_LAST_BLOCK (-1) 45 #define RETVAL_NOT_BZIP_DATA (-2) 46 #define RETVAL_UNEXPECTED_INPUT_EOF (-3) 47 #define RETVAL_UNEXPECTED_OUTPUT_EOF (-4) 48 #define RETVAL_DATA_ERROR (-5) 49 #define RETVAL_OUT_OF_MEMORY (-6) 50 #define RETVAL_OBSOLETE_INPUT (-7) 59 51 60 52 /* Other housekeeping constants */ 61 #define IOBUF_SIZE 53 #define IOBUF_SIZE 4096 62 54 63 55 /* This is what we know about each Huffman coding group */ 64 56 struct group_data { 65 57 /* We have an extra slot at the end of limit[] for a sentinal value. */ 66 int limit[MAX_HUFCODE_BITS+1], base[MAX_HUFCODE_BITS],permute[MAX_SYMBOLS];58 int limit[MAX_HUFCODE_BITS+1], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS]; 67 59 int minLen, maxLen; 68 60 }; … … 71 63 memory that persists between calls to bunzip */ 72 64 73 typedef struct{65 struct bunzip_data { 74 66 /* State for interrupting output loop */ 75 76 int writeCopies,writePos,writeRunCountdown,writeCount,writeCurrent; 67 int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent; 77 68 78 69 /* I/O tracking data (file handles, buffers, positions, etc.) */ 79 80 int in_fd,out_fd,inbufCount,inbufPos /*,outbufPos*/; 70 int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/; 81 71 unsigned char *inbuf /*,*outbuf*/; 82 unsigned in t inbufBitCount, inbufBits;72 unsigned inbufBitCount, inbufBits; 83 73 84 74 /* The CRC values stored in the block header and calculated from the data */ 85 86 75 uint32_t headerCRC, totalCRC, writeCRC; 87 uint32_t *crc32Table; 76 88 77 /* Intermediate buffer and its size (in bytes) */ 89 90 unsigned int *dbuf, dbufSize; 91 92 /* These things are a bit too big to go on the stack */ 93 78 unsigned *dbuf, dbufSize; 79 80 /* For I/O error handling */ 81 jmp_buf jmpbuf; 82 83 /* Big things go last (register-relative addressing can be larger for big offsets */ 84 uint32_t crc32Table[256]; 94 85 unsigned char selectors[32768]; /* nSelectors=15 bits */ 95 86 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ 96 97 /* For I/O error handling */ 98 99 jmp_buf jmpbuf; 100 } bunzip_data; 87 }; 88 /* typedef struct bunzip_data bunzip_data; -- done in .h file */ 89 101 90 102 91 /* Return the next nnn bits of input. All reads from the compressed input 103 92 are done through this function. All reads are big endian */ 104 93 105 static unsigned intget_bits(bunzip_data *bd, char bits_wanted)94 static unsigned get_bits(bunzip_data *bd, char bits_wanted) 106 95 { 107 unsigned int bits=0;96 unsigned bits = 0; 108 97 109 98 /* If we need to get more data from the byte buffer, do so. (Loop getting 110 99 one byte at a time to enforce endianness and avoid unaligned access.) */ 111 100 112 while (bd->inbufBitCount <bits_wanted) {101 while (bd->inbufBitCount < bits_wanted) { 113 102 114 103 /* If we need to read more data from file into byte buffer, do so */ 115 104 116 if(bd->inbufPos==bd->inbufCount) { 117 if((bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE)) <= 0) 118 longjmp(bd->jmpbuf,RETVAL_UNEXPECTED_INPUT_EOF); 119 bd->inbufPos=0; 105 if (bd->inbufPos == bd->inbufCount) { 106 /* if "no input fd" case: in_fd == -1, read fails, we jump */ 107 bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE); 108 if (bd->inbufCount <= 0) 109 longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF); 110 bd->inbufPos = 0; 120 111 } 121 112 122 113 /* Avoid 32-bit overflow (dump bit buffer to top of output) */ 123 114 124 if (bd->inbufBitCount>=24) {125 bits =bd->inbufBits&((1<<bd->inbufBitCount)-1);126 bits_wanted -=bd->inbufBitCount;127 bits <<=bits_wanted;128 bd->inbufBitCount =0;115 if (bd->inbufBitCount >= 24) { 116 bits = bd->inbufBits & ((1 << bd->inbufBitCount) - 1); 117 bits_wanted -= bd->inbufBitCount; 118 bits <<= bits_wanted; 119 bd->inbufBitCount = 0; 129 120 } 130 121 131 122 /* Grab next 8 bits of input from buffer. */ 132 123 133 bd->inbufBits =(bd->inbufBits<<8)|bd->inbuf[bd->inbufPos++];134 bd->inbufBitCount +=8;124 bd->inbufBits = (bd->inbufBits<<8) | bd->inbuf[bd->inbufPos++]; 125 bd->inbufBitCount += 8; 135 126 } 136 127 137 128 /* Calculate result */ 138 129 139 bd->inbufBitCount -=bits_wanted;140 bits |=(bd->inbufBits>>bd->inbufBitCount)&((1<<bits_wanted)-1);130 bd->inbufBitCount -= bits_wanted; 131 bits |= (bd->inbufBits >> bd->inbufBitCount) & ((1 << bits_wanted) - 1); 141 132 142 133 return bits; … … 148 139 { 149 140 struct group_data *hufGroup; 150 int dbufCount, nextSym,dbufSize,groupCount,*base,*limit,selector,151 i, j,k,t,runPos,symCount,symTotal,nSelectors,byteCount[256];141 int dbufCount, nextSym, dbufSize, groupCount, *base, *limit, selector, 142 i, j, k, t, runPos, symCount, symTotal, nSelectors, byteCount[256]; 152 143 unsigned char uc, symToByte[256], mtfSymbol[256], *selectors; 153 unsigned int *dbuf,origPtr;154 155 dbuf =bd->dbuf;156 dbufSize =bd->dbufSize;157 selectors =bd->selectors;144 unsigned *dbuf, origPtr; 145 146 dbuf = bd->dbuf; 147 dbufSize = bd->dbufSize; 148 selectors = bd->selectors; 158 149 159 150 /* Reset longjmp I/O error handling */ 160 151 161 i =setjmp(bd->jmpbuf);162 if (i) return i;152 i = setjmp(bd->jmpbuf); 153 if (i) return i; 163 154 164 155 /* Read in header signature and CRC, then validate signature. 165 156 (last block signature means CRC is for whole file, return now) */ 166 157 167 i = get_bits(bd, 24);168 j = get_bits(bd, 24);169 bd->headerCRC =get_bits(bd,32);158 i = get_bits(bd, 24); 159 j = get_bits(bd, 24); 160 bd->headerCRC = get_bits(bd, 32); 170 161 if ((i == 0x177245) && (j == 0x385090)) return RETVAL_LAST_BLOCK; 171 162 if ((i != 0x314159) || (j != 0x265359)) return RETVAL_NOT_BZIP_DATA; … … 175 166 it didn't actually work. */ 176 167 177 if(get_bits(bd,1)) return RETVAL_OBSOLETE_INPUT; 178 if((origPtr=get_bits(bd,24)) > dbufSize) return RETVAL_DATA_ERROR; 168 if (get_bits(bd, 1)) return RETVAL_OBSOLETE_INPUT; 169 origPtr = get_bits(bd, 24); 170 if (origPtr > dbufSize) return RETVAL_DATA_ERROR; 179 171 180 172 /* mapping table: if some byte values are never used (encoding things … … 184 176 back to the corresponding bytes. */ 185 177 186 t=get_bits(bd, 16); 187 symTotal=0; 188 for (i=0;i<16;i++) { 189 if(t&(1<<(15-i))) { 190 k=get_bits(bd,16); 191 for(j=0;j<16;j++) 192 if(k&(1<<(15-j))) symToByte[symTotal++]=(16*i)+j; 178 t = get_bits(bd, 16); 179 symTotal = 0; 180 for (i = 0; i < 16; i++) { 181 if (t & (1 << (15-i))) { 182 k = get_bits(bd, 16); 183 for (j = 0; j < 16; j++) 184 if (k & (1 << (15-j))) 185 symToByte[symTotal++] = (16*i) + j; 193 186 } 194 187 } … … 196 189 /* How many different Huffman coding groups does this block use? */ 197 190 198 groupCount=get_bits(bd,3); 199 if (groupCount<2 || groupCount>MAX_GROUPS) return RETVAL_DATA_ERROR; 191 groupCount = get_bits(bd, 3); 192 if (groupCount < 2 || groupCount > MAX_GROUPS) 193 return RETVAL_DATA_ERROR; 200 194 201 195 /* nSelectors: Every GROUP_SIZE many symbols we select a new Huffman coding … … 204 198 start of the list.) */ 205 199 206 if(!(nSelectors=get_bits(bd, 15))) return RETVAL_DATA_ERROR; 207 for(i=0; i<groupCount; i++) mtfSymbol[i] = i; 208 for(i=0; i<nSelectors; i++) { 200 nSelectors = get_bits(bd, 15); 201 if (!nSelectors) return RETVAL_DATA_ERROR; 202 for (i = 0; i < groupCount; i++) mtfSymbol[i] = i; 203 for (i = 0; i < nSelectors; i++) { 209 204 210 205 /* Get next value */ 211 206 212 for(j=0;get_bits(bd,1);j++) if (j>=groupCount) return RETVAL_DATA_ERROR; 207 for (j = 0; get_bits(bd, 1); j++) 208 if (j>=groupCount) return RETVAL_DATA_ERROR; 213 209 214 210 /* Decode MTF to get the next selector */ 215 211 216 212 uc = mtfSymbol[j]; 217 for (;j;j--) mtfSymbol[j] = mtfSymbol[j-1];218 mtfSymbol[0] =selectors[i]=uc;213 for (;j;j--) mtfSymbol[j] = mtfSymbol[j-1]; 214 mtfSymbol[0] = selectors[i] = uc; 219 215 } 220 216 … … 222 218 literal symbols, plus two run symbols (RUNA, RUNB) */ 223 219 224 symCount =symTotal+2;225 for (j =0; j<groupCount; j++) {226 unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1];227 int minLen,maxLen, pp;220 symCount = symTotal + 2; 221 for (j = 0; j < groupCount; j++) { 222 unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1]; 223 int minLen, maxLen, pp; 228 224 229 225 /* Read Huffman code lengths for each symbol. They're stored in … … 234 230 length 0 becomes negative, so an unsigned inequality catches it.) */ 235 231 236 t =get_bits(bd, 5)-1;232 t = get_bits(bd, 5) - 1; 237 233 for (i = 0; i < symCount; i++) { 238 for (;;) {239 if (( (unsigned)t)> (MAX_HUFCODE_BITS-1))234 for (;;) { 235 if ((unsigned)t > (MAX_HUFCODE_BITS-1)) 240 236 return RETVAL_DATA_ERROR; 241 237 … … 244 240 bits and unget the second if the first was 0. */ 245 241 246 k = get_bits(bd, 2);242 k = get_bits(bd, 2); 247 243 if (k < 2) { 248 244 bd->inbufBitCount++; … … 252 248 /* Add one if second bit 1, else subtract 1. Avoids if/else */ 253 249 254 t +=(((k+1)&2)-1);250 t += (((k+1) & 2) - 1); 255 251 } 256 252 257 253 /* Correct for the initial -1, to get the final symbol length */ 258 254 259 length[i] =t+1;255 length[i] = t + 1; 260 256 } 261 257 262 258 /* Find largest and smallest lengths in this group */ 263 259 264 minLen =maxLen=length[0];265 for (i = 1; i < symCount; i++) {266 if (length[i] > maxLen) maxLen = length[i];267 else if (length[i] < minLen) minLen = length[i];260 minLen = maxLen = length[0]; 261 for (i = 1; i < symCount; i++) { 262 if (length[i] > maxLen) maxLen = length[i]; 263 else if (length[i] < minLen) minLen = length[i]; 268 264 } 269 265 … … 279 275 */ 280 276 281 hufGroup =bd->groups+j;277 hufGroup = bd->groups + j; 282 278 hufGroup->minLen = minLen; 283 279 hufGroup->maxLen = maxLen; … … 287 283 entry. We do this again when using them (during symbol decoding).*/ 288 284 289 base =hufGroup->base-1;290 limit =hufGroup->limit-1;285 base = hufGroup->base - 1; 286 limit = hufGroup->limit - 1; 291 287 292 288 /* Calculate permute[]. Concurently, initialize temp[] and limit[]. */ 293 289 294 pp=0; 295 for(i=minLen;i<=maxLen;i++) { 296 temp[i]=limit[i]=0; 297 for(t=0;t<symCount;t++) 298 if(length[t]==i) hufGroup->permute[pp++] = t; 290 pp = 0; 291 for (i = minLen; i <= maxLen; i++) { 292 temp[i] = limit[i] = 0; 293 for (t = 0; t < symCount; t++) 294 if (length[t] == i) 295 hufGroup->permute[pp++] = t; 299 296 } 300 297 301 298 /* Count symbols coded for at each bit length */ 302 299 303 for (i =0;i<symCount;i++) temp[length[i]]++;300 for (i = 0; i < symCount; i++) temp[length[i]]++; 304 301 305 302 /* Calculate limit[] (the largest symbol-coding value at each bit … … 308 305 * limit minus the cumulative count of symbols coded for already). */ 309 306 310 pp =t=0;311 for (i =minLen; i<maxLen; i++) {312 pp +=temp[i];307 pp = t = 0; 308 for (i = minLen; i < maxLen; i++) { 309 pp += temp[i]; 313 310 314 311 /* We read the largest possible symbol size and then unget bits … … 319 316 don't affect the value>limit[length] comparison. */ 320 317 321 limit[i]= (pp << (maxLen - i)) - 1; 322 pp<<=1; 323 base[i+1]=pp-(t+=temp[i]); 318 limit[i] = (pp << (maxLen - i)) - 1; 319 pp <<= 1; 320 t += temp[i]; 321 base[i+1] = pp - t; 324 322 } 325 323 limit[maxLen+1] = INT_MAX; /* Sentinal value for reading next sym. */ 326 limit[maxLen] =pp+temp[maxLen]-1;327 base[minLen] =0;324 limit[maxLen] = pp + temp[maxLen] - 1; 325 base[minLen] = 0; 328 326 } 329 327 … … 334 332 /* Initialize symbol occurrence counters and symbol Move To Front table */ 335 333 336 for (i=0;i<256;i++) {334 for (i = 0; i < 256; i++) { 337 335 byteCount[i] = 0; 338 mtfSymbol[i] =(unsigned char)i;336 mtfSymbol[i] = (unsigned char)i; 339 337 } 340 338 341 339 /* Loop through compressed symbols. */ 342 340 343 runPos =dbufCount=selector=0;344 for (;;) {341 runPos = dbufCount = selector = 0; 342 for (;;) { 345 343 346 344 /* fetch next Huffman coding group from list. */ 347 345 348 symCount =GROUP_SIZE-1;349 if (selector>=nSelectors) return RETVAL_DATA_ERROR;350 hufGroup =bd->groups+selectors[selector++];351 base =hufGroup->base-1;352 limit =hufGroup->limit-1;353 continue_this_group:346 symCount = GROUP_SIZE - 1; 347 if (selector >= nSelectors) return RETVAL_DATA_ERROR; 348 hufGroup = bd->groups + selectors[selector++]; 349 base = hufGroup->base - 1; 350 limit = hufGroup->limit - 1; 351 continue_this_group: 354 352 355 353 /* Read next Huffman-coded symbol. */ … … 362 360 inline (falling back to a call to get_bits if the buffer runs 363 361 dry). The following (up to got_huff_bits:) is equivalent to 364 j =get_bits(bd,hufGroup->maxLen);362 j = get_bits(bd, hufGroup->maxLen); 365 363 */ 366 364 367 while (bd->inbufBitCount <hufGroup->maxLen) {368 if (bd->inbufPos==bd->inbufCount) {369 j = get_bits(bd, hufGroup->maxLen);365 while (bd->inbufBitCount < hufGroup->maxLen) { 366 if (bd->inbufPos == bd->inbufCount) { 367 j = get_bits(bd, hufGroup->maxLen); 370 368 goto got_huff_bits; 371 369 } 372 bd->inbufBits =(bd->inbufBits<<8)|bd->inbuf[bd->inbufPos++];373 bd->inbufBitCount +=8;370 bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++]; 371 bd->inbufBitCount += 8; 374 372 }; 375 bd->inbufBitCount -=hufGroup->maxLen;376 j = (bd->inbufBits >>bd->inbufBitCount)&((1<<hufGroup->maxLen)-1);377 378 got_huff_bits:373 bd->inbufBitCount -= hufGroup->maxLen; 374 j = (bd->inbufBits >> bd->inbufBitCount) & ((1 << hufGroup->maxLen) - 1); 375 376 got_huff_bits: 379 377 380 378 /* Figure how how many bits are in next symbol and unget extras */ 381 379 382 i =hufGroup->minLen;383 while (j>limit[i]) ++i;380 i = hufGroup->minLen; 381 while (j > limit[i]) ++i; 384 382 bd->inbufBitCount += (hufGroup->maxLen - i); 385 383 386 384 /* Huffman decode value to get nextSym (with bounds checking) */ 387 385 388 if ((i > hufGroup->maxLen) 389 || (((unsigned)(j=(j>>(hufGroup->maxLen-i))-base[i])) 390 >= MAX_SYMBOLS)) 386 if (i > hufGroup->maxLen) 387 return RETVAL_DATA_ERROR; 388 j = (j >> (hufGroup->maxLen - i)) - base[i]; 389 if ((unsigned)j >= MAX_SYMBOLS) 391 390 return RETVAL_DATA_ERROR; 392 391 nextSym = hufGroup->permute[j]; … … 397 396 how many times to repeat the last literal. */ 398 397 399 if (( (unsigned)nextSym)<= SYMBOL_RUNB) { /* RUNA or RUNB */398 if ((unsigned)nextSym <= SYMBOL_RUNB) { /* RUNA or RUNB */ 400 399 401 400 /* If this is the start of a new run, zero out counter */ 402 401 403 if (!runPos) {402 if (!runPos) { 404 403 runPos = 1; 405 404 t = 0; … … 415 414 416 415 t += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */ 417 if (runPos < dbufSize) runPos <<= 1;416 if (runPos < dbufSize) runPos <<= 1; 418 417 goto end_of_huffman_loop; 419 418 } … … 424 423 literal used is the one at the head of the mtfSymbol array.) */ 425 424 426 if (runPos) {427 runPos =0;428 if (dbufCount+t>=dbufSize) return RETVAL_DATA_ERROR;425 if (runPos) { 426 runPos = 0; 427 if (dbufCount + t >= dbufSize) return RETVAL_DATA_ERROR; 429 428 430 429 uc = symToByte[mtfSymbol[0]]; 431 430 byteCount[uc] += t; 432 while (t--) dbuf[dbufCount++]=uc;431 while (t--) dbuf[dbufCount++] = uc; 433 432 } 434 433 435 434 /* Is this the terminating symbol? */ 436 435 437 if (nextSym>symTotal) break;436 if (nextSym > symTotal) break; 438 437 439 438 /* At this point, nextSym indicates a new literal character. Subtract … … 445 444 2 non-literal nextSym values equals -1.) */ 446 445 447 if (dbufCount>=dbufSize) return RETVAL_DATA_ERROR;446 if (dbufCount >= dbufSize) return RETVAL_DATA_ERROR; 448 447 i = nextSym - 1; 449 448 uc = mtfSymbol[i]; … … 458 457 } while (--i); 459 458 mtfSymbol[0] = uc; 460 uc =symToByte[uc];459 uc = symToByte[uc]; 461 460 462 461 /* We have our literal byte. Save it into dbuf. */ 463 462 464 463 byteCount[uc]++; 465 dbuf[dbufCount++] = (unsigned int)uc;464 dbuf[dbufCount++] = (unsigned)uc; 466 465 467 466 /* Skip group initialization if we're not done with this group. Done 468 467 * this way to avoid compiler warning. */ 469 468 470 end_of_huffman_loop:471 if (symCount--) goto continue_this_group;469 end_of_huffman_loop: 470 if (symCount--) goto continue_this_group; 472 471 } 473 472 474 473 /* At this point, we've read all the Huffman-coded symbols (and repeated 475 474 runs) for this block from the input stream, and decoded them into the 476 475 intermediate buffer. There are dbufCount many decoded bytes in dbuf[]. 477 476 Now undo the Burrows-Wheeler transform on dbuf. … … 481 480 /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */ 482 481 483 j =0;484 for (i=0;i<256;i++) {485 k =j+byteCount[i];482 j = 0; 483 for (i = 0; i < 256; i++) { 484 k = j + byteCount[i]; 486 485 byteCount[i] = j; 487 j =k;486 j = k; 488 487 } 489 488 490 489 /* Figure out what order dbuf would be in if we sorted it. */ 491 490 492 for (i =0;i<dbufCount;i++) {493 uc =(unsigned char)(dbuf[i] & 0xff);491 for (i = 0; i < dbufCount; i++) { 492 uc = (unsigned char)(dbuf[i] & 0xff); 494 493 dbuf[byteCount[uc]] |= (i << 8); 495 494 byteCount[uc]++; … … 500 499 it doesn't qualify as a run (hence writeRunCountdown=5). */ 501 500 502 if (dbufCount) {503 if (origPtr>=dbufCount) return RETVAL_DATA_ERROR;504 bd->writePos =dbuf[origPtr];505 bd->writeCurrent =(unsigned char)(bd->writePos&0xff);506 bd->writePos >>=8;507 bd->writeRunCountdown =5;508 } 509 bd->writeCount =dbufCount;501 if (dbufCount) { 502 if (origPtr >= dbufCount) return RETVAL_DATA_ERROR; 503 bd->writePos = dbuf[origPtr]; 504 bd->writeCurrent = (unsigned char)(bd->writePos & 0xff); 505 bd->writePos >>= 8; 506 bd->writeRunCountdown = 5; 507 } 508 bd->writeCount = dbufCount; 510 509 511 510 return RETVAL_OK; … … 519 518 */ 520 519 521 staticint read_bunzip(bunzip_data *bd, char *outbuf, int len)520 int read_bunzip(bunzip_data *bd, char *outbuf, int len) 522 521 { 523 const unsigned int*dbuf;524 int pos, current,previous,gotcount;522 const unsigned *dbuf; 523 int pos, current, previous, gotcount; 525 524 526 525 /* If last read was short due to end of file, return last block now */ 527 if (bd->writeCount<0) return bd->writeCount;526 if (bd->writeCount < 0) return bd->writeCount; 528 527 529 528 gotcount = 0; 530 dbuf =bd->dbuf;531 pos =bd->writePos;532 current =bd->writeCurrent;529 dbuf = bd->dbuf; 530 pos = bd->writePos; 531 current = bd->writeCurrent; 533 532 534 533 /* We will always have pending decoded data to write into the output … … 544 543 /* Loop outputting bytes */ 545 544 546 for (;;) {545 for (;;) { 547 546 548 547 /* If the output buffer is full, snapshot state and return */ 549 548 550 if (gotcount >= len) {551 bd->writePos =pos;552 bd->writeCurrent =current;549 if (gotcount >= len) { 550 bd->writePos =pos; 551 bd->writeCurrent = current; 553 552 bd->writeCopies++; 554 553 return len; … … 558 557 559 558 outbuf[gotcount++] = current; 560 bd->writeCRC =(((bd->writeCRC)<<8)561 ^ bd->crc32Table[((bd->writeCRC)>>24)^current]);559 bd->writeCRC = (bd->writeCRC << 8) 560 ^ bd->crc32Table[(bd->writeCRC >> 24) ^ current]; 562 561 563 562 /* Loop now if we're outputting multiple copies of this byte */ … … 567 566 continue; 568 567 } 569 decode_next_byte:568 decode_next_byte: 570 569 if (!bd->writeCount--) break; 571 570 /* Follow sequence vector to undo Burrows-Wheeler transform */ 572 previous =current;573 pos =dbuf[pos];574 current =pos&0xff;575 pos >>=8;571 previous = current; 572 pos = dbuf[pos]; 573 current = pos & 0xff; 574 pos >>= 8; 576 575 577 576 /* After 3 consecutive copies of the same byte, the 4th is a repeat … … 579 578 * of counting up because testing for non-zero is faster */ 580 579 581 if(--bd->writeRunCountdown) { 582 if(current!=previous) bd->writeRunCountdown=4; 580 if (--bd->writeRunCountdown) { 581 if (current != previous) 582 bd->writeRunCountdown = 4; 583 583 } else { 584 584 585 585 /* We have a repeated run, this byte indicates the count */ 586 586 587 bd->writeCopies =current;588 current =previous;589 bd->writeRunCountdown =5;587 bd->writeCopies = current; 588 current = previous; 589 bd->writeRunCountdown = 5; 590 590 591 591 /* Sometimes there are just 3 bytes (run length 0) */ 592 592 593 if (!bd->writeCopies) goto decode_next_byte;593 if (!bd->writeCopies) goto decode_next_byte; 594 594 595 595 /* Subtract the 1 copy we'd output anyway to get extras */ … … 601 601 /* Decompression of this block completed successfully */ 602 602 603 bd->writeCRC =~bd->writeCRC;604 bd->totalCRC =((bd->totalCRC<<1) | (bd->totalCRC>>31)) ^ bd->writeCRC;603 bd->writeCRC = ~bd->writeCRC; 604 bd->totalCRC = ((bd->totalCRC << 1) | (bd->totalCRC >> 31)) ^ bd->writeCRC; 605 605 606 606 /* If this block had a CRC error, force file level CRC error. */ 607 607 608 if (bd->writeCRC!=bd->headerCRC) {609 bd->totalCRC =bd->headerCRC+1;608 if (bd->writeCRC != bd->headerCRC) { 609 bd->totalCRC = bd->headerCRC+1; 610 610 return RETVAL_LAST_BLOCK; 611 611 } … … 615 615 /* (previous is just a convenient unused temp variable here) */ 616 616 617 previous =get_next_block(bd);618 if (previous) {619 bd->writeCount =previous;620 return (previous !=RETVAL_LAST_BLOCK) ? previous : gotcount;621 } 622 bd->writeCRC =~0;623 pos =bd->writePos;624 current =bd->writeCurrent;617 previous = get_next_block(bd); 618 if (previous) { 619 bd->writeCount = previous; 620 return (previous != RETVAL_LAST_BLOCK) ? previous : gotcount; 621 } 622 bd->writeCRC = ~0; 623 pos = bd->writePos; 624 current = bd->writeCurrent; 625 625 goto decode_next_byte; 626 626 } 627 627 628 628 629 /* Allocate the structure, read file header. If in_fd==-1, inbuf must contain … … 630 631 ignored, and data is read from file handle into temporary buffer. */ 631 632 632 static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf, 633 /* Because bunzip2 is used for help text unpacking, and because bb_show_usage() 634 should work for NOFORK applets too, we must be extremely careful to not leak 635 any allocations! */ 636 637 int start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *inbuf, 633 638 int len) 634 639 { 635 640 bunzip_data *bd; 636 unsigned int i; 637 const unsigned int BZh0=(((unsigned int)'B')<<24)+(((unsigned int)'Z')<<16) 638 +(((unsigned int)'h')<<8)+(unsigned int)'0'; 641 unsigned i; 642 enum { 643 BZh0 = ('B' << 24) + ('Z' << 16) + ('h' << 8) + '0' 644 }; 639 645 640 646 /* Figure out how much data to allocate */ 641 647 642 i =sizeof(bunzip_data);643 if (in_fd!=-1) i+=IOBUF_SIZE;648 i = sizeof(bunzip_data); 649 if (in_fd != -1) i += IOBUF_SIZE; 644 650 645 651 /* Allocate bunzip_data. Most fields initialize to zero. */ 646 652 647 bd =*bdp=xzalloc(i);653 bd = *bdp = xzalloc(i); 648 654 649 655 /* Setup input buffer */ 650 656 651 if(-1==(bd->in_fd=in_fd)) { 652 bd->inbuf=inbuf; 653 bd->inbufCount=len; 654 } else bd->inbuf=(unsigned char *)(bd+1); 657 bd->in_fd = in_fd; 658 if (-1 == in_fd) { 659 /* in this case, bd->inbuf is read-only */ 660 bd->inbuf = (void*)inbuf; /* cast away const-ness */ 661 bd->inbufCount = len; 662 } else 663 bd->inbuf = (unsigned char *)(bd + 1); 655 664 656 665 /* Init the CRC32 table (big endian) */ 657 666 658 bd->crc32Table = bb_crc32_filltable(1);667 crc32_filltable(bd->crc32Table, 1); 659 668 660 669 /* Setup for I/O error handling via longjmp */ 661 670 662 i =setjmp(bd->jmpbuf);663 if (i) return i;671 i = setjmp(bd->jmpbuf); 672 if (i) return i; 664 673 665 674 /* Ensure that file starts with "BZh['1'-'9']." */ 666 675 667 i = get_bits(bd, 32);668 if (( (unsigned int)(i-BZh0-1)) >= 9) return RETVAL_NOT_BZIP_DATA;676 i = get_bits(bd, 32); 677 if ((unsigned)(i - BZh0 - 1) >= 9) return RETVAL_NOT_BZIP_DATA; 669 678 670 679 /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of 671 680 uncompressed data. Allocate intermediate buffer for block. */ 672 681 673 bd->dbufSize=100000*(i-BZh0); 674 675 bd->dbuf=xmalloc(bd->dbufSize * sizeof(int)); 682 bd->dbufSize = 100000 * (i - BZh0); 683 684 /* Cannot use xmalloc - may leak bd in NOFORK case! */ 685 bd->dbuf = malloc_or_warn(bd->dbufSize * sizeof(int)); 686 if (!bd->dbuf) { 687 free(bd); 688 xfunc_die(); 689 } 676 690 return RETVAL_OK; 677 691 } 678 692 679 /* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip data, 680 not end of file.) */ 681 682 int uncompressStream(int src_fd, int dst_fd) 693 void dealloc_bunzip(bunzip_data *bd) 683 694 { 695 free(bd->dbuf); 696 free(bd); 697 } 698 699 700 /* Decompress src_fd to dst_fd. Stops at end of bzip data, not end of file. */ 701 702 USE_DESKTOP(long long) int 703 unpack_bz2_stream(int src_fd, int dst_fd) 704 { 705 USE_DESKTOP(long long total_written = 0;) 684 706 char *outbuf; 685 707 bunzip_data *bd; 686 708 int i; 687 709 688 outbuf=xmalloc(IOBUF_SIZE); 689 if(!(i=start_bunzip(&bd,src_fd,0,0))) { 690 for(;;) { 691 if((i=read_bunzip(bd,outbuf,IOBUF_SIZE)) <= 0) break; 692 if(i!=write(dst_fd,outbuf,i)) { 693 i=RETVAL_UNEXPECTED_OUTPUT_EOF; 710 outbuf = xmalloc(IOBUF_SIZE); 711 i = start_bunzip(&bd, src_fd, NULL, 0); 712 if (!i) { 713 for (;;) { 714 i = read_bunzip(bd, outbuf, IOBUF_SIZE); 715 if (i <= 0) break; 716 if (i != safe_write(dst_fd, outbuf, i)) { 717 i = RETVAL_UNEXPECTED_OUTPUT_EOF; 694 718 break; 695 719 } 720 USE_DESKTOP(total_written += i;) 696 721 } 697 722 } … … 699 724 /* Check CRC and release memory */ 700 725 701 if (i==RETVAL_LAST_BLOCK) {702 if (bd->headerCRC !=bd->totalCRC) {703 bb_error_msg(" Data integrity error when decompressing.");726 if (i == RETVAL_LAST_BLOCK) { 727 if (bd->headerCRC != bd->totalCRC) { 728 bb_error_msg("data integrity error when decompressing"); 704 729 } else { 705 i =RETVAL_OK;706 } 707 } else if (i ==RETVAL_UNEXPECTED_OUTPUT_EOF) {708 bb_error_msg(" Compressed file ends unexpectedly");730 i = RETVAL_OK; 731 } 732 } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) { 733 bb_error_msg("compressed file ends unexpectedly"); 709 734 } else { 710 bb_error_msg("Decompression failed"); 711 } 712 free(bd->dbuf); 713 free(bd); 735 bb_error_msg("decompression failed"); 736 } 737 dealloc_bunzip(bd); 714 738 free(outbuf); 715 739 716 return i ;740 return i ? i : USE_DESKTOP(total_written) + 0; 717 741 } 718 742 719 743 #ifdef TESTING 720 744 721 static char * const bunzip_errors[]={NULL,"Bad file checksum","Not bzip data", 722 "Unexpected input EOF","Unexpected output EOF","Data error", 723 "Out of memory","Obsolete (pre 0.9.5) bzip format not supported."}; 745 static char *const bunzip_errors[] = { 746 NULL, "Bad file checksum", "Not bzip data", 747 "Unexpected input EOF", "Unexpected output EOF", "Data error", 748 "Out of memory", "Obsolete (pre 0.9.5) bzip format not supported" 749 }; 724 750 725 751 /* Dumb little test thing, decompress stdin to stdout */ 726 int main(int argc, char * argv[])752 int main(int argc, char **argv) 727 753 { 728 int i =uncompressStream(0,1);754 int i = unpack_bz2_stream(0, 1); 729 755 char c; 730 756 731 if(i) fprintf(stderr,"%s\n", bunzip_errors[-i]); 732 else if(read(0,&c,1)) fprintf(stderr,"Trailing garbage ignored\n"); 757 if (i < 0) 758 fprintf(stderr,"%s\n", bunzip_errors[-i]); 759 else if (read(0, &c, 1)) 760 fprintf(stderr,"Trailing garbage ignored\n"); 733 761 return -i; 734 762 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/decompress_uncompress.c
r902 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 #include "libbb.h" 2 3 … … 6 7 * (see disclaimer below) 7 8 */ 8 9 9 10 10 /* (N)compress42.c - File compression ala IEEE Computer, Mar 1992. … … 26 26 * 27 27 */ 28 #include <stdio.h>29 #include <string.h>30 #include <unistd.h>31 28 32 29 /* Default input buffer size */ … … 37 34 38 35 /* Defines for third byte of header */ 39 #define MAGIC_1 (char_type)'\037' /* First byte of compressed file */ 40 #define MAGIC_2 (char_type)'\235' /* Second byte of compressed file */ 41 #define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */ 42 /* Masks 0x20 and 0x40 are free. */ 43 /* I think 0x20 should mean that there is */ 44 /* a fourth header byte (for expansion). */ 45 #define BLOCK_MODE 0x80 /* Block compresssion if table is full and */ 46 /* compression rate is dropping flush tables */ 47 /* the next two codes should not be changed lightly, as they must not */ 48 /* lie within the contiguous general code space. */ 49 #define FIRST 257 /* first free entry */ 50 #define CLEAR 256 /* table clear output code */ 51 52 #define INIT_BITS 9 /* initial number of bits/code */ 36 #define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */ 37 /* Masks 0x20 and 0x40 are free. */ 38 /* I think 0x20 should mean that there is */ 39 /* a fourth header byte (for expansion). */ 40 #define BLOCK_MODE 0x80 /* Block compression if table is full and */ 41 /* compression rate is dropping flush tables */ 42 /* the next two codes should not be changed lightly, as they must not */ 43 /* lie within the contiguous general code space. */ 44 #define FIRST 257 /* first free entry */ 45 #define CLEAR 256 /* table clear output code */ 46 47 #define INIT_BITS 9 /* initial number of bits/code */ 53 48 54 49 55 50 /* machine variants which require cc -Dmachine: pdp11, z8000, DOS */ 56 #define FAST 57 58 #define HBITS 17 /* 50% occupancy */ 59 #define HSIZE (1<<HBITS) 60 #define HMASK (HSIZE-1) 61 #define HPRIME 9941 62 #define BITS 16 63 #undef MAXSEG_64K 64 #define MAXCODE(n) (1L << (n)) 65 66 /* Block compress mode -C compatible with 2.0 */ 67 static int block_mode = BLOCK_MODE; 68 69 /* user settable max # bits/code */ 70 static int maxbits = BITS; 71 72 #define htabof(i) htab[i] 73 #define codetabof(i) codetab[i] 74 #define tab_prefixof(i) codetabof(i) 75 #define tab_suffixof(i) ((unsigned char *)(htab))[i] 76 #define de_stack ((unsigned char *)&(htab[HSIZE-1])) 77 #define clear_htab() memset(htab, -1, HSIZE) 78 #define clear_tab_prefixof() memset(codetab, 0, 256); 79 51 #define HBITS 17 /* 50% occupancy */ 52 #define HSIZE (1<<HBITS) 53 #define HMASK (HSIZE-1) /* unused */ 54 #define HPRIME 9941 /* unused */ 55 #define BITS 16 56 #define BITS_STR "16" 57 #undef MAXSEG_64K /* unused */ 58 #define MAXCODE(n) (1L << (n)) 59 60 #define htabof(i) htab[i] 61 #define codetabof(i) codetab[i] 62 #define tab_prefixof(i) codetabof(i) 63 #define tab_suffixof(i) ((unsigned char *)(htab))[i] 64 #define de_stack ((unsigned char *)&(htab[HSIZE-1])) 65 #define clear_tab_prefixof() memset(codetab, 0, 256) 80 66 81 67 /* 82 68 * Decompress stdin to stdout. This routine adapts to the codes in the 83 69 * file building the "string" table on-the-fly; requiring no table to 84 * be stored in the compressed file. The tables used herein are shared 85 * with those of the compress() routine. See the definitions above. 70 * be stored in the compressed file. 86 71 */ 87 72 88 int uncompress(int fd_in, int fd_out) 73 USE_DESKTOP(long long) int 74 uncompress(int fd_in, int fd_out) 89 75 { 76 USE_DESKTOP(long long total_written = 0;) 77 USE_DESKTOP(long long) int retval = -1; 90 78 unsigned char *stackp; 91 long intcode;79 long code; 92 80 int finchar; 93 long intoldcode;94 long in t incode;81 long oldcode; 82 long incode; 95 83 int inbits; 96 84 int posbits; … … 98 86 int insize; 99 87 int bitmask; 100 long intfree_ent;101 long intmaxcode;102 long intmaxmaxcode;88 long free_ent; 89 long maxcode; 90 long maxmaxcode; 103 91 int n_bits; 104 92 int rsize = 0; 105 RESERVE_CONFIG_UBUFFER(inbuf, IBUFSIZ + 64); 106 RESERVE_CONFIG_UBUFFER(outbuf, OBUFSIZ + 2048); 107 unsigned char htab[HSIZE]; 108 unsigned short codetab[HSIZE]; 109 memset(inbuf, 0, IBUFSIZ + 64); 110 memset(outbuf, 0, OBUFSIZ + 2048); 93 unsigned char *inbuf; /* were eating insane amounts of stack - */ 94 unsigned char *outbuf; /* bad for some embedded targets */ 95 unsigned char *htab; 96 unsigned short *codetab; 97 98 /* Hmm, these were statics - why?! */ 99 /* user settable max # bits/code */ 100 int maxbits; /* = BITS; */ 101 /* block compress mode -C compatible with 2.0 */ 102 int block_mode; /* = BLOCK_MODE; */ 103 104 inbuf = xzalloc(IBUFSIZ + 64); 105 outbuf = xzalloc(OBUFSIZ + 2048); 106 htab = xzalloc(HSIZE); /* wsn't zeroed out before, maybe can xmalloc? */ 107 codetab = xzalloc(HSIZE * sizeof(codetab[0])); 111 108 112 109 insize = 0; 113 110 114 inbuf[0] = bb_xread_char(fd_in); 111 /* xread isn't good here, we have to return - caller may want 112 * to do some cleanup (e.g. delete incomplete unpacked file etc) */ 113 if (full_read(fd_in, inbuf, 1) != 1) { 114 bb_error_msg("short read"); 115 goto err; 116 } 115 117 116 118 maxbits = inbuf[0] & BIT_MASK; … … 119 121 120 122 if (maxbits > BITS) { 121 bb_error_msg("compressed with %d bits, can only handle %d bits", maxbits,122 BITS);123 return -1;123 bb_error_msg("compressed with %d bits, can only handle " 124 BITS_STR" bits", maxbits); 125 goto err; 124 126 } 125 127 126 maxcode = MAXCODE(n_bits = INIT_BITS) - 1; 127 bitmask = (1 << n_bits) - 1; 128 n_bits = INIT_BITS; 129 maxcode = MAXCODE(INIT_BITS) - 1; 130 bitmask = (1 << INIT_BITS) - 1; 128 131 oldcode = -1; 129 132 finchar = 0; … … 134 137 135 138 /* As above, initialize the first 256 entries in the table. */ 136 clear_tab_prefixof();139 /*clear_tab_prefixof(); - done by xzalloc */ 137 140 138 141 for (code = 255; code >= 0; --code) { … … 141 144 142 145 do { 143 resetbuf:; 146 resetbuf: 144 147 { 145 148 int i; … … 147 150 int o; 148 151 149 e = insize - (o = (posbits >> 3)); 152 o = posbits >> 3; 153 e = insize - o; 150 154 151 155 for (i = 0; i < e; ++i) … … 158 162 if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { 159 163 rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); 164 //error check?? 160 165 insize += rsize; 161 166 } … … 182 187 unsigned char *p = &inbuf[posbits >> 3]; 183 188 184 code = 185 ((((long) (p[0])) | ((long) (p[1]) << 8) | 186 ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask; 189 code = ((((long) (p[0])) | ((long) (p[1]) << 8) | 190 ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask; 187 191 } 188 192 posbits += n_bits; … … 190 194 191 195 if (oldcode == -1) { 192 outbuf[outpos++] = (unsigned char) (finchar = 193 (int) (oldcode = code)); 196 oldcode = code; 197 finchar = (int) oldcode; 198 outbuf[outpos++] = (unsigned char) finchar; 194 199 continue; 195 200 } … … 202 207 ((n_bits << 3) - 203 208 (posbits - 1 + (n_bits << 3)) % (n_bits << 3))); 204 maxcode = MAXCODE(n_bits = INIT_BITS) - 1; 205 bitmask = (1 << n_bits) - 1; 209 n_bits = INIT_BITS; 210 maxcode = MAXCODE(INIT_BITS) - 1; 211 bitmask = (1 << INIT_BITS) - 1; 206 212 goto resetbuf; 207 213 } … … 223 229 (posbits & 07)); 224 230 bb_error_msg("uncompress: corrupt input"); 225 return -1;231 goto err; 226 232 } 227 233 … … 231 237 232 238 /* Generate output characters in reverse order */ 233 while ((long int) code >= (long int) 256) {239 while ((long) code >= (long) 256) { 234 240 *--stackp = tab_suffixof(code); 235 241 code = tab_prefixof(code); 236 242 } 237 243 238 *--stackp = (unsigned char) (finchar = tab_suffixof(code)); 244 finchar = tab_suffixof(code); 245 *--stackp = (unsigned char) finchar; 239 246 240 247 /* And put them out in forward order */ … … 242 249 int i; 243 250 244 if (outpos + (i = (de_stack - stackp)) >= OBUFSIZ) { 251 i = de_stack - stackp; 252 if (outpos + i >= OBUFSIZ) { 245 253 do { 246 254 if (i > OBUFSIZ - outpos) { … … 254 262 255 263 if (outpos >= OBUFSIZ) { 256 write(fd_out, outbuf, outpos); 264 full_write(fd_out, outbuf, outpos); 265 //error check?? 266 USE_DESKTOP(total_written += outpos;) 257 267 outpos = 0; 258 268 } 259 269 stackp += i; 260 } while ((i = (de_stack - stackp)) > 0); 270 i = de_stack - stackp; 271 } while (i > 0); 261 272 } else { 262 273 memcpy(outbuf + outpos, stackp, i); … … 266 277 267 278 /* Generate the new entry. */ 268 if ((code = free_ent) < maxmaxcode) { 279 code = free_ent; 280 if (code < maxmaxcode) { 269 281 tab_prefixof(code) = (unsigned short) oldcode; 270 282 tab_suffixof(code) = (unsigned char) finchar; … … 279 291 280 292 if (outpos > 0) { 281 write(fd_out, outbuf, outpos); 293 full_write(fd_out, outbuf, outpos); 294 //error check?? 295 USE_DESKTOP(total_written += outpos;) 282 296 } 283 297 284 RELEASE_CONFIG_BUFFER(inbuf); 285 RELEASE_CONFIG_BUFFER(outbuf); 286 return 0; 298 retval = USE_DESKTOP(total_written) + 0; 299 err: 300 free(inbuf); 301 free(outbuf); 302 free(htab); 303 free(codetab); 304 return retval; 287 305 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/decompress_unlzma.c
r821 r1765 1 /* vi: setts=4: */1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 3 * Small lzma deflate implementation. … … 13 13 #include "unarchive.h" 14 14 15 #if def CONFIG_FEATURE_LZMA_FAST16 # define speed_inline A TTRIBUTE_ALWAYS_INLINE15 #if ENABLE_FEATURE_LZMA_FAST 16 # define speed_inline ALWAYS_INLINE 17 17 #else 18 18 # define speed_inline … … 23 23 int fd; 24 24 uint8_t *ptr; 25 uint8_t *buffer; 25 26 /* Was keeping rc on stack in unlzma and separately allocating buffer, 27 * but with "buffer 'attached to' allocated rc" code is smaller: */ 28 /* uint8_t *buffer; */ 29 #define RC_BUFFER ((uint8_t*)(rc+1)) 30 26 31 uint8_t *buffer_end; 27 int buffer_size; 32 33 /* Had provisions for variable buffer, but we don't need it here */ 34 /* int buffer_size; */ 35 #define RC_BUFFER_SIZE 0x10000 36 28 37 uint32_t code; 29 38 uint32_t range; … … 31 40 } rc_t; 32 41 33 34 42 #define RC_TOP_BITS 24 35 43 #define RC_MOVE_BITS 5 … … 40 48 static void rc_read(rc_t * rc) 41 49 { 42 rc->buffer_size = read(rc->fd, rc->buffer, rc->buffer_size);43 if ( rc->buffer_size <= 0)50 int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE); 51 if (buffer_size <= 0) 44 52 bb_error_msg_and_die("unexpected EOF"); 45 rc->ptr = rc->buffer;46 rc->buffer_end = rc->buffer + rc->buffer_size;53 rc->ptr = RC_BUFFER; 54 rc->buffer_end = RC_BUFFER + buffer_size; 47 55 } 48 56 49 57 /* Called once */ 50 static void rc_init(rc_t * rc, int fd, int buffer_size)58 static rc_t* rc_init(int fd) /*, int buffer_size) */ 51 59 { 52 60 int i; 61 rc_t* rc; 62 63 rc = xmalloc(sizeof(rc_t) + RC_BUFFER_SIZE); 53 64 54 65 rc->fd = fd; 55 rc->buffer = xmalloc(buffer_size); 56 rc->buffer_size = buffer_size; 57 rc->buffer_end = rc->buffer + rc->buffer_size; 66 /* rc->buffer_size = buffer_size; */ 67 rc->buffer_end = RC_BUFFER + RC_BUFFER_SIZE; 58 68 rc->ptr = rc->buffer_end; 59 69 … … 65 75 rc->code = (rc->code << 8) | *rc->ptr++; 66 76 } 67 } 68 69 /* Called once. TODO: bb_maybe_free() */ 70 static ATTRIBUTE_ALWAYS_INLINE void rc_free(rc_t * rc) 77 return rc; 78 } 79 80 /* Called once */ 81 static ALWAYS_INLINE void rc_free(rc_t * rc) 71 82 { 72 83 if (ENABLE_FEATURE_CLEAN_UP) 73 free(rc ->buffer);84 free(rc); 74 85 } 75 86 … … 82 93 rc->code = (rc->code << 8) | *rc->ptr++; 83 94 } 84 static A TTRIBUTE_ALWAYS_INLINE void rc_normalize(rc_t * rc)95 static ALWAYS_INLINE void rc_normalize(rc_t * rc) 85 96 { 86 97 if (rc->range < (1 << RC_TOP_BITS)) { … … 89 100 } 90 101 91 /* Called 9 times */102 /* rc_is_bit_0 is called 9 times */ 92 103 /* Why rc_is_bit_0_helper exists? 93 * Because we want to always expose (rc->code < rc->bound) to optimizer 104 * Because we want to always expose (rc->code < rc->bound) to optimizer. 105 * Thus rc_is_bit_0 is always inlined, and rc_is_bit_0_helper is inlined 106 * only if we compile for speed. 94 107 */ 95 108 static speed_inline uint32_t rc_is_bit_0_helper(rc_t * rc, uint16_t * p) … … 99 112 return rc->bound; 100 113 } 101 static A TTRIBUTE_ALWAYS_INLINE int rc_is_bit_0(rc_t * rc, uint16_t * p)114 static ALWAYS_INLINE int rc_is_bit_0(rc_t * rc, uint16_t * p) 102 115 { 103 116 uint32_t t = rc_is_bit_0_helper(rc, p); … … 133 146 134 147 /* Called once */ 135 static A TTRIBUTE_ALWAYS_INLINE int rc_direct_bit(rc_t * rc)148 static ALWAYS_INLINE int rc_direct_bit(rc_t * rc) 136 149 { 137 150 rc_normalize(rc); … … 164 177 165 178 166 #define LZMA_BASE_SIZE 1846 167 #define LZMA_LIT_SIZE 768 168 169 #define LZMA_NUM_POS_BITS_MAX 4 170 171 #define LZMA_LEN_NUM_LOW_BITS 3 172 #define LZMA_LEN_NUM_MID_BITS 3 173 #define LZMA_LEN_NUM_HIGH_BITS 8 174 175 #define LZMA_LEN_CHOICE 0 176 #define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1) 177 #define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1) 178 #define LZMA_LEN_MID (LZMA_LEN_LOW \ 179 + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))) 180 #define LZMA_LEN_HIGH (LZMA_LEN_MID \ 181 +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))) 182 #define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)) 183 184 #define LZMA_NUM_STATES 12 185 #define LZMA_NUM_LIT_STATES 7 186 187 #define LZMA_START_POS_MODEL_INDEX 4 188 #define LZMA_END_POS_MODEL_INDEX 14 189 #define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1)) 190 191 #define LZMA_NUM_POS_SLOT_BITS 6 192 #define LZMA_NUM_LEN_TO_POS_STATES 4 193 194 #define LZMA_NUM_ALIGN_BITS 4 195 196 #define LZMA_MATCH_MIN_LEN 2 197 198 #define LZMA_IS_MATCH 0 199 #define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES <<LZMA_NUM_POS_BITS_MAX)) 200 #define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES) 201 #define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES) 202 #define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES) 203 #define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES) 204 #define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \ 205 + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)) 206 #define LZMA_SPEC_POS (LZMA_POS_SLOT \ 207 +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)) 208 #define LZMA_ALIGN (LZMA_SPEC_POS \ 209 + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX) 210 #define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)) 211 #define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS) 212 #define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS) 213 214 215 int unlzma(int src_fd, int dst_fd) 216 { 179 /* #defines will force compiler to compute/optimize each one with each usage. 180 * Have heart and use enum instead. */ 181 enum { 182 LZMA_BASE_SIZE = 1846, 183 LZMA_LIT_SIZE = 768, 184 185 LZMA_NUM_POS_BITS_MAX = 4, 186 187 LZMA_LEN_NUM_LOW_BITS = 3, 188 LZMA_LEN_NUM_MID_BITS = 3, 189 LZMA_LEN_NUM_HIGH_BITS = 8, 190 191 LZMA_LEN_CHOICE = 0, 192 LZMA_LEN_CHOICE_2 = (LZMA_LEN_CHOICE + 1), 193 LZMA_LEN_LOW = (LZMA_LEN_CHOICE_2 + 1), 194 LZMA_LEN_MID = (LZMA_LEN_LOW \ 195 + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))), 196 LZMA_LEN_HIGH = (LZMA_LEN_MID \ 197 + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))), 198 LZMA_NUM_LEN_PROBS = (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)), 199 200 LZMA_NUM_STATES = 12, 201 LZMA_NUM_LIT_STATES = 7, 202 203 LZMA_START_POS_MODEL_INDEX = 4, 204 LZMA_END_POS_MODEL_INDEX = 14, 205 LZMA_NUM_FULL_DISTANCES = (1 << (LZMA_END_POS_MODEL_INDEX >> 1)), 206 207 LZMA_NUM_POS_SLOT_BITS = 6, 208 LZMA_NUM_LEN_TO_POS_STATES = 4, 209 210 LZMA_NUM_ALIGN_BITS = 4, 211 212 LZMA_MATCH_MIN_LEN = 2, 213 214 LZMA_IS_MATCH = 0, 215 LZMA_IS_REP = (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)), 216 LZMA_IS_REP_G0 = (LZMA_IS_REP + LZMA_NUM_STATES), 217 LZMA_IS_REP_G1 = (LZMA_IS_REP_G0 + LZMA_NUM_STATES), 218 LZMA_IS_REP_G2 = (LZMA_IS_REP_G1 + LZMA_NUM_STATES), 219 LZMA_IS_REP_0_LONG = (LZMA_IS_REP_G2 + LZMA_NUM_STATES), 220 LZMA_POS_SLOT = (LZMA_IS_REP_0_LONG \ 221 + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)), 222 LZMA_SPEC_POS = (LZMA_POS_SLOT \ 223 + (LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)), 224 LZMA_ALIGN = (LZMA_SPEC_POS \ 225 + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX), 226 LZMA_LEN_CODER = (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)), 227 LZMA_REP_LEN_CODER = (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS), 228 LZMA_LITERAL = (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS), 229 }; 230 231 232 USE_DESKTOP(long long) int 233 unpack_lzma_stream(int src_fd, int dst_fd) 234 { 235 USE_DESKTOP(long long total_written = 0;) 217 236 lzma_header_t header; 218 237 int lc, pb, lp; … … 225 244 int num_bits; 226 245 int num_probs; 227 rc_t rc;246 rc_t *rc; 228 247 int i, mi; 229 248 uint8_t *buffer; … … 234 253 uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; 235 254 236 if (read(src_fd, &header, sizeof(header)) != sizeof(header)) 237 bb_error_msg_and_die("can't read header"); 255 xread(src_fd, &header, sizeof(header)); 238 256 239 257 if (header.pos >= (9 * 5 * 5)) … … 260 278 p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; 261 279 262 rc _init(&rc, src_fd, 0x10000);280 rc = rc_init(src_fd); /*, RC_BUFFER_SIZE); */ 263 281 264 282 while (global_pos + buffer_pos < header.dst_size) { … … 267 285 prob = 268 286 p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state; 269 if (rc_is_bit_0( &rc, prob)) {287 if (rc_is_bit_0(rc, prob)) { 270 288 mi = 1; 271 rc_update_bit_0( &rc, prob);289 rc_update_bit_0(rc, prob); 272 290 prob = (p + LZMA_LITERAL + (LZMA_LIT_SIZE 273 291 * ((((buffer_pos + global_pos) & literal_pos_mask) << lc) … … 287 305 bit = match_byte & 0x100; 288 306 prob_lit = prob + 0x100 + bit + mi; 289 if (rc_get_bit( &rc, prob_lit, &mi)) {307 if (rc_get_bit(rc, prob_lit, &mi)) { 290 308 if (!bit) 291 309 break; … … 298 316 while (mi < 0x100) { 299 317 prob_lit = prob + mi; 300 rc_get_bit( &rc, prob_lit, &mi);318 rc_get_bit(rc, prob_lit, &mi); 301 319 } 302 320 previous_byte = (uint8_t) mi; … … 306 324 buffer_pos = 0; 307 325 global_pos += header.dict_size; 308 write(dst_fd, buffer, header.dict_size); 326 if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size) 327 goto bad; 328 USE_DESKTOP(total_written += header.dict_size;) 309 329 } 310 330 if (state < 4) … … 318 338 uint16_t *prob_len; 319 339 320 rc_update_bit_1( &rc, prob);340 rc_update_bit_1(rc, prob); 321 341 prob = p + LZMA_IS_REP + state; 322 if (rc_is_bit_0( &rc, prob)) {323 rc_update_bit_0( &rc, prob);342 if (rc_is_bit_0(rc, prob)) { 343 rc_update_bit_0(rc, prob); 324 344 rep3 = rep2; 325 345 rep2 = rep1; … … 328 348 prob = p + LZMA_LEN_CODER; 329 349 } else { 330 rc_update_bit_1( &rc, prob);350 rc_update_bit_1(rc, prob); 331 351 prob = p + LZMA_IS_REP_G0 + state; 332 if (rc_is_bit_0( &rc, prob)) {333 rc_update_bit_0( &rc, prob);352 if (rc_is_bit_0(rc, prob)) { 353 rc_update_bit_0(rc, prob); 334 354 prob = (p + LZMA_IS_REP_0_LONG 335 355 + (state << LZMA_NUM_POS_BITS_MAX) + pos_state); 336 if (rc_is_bit_0( &rc, prob)) {337 rc_update_bit_0( &rc, prob);356 if (rc_is_bit_0(rc, prob)) { 357 rc_update_bit_0(rc, prob); 338 358 339 359 state = state < LZMA_NUM_LIT_STATES ? 9 : 11; … … 346 366 buffer_pos = 0; 347 367 global_pos += header.dict_size; 348 write(dst_fd, buffer, header.dict_size); 368 if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size) 369 goto bad; 370 USE_DESKTOP(total_written += header.dict_size;) 349 371 } 350 372 continue; 351 373 } else { 352 rc_update_bit_1( &rc, prob);374 rc_update_bit_1(rc, prob); 353 375 } 354 376 } else { 355 377 uint32_t distance; 356 378 357 rc_update_bit_1( &rc, prob);379 rc_update_bit_1(rc, prob); 358 380 prob = p + LZMA_IS_REP_G1 + state; 359 if (rc_is_bit_0( &rc, prob)) {360 rc_update_bit_0( &rc, prob);381 if (rc_is_bit_0(rc, prob)) { 382 rc_update_bit_0(rc, prob); 361 383 distance = rep1; 362 384 } else { 363 rc_update_bit_1( &rc, prob);385 rc_update_bit_1(rc, prob); 364 386 prob = p + LZMA_IS_REP_G2 + state; 365 if (rc_is_bit_0( &rc, prob)) {366 rc_update_bit_0( &rc, prob);387 if (rc_is_bit_0(rc, prob)) { 388 rc_update_bit_0(rc, prob); 367 389 distance = rep2; 368 390 } else { 369 rc_update_bit_1( &rc, prob);391 rc_update_bit_1(rc, prob); 370 392 distance = rep3; 371 393 rep3 = rep2; … … 381 403 382 404 prob_len = prob + LZMA_LEN_CHOICE; 383 if (rc_is_bit_0( &rc, prob_len)) {384 rc_update_bit_0( &rc, prob_len);405 if (rc_is_bit_0(rc, prob_len)) { 406 rc_update_bit_0(rc, prob_len); 385 407 prob_len = (prob + LZMA_LEN_LOW 386 408 + (pos_state << LZMA_LEN_NUM_LOW_BITS)); … … 388 410 num_bits = LZMA_LEN_NUM_LOW_BITS; 389 411 } else { 390 rc_update_bit_1( &rc, prob_len);412 rc_update_bit_1(rc, prob_len); 391 413 prob_len = prob + LZMA_LEN_CHOICE_2; 392 if (rc_is_bit_0( &rc, prob_len)) {393 rc_update_bit_0( &rc, prob_len);414 if (rc_is_bit_0(rc, prob_len)) { 415 rc_update_bit_0(rc, prob_len); 394 416 prob_len = (prob + LZMA_LEN_MID 395 417 + (pos_state << LZMA_LEN_NUM_MID_BITS)); … … 397 419 num_bits = LZMA_LEN_NUM_MID_BITS; 398 420 } else { 399 rc_update_bit_1( &rc, prob_len);421 rc_update_bit_1(rc, prob_len); 400 422 prob_len = prob + LZMA_LEN_HIGH; 401 423 offset = ((1 << LZMA_LEN_NUM_LOW_BITS) … … 404 426 } 405 427 } 406 rc_bit_tree_decode( &rc, prob_len, num_bits, &len);428 rc_bit_tree_decode(rc, prob_len, num_bits, &len); 407 429 len += offset; 408 430 … … 417 439 LZMA_NUM_LEN_TO_POS_STATES - 1) 418 440 << LZMA_NUM_POS_SLOT_BITS); 419 rc_bit_tree_decode( &rc, prob, LZMA_NUM_POS_SLOT_BITS,441 rc_bit_tree_decode(rc, prob, LZMA_NUM_POS_SLOT_BITS, 420 442 &pos_slot); 421 443 if (pos_slot >= LZMA_START_POS_MODEL_INDEX) { … … 428 450 num_bits -= LZMA_NUM_ALIGN_BITS; 429 451 while (num_bits--) 430 rep0 = (rep0 << 1) | rc_direct_bit( &rc);452 rep0 = (rep0 << 1) | rc_direct_bit(rc); 431 453 prob = p + LZMA_ALIGN; 432 454 rep0 <<= LZMA_NUM_ALIGN_BITS; … … 436 458 mi = 1; 437 459 while (num_bits--) { 438 if (rc_get_bit( &rc, prob + mi, &mi))460 if (rc_get_bit(rc, prob + mi, &mi)) 439 461 rep0 |= i; 440 462 i <<= 1; … … 457 479 buffer_pos = 0; 458 480 global_pos += header.dict_size; 459 write(dst_fd, buffer, header.dict_size); 481 if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size) 482 goto bad; 483 USE_DESKTOP(total_written += header.dict_size;) 460 484 } 461 485 len--; … … 464 488 } 465 489 466 write(dst_fd, buffer, buffer_pos); 467 rc_free(&rc); 468 return 0; 469 } 470 471 /* vi:set ts=4: */ 490 491 if (full_write(dst_fd, buffer, buffer_pos) != buffer_pos) { 492 bad: 493 rc_free(rc); 494 return -1; 495 } 496 rc_free(rc); 497 USE_DESKTOP(total_written += buffer_pos;) 498 return USE_DESKTOP(total_written) + 0; 499 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/decompress_unzip.c
r821 r1765 30 30 * 31 31 * See the file algorithm.doc for the compression algorithms and file formats. 32 * 32 * 33 33 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 34 34 */ 35 35 36 36 #include "libbb.h" 37 #include <sys/wait.h>38 #include <signal.h>39 37 #include "unarchive.h" 40 38 … … 48 46 } huft_t; 49 47 50 static int gunzip_src_fd; 51 unsigned int gunzip_bytes_out; /* number of output bytes */ 52 static unsigned int gunzip_outbuf_count; /* bytes in output buffer */ 53 54 /* gunzip_window size--must be a power of two, and 55 * at least 32K for zip's deflate method */ 56 enum { gunzip_wsize = 0x8000 }; 57 static unsigned char *gunzip_window; 58 59 static uint32_t *gunzip_crc_table; 60 uint32_t gunzip_crc; 61 62 /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ 63 #define BMAX 16 /* maximum bit length of any code (16 for explode) */ 64 #define N_MAX 288 /* maximum number of codes in any set */ 65 66 /* bitbuffer */ 67 static unsigned int gunzip_bb; /* bit buffer */ 68 static unsigned char gunzip_bk; /* bits in bit buffer */ 69 70 /* These control the size of the bytebuffer */ 71 static unsigned int bytebuffer_max = 0x8000; 72 static unsigned char *bytebuffer = NULL; 73 static unsigned int bytebuffer_offset = 0; 74 static unsigned int bytebuffer_size = 0; 75 76 static const unsigned short mask_bits[] = { 48 enum { 49 /* gunzip_window size--must be a power of two, and 50 * at least 32K for zip's deflate method */ 51 GUNZIP_WSIZE = 0x8000, 52 /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ 53 BMAX = 16, /* maximum bit length of any code (16 for explode) */ 54 N_MAX = 288, /* maximum number of codes in any set */ 55 }; 56 57 58 /* This is somewhat complex-looking arrangement, but it allows 59 * to place decompressor state either in bss or in 60 * malloc'ed space simply by changing #defines below. 61 * Sizes on i386: 62 * text data bss dec hex 63 * 5256 0 108 5364 14f4 - bss 64 * 4915 0 0 4915 1333 - malloc 65 */ 66 #define STATE_IN_BSS 0 67 #define STATE_IN_MALLOC 1 68 69 70 typedef struct state_t { 71 off_t gunzip_bytes_out; /* number of output bytes */ 72 uint32_t gunzip_crc; 73 74 int gunzip_src_fd; 75 unsigned gunzip_outbuf_count; /* bytes in output buffer */ 76 77 unsigned char *gunzip_window; 78 79 uint32_t *gunzip_crc_table; 80 81 /* bitbuffer */ 82 unsigned gunzip_bb; /* bit buffer */ 83 unsigned char gunzip_bk; /* bits in bit buffer */ 84 85 /* These control the size of the STATE()bytebuffer */ 86 unsigned bytebuffer_max; 87 unsigned char *bytebuffer; 88 unsigned bytebuffer_offset; 89 unsigned bytebuffer_size; 90 91 /* private data of inflate_codes() */ 92 unsigned inflate_codes_ml; /* masks for bl and bd bits */ 93 unsigned inflate_codes_md; /* masks for bl and bd bits */ 94 unsigned inflate_codes_bb; /* bit buffer */ 95 unsigned inflate_codes_k; /* number of bits in bit buffer */ 96 unsigned inflate_codes_w; /* current gunzip_window position */ 97 huft_t *inflate_codes_tl; 98 huft_t *inflate_codes_td; 99 unsigned inflate_codes_bl; 100 unsigned inflate_codes_bd; 101 unsigned inflate_codes_nn; /* length and index for copy */ 102 unsigned inflate_codes_dd; 103 smallint resume_copy; 104 105 /* private data of inflate_get_next_window() */ 106 smallint method; /* Method == -1 for stored, -2 for codes */ 107 smallint need_another_block; 108 smallint end_reached; 109 110 /* private data of inflate_stored() */ 111 unsigned inflate_stored_n; 112 unsigned inflate_stored_b; 113 unsigned inflate_stored_k; 114 unsigned inflate_stored_w; 115 } state_t; 116 #define gunzip_bytes_out (S()gunzip_bytes_out ) 117 #define gunzip_crc (S()gunzip_crc ) 118 #define gunzip_src_fd (S()gunzip_src_fd ) 119 #define gunzip_outbuf_count (S()gunzip_outbuf_count) 120 #define gunzip_window (S()gunzip_window ) 121 #define gunzip_crc_table (S()gunzip_crc_table ) 122 #define gunzip_bb (S()gunzip_bb ) 123 #define gunzip_bk (S()gunzip_bk ) 124 #define bytebuffer_max (S()bytebuffer_max ) 125 #define bytebuffer (S()bytebuffer ) 126 #define bytebuffer_offset (S()bytebuffer_offset ) 127 #define bytebuffer_size (S()bytebuffer_size ) 128 #define inflate_codes_ml (S()inflate_codes_ml ) 129 #define inflate_codes_md (S()inflate_codes_md ) 130 #define inflate_codes_bb (S()inflate_codes_bb ) 131 #define inflate_codes_k (S()inflate_codes_k ) 132 #define inflate_codes_w (S()inflate_codes_w ) 133 #define inflate_codes_tl (S()inflate_codes_tl ) 134 #define inflate_codes_td (S()inflate_codes_td ) 135 #define inflate_codes_bl (S()inflate_codes_bl ) 136 #define inflate_codes_bd (S()inflate_codes_bd ) 137 #define inflate_codes_nn (S()inflate_codes_nn ) 138 #define inflate_codes_dd (S()inflate_codes_dd ) 139 #define resume_copy (S()resume_copy ) 140 #define method (S()method ) 141 #define need_another_block (S()need_another_block ) 142 #define end_reached (S()end_reached ) 143 #define inflate_stored_n (S()inflate_stored_n ) 144 #define inflate_stored_b (S()inflate_stored_b ) 145 #define inflate_stored_k (S()inflate_stored_k ) 146 #define inflate_stored_w (S()inflate_stored_w ) 147 #define INIT_STATE ({ bytebuffer_size = 0; method = -1; need_another_block = 1; }) 148 149 150 /* This is generic part */ 151 #if STATE_IN_BSS /* Use global data segment */ 152 #define DECLARE_STATE /*nothing*/ 153 #define ALLOC_STATE (init_state()) 154 #define DEALLOC_STATE ((void)0) 155 #define S() state. 156 #define PASS_STATE /*nothing*/ 157 #define PASS_STATE_ONLY /*nothing*/ 158 #define STATE_PARAM /*nothing*/ 159 #define STATE_PARAM_ONLY void 160 static state_t state; 161 static void init_state(void) 162 { 163 INIT_STATE; 164 } 165 #endif 166 167 #if STATE_IN_MALLOC /* Use malloc space */ 168 #define DECLARE_STATE state_t *state 169 #define ALLOC_STATE (state = alloc_state()) 170 #define DEALLOC_STATE free(state) 171 #define S() state-> 172 #define PASS_STATE state, 173 #define PASS_STATE_ONLY state 174 #define STATE_PARAM state_t *state, 175 #define STATE_PARAM_ONLY state_t *state 176 static state_t* alloc_state(void) 177 { 178 state_t* state = xzalloc(sizeof(*state)); 179 INIT_STATE; 180 return state; 181 } 182 #endif 183 184 185 static const unsigned short mask_bits[] ALIGN2 = { 77 186 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 78 187 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff … … 80 189 81 190 /* Copy lengths for literal codes 257..285 */ 82 static const unsigned short cplens[] = {191 static const unsigned short cplens[] ALIGN2 = { 83 192 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 84 193 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 … … 87 196 /* note: see note #13 above about the 258 in this list. */ 88 197 /* Extra bits for literal codes 257..285 */ 89 static const unsigned char cplext[] = {198 static const unsigned char cplext[] ALIGN1 = { 90 199 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 91 200 5, 5, 5, 0, 99, 99 92 }; /* 99==invalid */201 }; /* 99 == invalid */ 93 202 94 203 /* Copy offsets for distance codes 0..29 */ 95 static const unsigned short cpdist[] = {204 static const unsigned short cpdist[] ALIGN2 = { 96 205 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 97 206 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 … … 99 208 100 209 /* Extra bits for distance codes */ 101 static const unsigned char cpdext[] = {210 static const unsigned char cpdext[] ALIGN1 = { 102 211 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 103 212 11, 11, 12, 12, 13, 13 … … 106 215 /* Tables for deflate from PKZIP's appnote.txt. */ 107 216 /* Order of the bit length code lengths */ 108 static const unsigned char border[] = {217 static const unsigned char border[] ALIGN1 = { 109 218 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 110 219 }; 111 220 112 static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current, const unsigned intrequired)221 static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current, const unsigned required) 113 222 { 114 223 while (*current < required) { … … 117 226 * to the front of the bytebuffer, leave 4 bytes free at end of tail 118 227 * so we can easily top up buffer in check_trailer_gzip() */ 119 if (!(bytebuffer_size = bb_xread(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 8))) { 228 bytebuffer_size = safe_read(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 8); 229 if (1 > bytebuffer_size) 230 //shouldn't we propagate error? 120 231 bb_error_msg_and_die("unexpected end of file"); 121 }122 232 bytebuffer_size += 4; 123 233 bytebuffer_offset = 4; 124 234 } 125 bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current;235 bitbuffer |= ((unsigned) bytebuffer[bytebuffer_offset]) << *current; 126 236 bytebuffer_offset++; 127 237 *current += 8; 128 238 } 129 return (bitbuffer);239 return bitbuffer; 130 240 } 131 241 … … 136 246 * t: table to free 137 247 */ 138 static int huft_free(huft_t * t) 139 { 140 huft_t *p; 248 static void huft_free(huft_t * p) 249 { 141 250 huft_t *q; 142 251 143 252 /* Go through linked list, freeing from the malloced (t[-1]) address. */ 144 p = t; 145 while (p != (huft_t *) NULL) { 253 while (p) { 146 254 q = (--p)->v.t; 147 free( (char *)p);255 free(p); 148 256 p = q; 149 257 } 150 return 0;151 258 } 152 259 … … 165 272 * m: maximum lookup bits, returns actual 166 273 */ 167 static 168 int huft_build(unsigned int *b, const unsigned int n, 169 const unsigned int s, const unsigned short *d, 170 const unsigned char *e, huft_t ** t, unsigned int *m) 274 static int huft_build(unsigned *b, const unsigned n, 275 const unsigned s, const unsigned short *d, 276 const unsigned char *e, huft_t ** t, unsigned *m) 171 277 { 172 278 unsigned a; /* counter for codes of length k */ … … 195 301 196 302 /* Generate counts for each bit length */ 197 memset( (void *)c, 0, sizeof(c));303 memset(c, 0, sizeof(c)); 198 304 p = b; 199 305 i = n; … … 203 309 } while (--i); 204 310 if (c[0] == n) { /* null input--all zero length codes */ 205 *t = (huft_t *)NULL;311 *t = NULL; 206 312 *m = 0; 207 313 return 2; … … 217 323 /* Adjust last length count to fill out codes, if needed */ 218 324 for (y = 1 << j; j < i; j++, y <<= 1) { 219 if ((y -= c[j]) < 0) { 325 y -= c[j]; 326 if (y < 0) { 220 327 return 2; /* bad input: more codes than bits */ 221 328 } 222 329 } 223 if ((y -= c[i]) < 0) { 330 y -= c[i]; 331 if (y < 0) { 224 332 return 2; 225 333 } … … 231 339 xp = x + 2; 232 340 while (--i) { /* note that i == g from above */ 233 *xp++ = (j += *p++); 341 j += *p++; 342 *xp++ = j; 234 343 } 235 344 … … 238 347 i = 0; 239 348 do { 240 if ((j = *p++) != 0) { 349 j = *p++; 350 if (j != 0) { 241 351 v[x[j]++] = i; 242 352 } … … 248 358 htl = -1; /* no tables yet--level -1 */ 249 359 w = ws[0] = 0; /* bits decoded */ 250 u[0] = (huft_t *)NULL; /* just to keep compilers happy */251 q = (huft_t *)NULL; /* ditto */360 u[0] = NULL; /* just to keep compilers happy */ 361 q = NULL; /* ditto */ 252 362 z = 0; /* ditto */ 253 363 … … 262 372 263 373 /* compute minimum size table less than or equal to *m bits */ 264 z = (z = g - w) > *m ? *m : z; /* upper limit on table size */ 265 if ((f = 1 << (j = k - w)) > a + 1) { /* try a k-w bit table */ 374 z = g - w; 375 z = z > *m ? *m : z; /* upper limit on table size */ 376 j = k - w; 377 f = 1 << j; 378 if (f > a + 1) { /* try a k-w bit table */ 266 379 /* too few codes for k-w bit table */ 267 380 f -= a + 1; /* deduct codes from patterns left */ 268 381 xp = c + k; 269 382 while (++j < z) { /* try smaller tables up to z bits */ 270 if ((f <<= 1) <= *++xp) { 383 f <<= 1; 384 if (f <= *++xp) { 271 385 break; /* enough codes to use up j bits */ 272 386 } … … 279 393 280 394 /* allocate and link in new table */ 281 q = (huft_t *)xzalloc((z + 1) * sizeof(huft_t));395 q = xzalloc((z + 1) * sizeof(huft_t)); 282 396 *t = q + 1; /* link to list for huft_free() */ 283 397 t = &(q->v.t); … … 333 447 } 334 448 449 335 450 /* 336 451 * inflate (decompress) the codes in a deflated (compressed) block. … … 340 455 * bl, bd: number of bits decoded by tl[] and td[] 341 456 */ 342 static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned int my_bl, const unsigned int my_bd, int setup) 343 { 344 static unsigned int e; /* table entry flag/number of extra bits */ 345 static unsigned int n, d; /* length and index for copy */ 346 static unsigned int w; /* current gunzip_window position */ 347 static huft_t *t; /* pointer to table entry */ 348 static unsigned int ml, md; /* masks for bl and bd bits */ 349 static unsigned int b; /* bit buffer */ 350 static unsigned int k; /* number of bits in bit buffer */ 351 static huft_t *tl, *td; 352 static unsigned int bl, bd; 353 static int resumeCopy = 0; 354 355 if (setup) { // 1st time we are called, copy in variables 356 tl = my_tl; 357 td = my_td; 358 bl = my_bl; 359 bd = my_bd; 360 /* make local copies of globals */ 361 b = gunzip_bb; /* initialize bit buffer */ 362 k = gunzip_bk; 363 w = gunzip_outbuf_count; /* initialize gunzip_window position */ 364 365 /* inflate the coded data */ 366 ml = mask_bits[bl]; /* precompute masks for speed */ 367 md = mask_bits[bd]; 368 return 0; // Don't actually do anything the first time 369 } 370 371 if (resumeCopy) goto do_copy; 457 /* called once from inflate_block */ 458 459 /* map formerly local static variables to globals */ 460 #define ml inflate_codes_ml 461 #define md inflate_codes_md 462 #define bb inflate_codes_bb 463 #define k inflate_codes_k 464 #define w inflate_codes_w 465 #define tl inflate_codes_tl 466 #define td inflate_codes_td 467 #define bl inflate_codes_bl 468 #define bd inflate_codes_bd 469 #define nn inflate_codes_nn 470 #define dd inflate_codes_dd 471 static void inflate_codes_setup(STATE_PARAM huft_t * my_tl, huft_t * my_td, const unsigned my_bl, const unsigned my_bd) 472 { 473 tl = my_tl; 474 td = my_td; 475 bl = my_bl; 476 bd = my_bd; 477 /* make local copies of globals */ 478 bb = gunzip_bb; /* initialize bit buffer */ 479 k = gunzip_bk; 480 w = gunzip_outbuf_count; /* initialize gunzip_window position */ 481 /* inflate the coded data */ 482 ml = mask_bits[bl]; /* precompute masks for speed */ 483 md = mask_bits[bd]; 484 } 485 /* called once from inflate_get_next_window */ 486 static int inflate_codes(STATE_PARAM_ONLY) 487 { 488 unsigned e; /* table entry flag/number of extra bits */ 489 huft_t *t; /* pointer to table entry */ 490 491 if (resume_copy) goto do_copy; 372 492 373 493 while (1) { /* do until end of block */ 374 b = fill_bitbuffer(b, &k, bl); 375 if ((e = (t = tl + ((unsigned) b & ml))->e) > 16) 494 bb = fill_bitbuffer(PASS_STATE bb, &k, bl); 495 t = tl + ((unsigned) bb & ml); 496 e = t->e; 497 if (e > 16) 376 498 do { 377 499 if (e == 99) { 500 //shouldn't we propagate error? 378 501 bb_error_msg_and_die("inflate_codes error 1"); 379 502 } 380 b >>= t->b;503 bb >>= t->b; 381 504 k -= t->b; 382 505 e -= 16; 383 b = fill_bitbuffer(b, &k, e); 384 } while ((e = 385 (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); 386 b >>= t->b; 506 bb = fill_bitbuffer(PASS_STATE bb, &k, e); 507 t = t->v.t + ((unsigned) bb & mask_bits[e]); 508 e = t->e; 509 } while (e > 16); 510 bb >>= t->b; 387 511 k -= t->b; 388 512 if (e == 16) { /* then it's a literal */ 389 513 gunzip_window[w++] = (unsigned char) t->v.n; 390 if (w == gunzip_wsize) {391 gunzip_outbuf_count = (w);514 if (w == GUNZIP_WSIZE) { 515 gunzip_outbuf_count = w; 392 516 //flush_gunzip_window(); 393 517 w = 0; … … 395 519 } 396 520 } else { /* it's an EOB or a length */ 397 398 521 /* exit if end of block */ 399 522 if (e == 15) { … … 402 525 403 526 /* get length of block to copy */ 404 b = fill_bitbuffer(b, &k, e);405 n = t->v.n + ((unsigned)b & mask_bits[e]);406 b >>= e;527 bb = fill_bitbuffer(PASS_STATE bb, &k, e); 528 nn = t->v.n + ((unsigned) bb & mask_bits[e]); 529 bb >>= e; 407 530 k -= e; 408 531 409 532 /* decode distance of block to copy */ 410 b = fill_bitbuffer(b, &k, bd); 411 if ((e = (t = td + ((unsigned) b & md))->e) > 16) 533 bb = fill_bitbuffer(PASS_STATE bb, &k, bd); 534 t = td + ((unsigned) bb & md); 535 e = t->e; 536 if (e > 16) 412 537 do { 413 538 if (e == 99) 539 //shouldn't we propagate error? 414 540 bb_error_msg_and_die("inflate_codes error 2"); 415 b >>= t->b;541 bb >>= t->b; 416 542 k -= t->b; 417 543 e -= 16; 418 b = fill_bitbuffer(b, &k, e);419 } while ((e =420 (t =421 t->v.t + ((unsigned) b & mask_bits[e]))->e)> 16);422 b >>= t->b;544 bb = fill_bitbuffer(PASS_STATE bb, &k, e); 545 t = t->v.t + ((unsigned) bb & mask_bits[e]); 546 e = t->e; 547 } while (e > 16); 548 bb >>= t->b; 423 549 k -= t->b; 424 b = fill_bitbuffer(b, &k, e);425 d = w - t->v.n - ((unsigned)b & mask_bits[e]);426 b >>= e;550 bb = fill_bitbuffer(PASS_STATE bb, &k, e); 551 dd = w - t->v.n - ((unsigned) bb & mask_bits[e]); 552 bb >>= e; 427 553 k -= e; 428 554 429 555 /* do the copy */ 430 do_copy: do { 431 n -= (e = 432 (e = 433 gunzip_wsize - ((d &= gunzip_wsize - 1) > w ? d : w)) > n ? n : e); 434 /* copy to new buffer to prevent possible overwrite */ 435 if (w - d >= e) { /* (this test assumes unsigned comparison) */ 436 memcpy(gunzip_window + w, gunzip_window + d, e); 556 do_copy: 557 do { 558 /* Was: nn -= (e = (e = GUNZIP_WSIZE - ((dd &= GUNZIP_WSIZE - 1) > w ? dd : w)) > nn ? nn : e); */ 559 /* Who wrote THAT?? rewritten as: */ 560 dd &= GUNZIP_WSIZE - 1; 561 e = GUNZIP_WSIZE - (dd > w ? dd : w); 562 if (e > nn) e = nn; 563 nn -= e; 564 565 /* copy to new buffer to prevent possible overwrite */ 566 if (w - dd >= e) { /* (this test assumes unsigned comparison) */ 567 memcpy(gunzip_window + w, gunzip_window + dd, e); 437 568 w += e; 438 d += e;569 dd += e; 439 570 } else { 440 441 571 /* do it slow to avoid memcpy() overlap */ 572 /* !NOMEMCPY */ 442 573 do { 443 gunzip_window[w++] = gunzip_window[d ++];574 gunzip_window[w++] = gunzip_window[dd++]; 444 575 } while (--e); 445 576 } 446 if (w == gunzip_wsize) { 447 gunzip_outbuf_count = (w); 448 if (n) resumeCopy = 1; 449 else resumeCopy = 0; 577 if (w == GUNZIP_WSIZE) { 578 gunzip_outbuf_count = w; 579 resume_copy = (nn != 0); 450 580 //flush_gunzip_window(); 451 581 w = 0; 452 582 return 1; 453 583 } 454 } while (n );455 resume Copy = 0;584 } while (nn); 585 resume_copy = 0; 456 586 } 457 587 } 458 588 459 589 /* restore the globals from the locals */ 460 gunzip_outbuf_count = w; 461 gunzip_bb = b ;/* restore global bit buffer */590 gunzip_outbuf_count = w; /* restore global gunzip_window pointer */ 591 gunzip_bb = bb; /* restore global bit buffer */ 462 592 gunzip_bk = k; 463 593 … … 470 600 return 0; 471 601 } 472 473 static int inflate_stored(int my_n, int my_b_stored, int my_k_stored, int setup) 474 { 475 static unsigned int n, b_stored, k_stored, w; 476 if (setup) { 477 n = my_n; 478 b_stored = my_b_stored; 479 k_stored = my_k_stored; 480 w = gunzip_outbuf_count; /* initialize gunzip_window position */ 481 return 0; // Don't do anything first time 482 } 483 602 #undef ml 603 #undef md 604 #undef bb 605 #undef k 606 #undef w 607 #undef tl 608 #undef td 609 #undef bl 610 #undef bd 611 #undef nn 612 #undef dd 613 614 615 /* called once from inflate_block */ 616 static void inflate_stored_setup(STATE_PARAM int my_n, int my_b, int my_k) 617 { 618 inflate_stored_n = my_n; 619 inflate_stored_b = my_b; 620 inflate_stored_k = my_k; 621 /* initialize gunzip_window position */ 622 inflate_stored_w = gunzip_outbuf_count; 623 } 624 /* called once from inflate_get_next_window */ 625 static int inflate_stored(STATE_PARAM_ONLY) 626 { 484 627 /* read and output the compressed data */ 485 while ( n--) {486 b_stored = fill_bitbuffer(b_stored, &k_stored, 8);487 gunzip_window[ w++] = (unsigned char) b_stored;488 if ( w == gunzip_wsize) {489 gunzip_outbuf_count = (w);628 while (inflate_stored_n--) { 629 inflate_stored_b = fill_bitbuffer(PASS_STATE inflate_stored_b, &inflate_stored_k, 8); 630 gunzip_window[inflate_stored_w++] = (unsigned char) inflate_stored_b; 631 if (inflate_stored_w == GUNZIP_WSIZE) { 632 gunzip_outbuf_count = inflate_stored_w; 490 633 //flush_gunzip_window(); 491 w = 0;492 b_stored>>= 8;493 k_stored-= 8;634 inflate_stored_w = 0; 635 inflate_stored_b >>= 8; 636 inflate_stored_k -= 8; 494 637 return 1; // We have a block 495 638 } 496 b_stored>>= 8;497 k_stored-= 8;639 inflate_stored_b >>= 8; 640 inflate_stored_k -= 8; 498 641 } 499 642 500 643 /* restore the globals from the locals */ 501 gunzip_outbuf_count = w; /* restore global gunzip_window pointer */502 gunzip_bb = b_stored; /* restore global bit buffer */503 gunzip_bk = k_stored;644 gunzip_outbuf_count = inflate_stored_w; /* restore global gunzip_window pointer */ 645 gunzip_bb = inflate_stored_b; /* restore global bit buffer */ 646 gunzip_bk = inflate_stored_k; 504 647 return 0; // Finished 505 648 } 649 506 650 507 651 /* … … 511 655 * GLOBAL VARIABLES: bb, kk, 512 656 */ 513 // Return values: -1 = inflate_stored, -2 = inflate_codes 514 static int inflate_block(int *e) 657 /* Return values: -1 = inflate_stored, -2 = inflate_codes */ 658 /* One callsite in inflate_get_next_window */ 659 static int inflate_block(STATE_PARAM smallint *e) 515 660 { 516 661 unsigned t; /* block type */ 517 register unsigned intb; /* bit buffer */518 unsigned intk; /* number of bits in bit buffer */662 unsigned b; /* bit buffer */ 663 unsigned k; /* number of bits in bit buffer */ 519 664 520 665 /* make local bit buffer */ … … 524 669 525 670 /* read in last block bit */ 526 b = fill_bitbuffer( b, &k, 1);527 *e = (int)b & 1;671 b = fill_bitbuffer(PASS_STATE b, &k, 1); 672 *e = b & 1; 528 673 b >>= 1; 529 674 k -= 1; 530 675 531 676 /* read in block type */ 532 b = fill_bitbuffer( b, &k, 2);677 b = fill_bitbuffer(PASS_STATE b, &k, 2); 533 678 t = (unsigned) b & 3; 534 679 b >>= 2; … … 543 688 case 0: /* Inflate stored */ 544 689 { 545 unsigned intn; /* number of bytes in block */546 unsigned intb_stored; /* bit buffer */547 unsigned intk_stored; /* number of bits in bit buffer */690 unsigned n; /* number of bytes in block */ 691 unsigned b_stored; /* bit buffer */ 692 unsigned k_stored; /* number of bits in bit buffer */ 548 693 549 694 /* make local copies of globals */ … … 557 702 558 703 /* get the length and its complement */ 559 b_stored = fill_bitbuffer( b_stored, &k_stored, 16);704 b_stored = fill_bitbuffer(PASS_STATE b_stored, &k_stored, 16); 560 705 n = ((unsigned) b_stored & 0xffff); 561 706 b_stored >>= 16; 562 707 k_stored -= 16; 563 708 564 b_stored = fill_bitbuffer( b_stored, &k_stored, 16);709 b_stored = fill_bitbuffer(PASS_STATE b_stored, &k_stored, 16); 565 710 if (n != (unsigned) ((~b_stored) & 0xffff)) { 566 711 return 1; /* error in compressed data */ … … 569 714 k_stored -= 16; 570 715 571 inflate_stored(n, b_stored, k_stored, 1); // Setup inflate_stored 716 inflate_stored_setup(PASS_STATE n, b_stored, k_stored); // Setup inflate_stored 717 572 718 return -1; 573 719 } 574 case 1: /* Inflate fixed575 * decompress an inflated type 1 (fixed Huffman codes) block. We should576 * either replace this with a custom decoder, or at least precompute the577 * Huffman tables.578 720 case 1: 721 /* Inflate fixed 722 * decompress an inflated type 1 (fixed Huffman codes) block. We should 723 * either replace this with a custom decoder, or at least precompute the 724 * Huffman tables. */ 579 725 { 580 726 int i; /* temporary variable */ 581 727 huft_t *tl; /* literal/length code table */ 582 728 huft_t *td; /* distance code table */ 583 unsigned intbl; /* lookup bits for tl */584 unsigned intbd; /* lookup bits for td */585 unsigned intl[288]; /* length list for huft_build */729 unsigned bl; /* lookup bits for tl */ 730 unsigned bd; /* lookup bits for td */ 731 unsigned l[288]; /* length list for huft_build */ 586 732 587 733 /* set up literal table */ … … 599 745 } 600 746 bl = 7; 601 if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) { 747 i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl); 748 if (i != 0) { 602 749 return i; 603 750 } … … 608 755 } 609 756 bd = 5; 610 if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) { 757 i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd); 758 if (i > 1) { 611 759 huft_free(tl); 612 760 return i; … … 614 762 615 763 /* decompress until an end-of-block code */ 616 inflate_codes (tl, td, bl, bd, 1); // Setup inflate_codes764 inflate_codes_setup(PASS_STATE tl, td, bl, bd); // Setup inflate_codes 617 765 618 766 /* huft_free code moved into inflate_codes */ … … 627 775 huft_t *tl; /* literal/length code table */ 628 776 huft_t *td; /* distance code table */ 629 unsigned i nt i; /* temporary variables */630 unsigned intj;631 unsigned intl; /* last length */632 unsigned intm; /* mask for bit lengths table */633 unsigned intn; /* number of lengths to get */634 unsigned intbl; /* lookup bits for tl */635 unsigned intbd; /* lookup bits for td */636 unsigned intnb; /* number of bit length codes */637 unsigned intnl; /* number of literal/length codes */638 unsigned intnd; /* number of distance codes */639 640 unsigned intll[286 + 30]; /* literal/length and distance code lengths */641 unsigned intb_dynamic; /* bit buffer */642 unsigned intk_dynamic; /* number of bits in bit buffer */777 unsigned i; /* temporary variables */ 778 unsigned j; 779 unsigned l; /* last length */ 780 unsigned m; /* mask for bit lengths table */ 781 unsigned n; /* number of lengths to get */ 782 unsigned bl; /* lookup bits for tl */ 783 unsigned bd; /* lookup bits for td */ 784 unsigned nb; /* number of bit length codes */ 785 unsigned nl; /* number of literal/length codes */ 786 unsigned nd; /* number of distance codes */ 787 788 unsigned ll[286 + 30]; /* literal/length and distance code lengths */ 789 unsigned b_dynamic; /* bit buffer */ 790 unsigned k_dynamic; /* number of bits in bit buffer */ 643 791 644 792 /* make local bit buffer */ … … 647 795 648 796 /* read in table lengths */ 649 b_dynamic = fill_bitbuffer( b_dynamic, &k_dynamic, 5);650 nl = 257 + ((unsigned int) b_dynamic & 0x1f); /* number of literal/length codes */797 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5); 798 nl = 257 + ((unsigned) b_dynamic & 0x1f); /* number of literal/length codes */ 651 799 652 800 b_dynamic >>= 5; 653 801 k_dynamic -= 5; 654 b_dynamic = fill_bitbuffer( b_dynamic, &k_dynamic, 5);655 nd = 1 + ((unsigned int) b_dynamic & 0x1f); /* number of distance codes */802 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5); 803 nd = 1 + ((unsigned) b_dynamic & 0x1f); /* number of distance codes */ 656 804 657 805 b_dynamic >>= 5; 658 806 k_dynamic -= 5; 659 b_dynamic = fill_bitbuffer( b_dynamic, &k_dynamic, 4);660 nb = 4 + ((unsigned int) b_dynamic & 0xf); /* number of bit length codes */807 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 4); 808 nb = 4 + ((unsigned) b_dynamic & 0xf); /* number of bit length codes */ 661 809 662 810 b_dynamic >>= 4; … … 668 816 /* read in bit-length-code lengths */ 669 817 for (j = 0; j < nb; j++) { 670 b_dynamic = fill_bitbuffer( b_dynamic, &k_dynamic, 3);671 ll[border[j]] = (unsigned int) b_dynamic & 7;818 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 3); 819 ll[border[j]] = (unsigned) b_dynamic & 7; 672 820 b_dynamic >>= 3; 673 821 k_dynamic -= 3; … … 691 839 m = mask_bits[bl]; 692 840 i = l = 0; 693 while ((unsigned int) i < n) {694 b_dynamic = fill_bitbuffer( b_dynamic, &k_dynamic, (unsigned int)bl);695 j = (td = tl + ((unsigned int) b_dynamic & m))->b;841 while ((unsigned) i < n) { 842 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, (unsigned)bl); 843 j = (td = tl + ((unsigned) b_dynamic & m))->b; 696 844 b_dynamic >>= j; 697 845 k_dynamic -= j; … … 700 848 ll[i++] = l = j; /* save last length in l */ 701 849 } else if (j == 16) { /* repeat last length 3 to 6 times */ 702 b_dynamic = fill_bitbuffer( b_dynamic, &k_dynamic, 2);703 j = 3 + ((unsigned int) b_dynamic & 3);850 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 2); 851 j = 3 + ((unsigned) b_dynamic & 3); 704 852 b_dynamic >>= 2; 705 853 k_dynamic -= 2; 706 if ((unsigned int) i + j > n) {854 if ((unsigned) i + j > n) { 707 855 return 1; 708 856 } … … 711 859 } 712 860 } else if (j == 17) { /* 3 to 10 zero length codes */ 713 b_dynamic = fill_bitbuffer( b_dynamic, &k_dynamic, 3);714 j = 3 + ((unsigned int) b_dynamic & 7);861 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 3); 862 j = 3 + ((unsigned) b_dynamic & 7); 715 863 b_dynamic >>= 3; 716 864 k_dynamic -= 3; 717 if ((unsigned int) i + j > n) {865 if ((unsigned) i + j > n) { 718 866 return 1; 719 867 } … … 723 871 l = 0; 724 872 } else { /* j == 18: 11 to 138 zero length codes */ 725 b_dynamic = fill_bitbuffer( b_dynamic, &k_dynamic, 7);726 j = 11 + ((unsigned int) b_dynamic & 0x7f);873 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 7); 874 j = 11 + ((unsigned) b_dynamic & 0x7f); 727 875 b_dynamic >>= 7; 728 876 k_dynamic -= 7; 729 if ((unsigned int) i + j > n) {877 if ((unsigned) i + j > n) { 730 878 return 1; 731 879 } … … 747 895 bl = lbits; 748 896 749 if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) { 897 i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl); 898 if (i != 0) { 750 899 if (i == 1) { 751 bb_error_msg_and_die("Incomplete literal tree"); 752 huft_free(tl); 900 //shouldn't we propagate error? 901 bb_error_msg_and_die("incomplete literal tree"); 902 /* huft_free(tl); */ 753 903 } 754 904 return i; /* incomplete code set */ … … 756 906 757 907 bd = dbits; 758 if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) { 908 i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd); 909 if (i != 0) { 759 910 if (i == 1) { 911 //shouldn't we propagate error? 760 912 bb_error_msg_and_die("incomplete distance tree"); 761 huft_free(td);913 /* huft_free(td); */ 762 914 } 763 915 huft_free(tl); … … 766 918 767 919 /* decompress until an end-of-block code */ 768 inflate_codes (tl, td, bl, bd, 1); // Setup inflate_codes920 inflate_codes_setup(PASS_STATE tl, td, bl, bd); // Setup inflate_codes 769 921 770 922 /* huft_free code moved into inflate_codes */ … … 774 926 default: 775 927 /* bad block type */ 776 bb_error_msg_and_die("bad block type %d\n", t); 777 } 778 } 779 780 static void calculate_gunzip_crc(void) 928 //shouldn't we propagate error? 929 bb_error_msg_and_die("bad block type %d", t); 930 } 931 } 932 933 /* Two callsites, both in inflate_get_next_window */ 934 static void calculate_gunzip_crc(STATE_PARAM_ONLY) 781 935 { 782 936 int n; … … 787 941 } 788 942 789 static int inflate_get_next_window(void) 790 { 791 static int method = -1; // Method == -1 for stored, -2 for codes 792 static int e = 0; 793 static int needAnotherBlock = 1; 794 943 /* One callsite in inflate_unzip_internal */ 944 static int inflate_get_next_window(STATE_PARAM_ONLY) 945 { 795 946 gunzip_outbuf_count = 0; 796 947 797 while (1) {948 while (1) { 798 949 int ret; 799 950 800 if (need AnotherBlock) {801 if (e) {802 calculate_gunzip_crc( );803 e = 0;804 need AnotherBlock = 1;805 return 0; 806 } // Last block807 method = inflate_block( &e);808 need AnotherBlock = 0;951 if (need_another_block) { 952 if (end_reached) { 953 calculate_gunzip_crc(PASS_STATE_ONLY); 954 end_reached = 0; 955 need_another_block = 1; 956 return 0; /* Last block */ 957 } 958 method = inflate_block(PASS_STATE &end_reached); 959 need_another_block = 0; 809 960 } 810 961 811 962 switch (method) { 812 case -1: ret = inflate_stored(0,0,0,0); 813 break; 814 case -2: ret = inflate_codes(0,0,0,0,0); 815 break; 816 default: bb_error_msg_and_die("inflate error %d", method); 963 case -1: 964 ret = inflate_stored(PASS_STATE_ONLY); 965 break; 966 case -2: 967 ret = inflate_codes(PASS_STATE_ONLY); 968 break; 969 default: 970 //shouldn't we propagate error? 971 bb_error_msg_and_die("inflate error %d", method); 817 972 } 818 973 819 974 if (ret == 1) { 820 calculate_gunzip_crc( );975 calculate_gunzip_crc(PASS_STATE_ONLY); 821 976 return 1; // More data left 822 } else needAnotherBlock = 1; // End of that block 977 } 978 need_another_block = 1; // End of that block 823 979 } 824 980 /* Doesnt get here */ 825 981 } 826 982 827 /* Initialise bytebuffer, be careful not to overfill the buffer */ 828 void inflate_init(unsigned int bufsize) 829 { 830 /* Set the bytebuffer size, default is same as gunzip_wsize */ 831 bytebuffer_max = bufsize + 8; 832 bytebuffer_offset = 4; 833 bytebuffer_size = 0; 834 } 835 836 void inflate_cleanup(void) 837 { 838 free(bytebuffer); 839 } 840 841 int inflate_unzip(int in, int out) 842 { 983 984 /* Called from unpack_gz_stream() and inflate_unzip() */ 985 /* NB: bytebuffer is allocated here but freeing it is left to the caller! */ 986 static USE_DESKTOP(long long) int 987 inflate_unzip_internal(STATE_PARAM int in, int out) 988 { 989 USE_DESKTOP(long long) int n = 0; 843 990 ssize_t nwrote; 844 typedef void (*sig_type) (int);845 991 846 992 /* Allocate all global buffers (for DYN_ALLOC option) */ 847 gunzip_window = xmalloc( gunzip_wsize);993 gunzip_window = xmalloc(GUNZIP_WSIZE); 848 994 gunzip_outbuf_count = 0; 849 995 gunzip_bytes_out = 0; … … 855 1001 856 1002 /* Create the crc table */ 857 gunzip_crc_table = bb_crc32_filltable(0);1003 gunzip_crc_table = crc32_filltable(NULL, 0); 858 1004 gunzip_crc = ~0; 859 1005 860 1006 /* Allocate space for buffer */ 861 1007 bytebuffer = xmalloc(bytebuffer_max); 862 1008 863 while (1) {864 int r et = inflate_get_next_window();865 nwrote = bb_full_write(out, gunzip_window, gunzip_outbuf_count);866 if (nwrote == -1) {1009 while (1) { 1010 int r = inflate_get_next_window(PASS_STATE_ONLY); 1011 nwrote = full_write(out, gunzip_window, gunzip_outbuf_count); 1012 if (nwrote != gunzip_outbuf_count) { 867 1013 bb_perror_msg("write"); 868 return -1; 869 } 870 if (ret == 0) break; 871 } 872 873 /* Cleanup */ 874 free(gunzip_window); 875 free(gunzip_crc_table); 1014 n = -1; 1015 goto ret; 1016 } 1017 USE_DESKTOP(n += nwrote;) 1018 if (r == 0) break; 1019 } 876 1020 877 1021 /* Store unused bytes in a global buffer so calling applets can access it */ … … 884 1028 gunzip_bk -= 8; 885 1029 } 886 return 0; 887 } 888 889 int inflate_gunzip(int in, int out) 1030 ret: 1031 /* Cleanup */ 1032 free(gunzip_window); 1033 free(gunzip_crc_table); 1034 return n; 1035 } 1036 1037 1038 USE_DESKTOP(long long) int 1039 inflate_unzip(inflate_unzip_result *res, unsigned bufsize, int in, int out) 1040 { 1041 USE_DESKTOP(long long) int n; 1042 DECLARE_STATE; 1043 1044 ALLOC_STATE; 1045 1046 bytebuffer_max = bufsize + 8; 1047 bytebuffer_offset = 4; 1048 n = inflate_unzip_internal(PASS_STATE in, out); 1049 1050 res->crc = gunzip_crc; 1051 res->bytes_out = gunzip_bytes_out; 1052 free(bytebuffer); 1053 DEALLOC_STATE; 1054 return n; 1055 } 1056 1057 1058 USE_DESKTOP(long long) int 1059 unpack_gz_stream(int in, int out) 890 1060 { 891 1061 uint32_t stored_crc = 0; 892 unsigned int count; 893 894 inflate_unzip(in, out); 1062 unsigned count; 1063 USE_DESKTOP(long long) int n; 1064 DECLARE_STATE; 1065 1066 ALLOC_STATE; 1067 1068 bytebuffer_max = 0x8000; 1069 n = inflate_unzip_internal(PASS_STATE in, out); 1070 1071 if (n < 0) goto ret; 895 1072 896 1073 /* top up the input buffer with the rest of the trailer */ 897 1074 count = bytebuffer_size - bytebuffer_offset; 898 1075 if (count < 8) { 899 bb_xread_all(in, &bytebuffer[bytebuffer_size], 8 - count); 1076 xread(in, &bytebuffer[bytebuffer_size], 8 - count); 1077 //shouldn't we propagate error? 900 1078 bytebuffer_size += 8 - count; 901 1079 } … … 908 1086 if (stored_crc != (~gunzip_crc)) { 909 1087 bb_error_msg("crc error"); 910 return -1; 1088 n = -1; 1089 goto ret; 911 1090 } 912 1091 … … 914 1093 if (gunzip_bytes_out != 915 1094 (bytebuffer[bytebuffer_offset] | (bytebuffer[bytebuffer_offset+1] << 8) | 916 (bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))) { 917 bb_error_msg("Incorrect length"); 918 return -1; 919 } 920 921 return 0; 922 } 1095 (bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24)) 1096 ) { 1097 bb_error_msg("incorrect length"); 1098 n = -1; 1099 } 1100 ret: 1101 free(bytebuffer); 1102 DEALLOC_STATE; 1103 return n; 1104 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/filter_accept_all.c
r821 r1765 6 6 */ 7 7 8 #include <stdlib.h>8 #include "libbb.h" 9 9 #include "unarchive.h" 10 10 … … 12 12 char filter_accept_all(archive_handle_t *archive_handle) 13 13 { 14 if (archive_handle->file_header->name) { 15 return(EXIT_SUCCESS); 16 } else { 17 return(EXIT_FAILURE); 18 } 14 if (archive_handle->file_header->name) 15 return EXIT_SUCCESS; 16 return EXIT_FAILURE; 19 17 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/filter_accept_list.c
r821 r1765 6 6 */ 7 7 8 #include <stdlib.h>8 #include "libbb.h" 9 9 #include "unarchive.h" 10 10 … … 14 14 char filter_accept_list(archive_handle_t *archive_handle) 15 15 { 16 if (find_list_entry(archive_handle->accept, archive_handle->file_header->name)) { 17 return(EXIT_SUCCESS); 18 } else { 19 return(EXIT_FAILURE); 20 } 16 if (find_list_entry(archive_handle->accept, archive_handle->file_header->name)) 17 return EXIT_SUCCESS; 18 return EXIT_FAILURE; 21 19 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/filter_accept_list_reassign.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * Copyright (C) 2002 by Glenn McGrath 3 4 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 17 6 */ 18 19 #include <stdlib.h>20 #include <string.h>21 #include <unistd.h>22 7 23 8 #include "libbb.h" … … 25 10 26 11 /* 27 * 28 * 29 * 12 * Reassign the subarchive metadata parser based on the filename extension 13 * e.g. if its a .tar.gz modify archive_handle->sub_archive to process a .tar.gz 14 * or if its a .tar.bz2 make archive_handle->sub_archive handle that 30 15 */ 31 16 char filter_accept_list_reassign(archive_handle_t *archive_handle) … … 39 24 40 25 /* Modify the subarchive handler based on the extension */ 41 #if def CONFIG_FEATURE_DEB_TAR_GZ26 #if ENABLE_FEATURE_DEB_TAR_GZ 42 27 if (strcmp(name_ptr, ".gz") == 0) { 43 28 archive_handle->action_data_subarchive = get_header_tar_gz; 44 return (EXIT_SUCCESS);29 return EXIT_SUCCESS; 45 30 } 46 31 #endif 47 #if def CONFIG_FEATURE_DEB_TAR_BZ232 #if ENABLE_FEATURE_DEB_TAR_BZ2 48 33 if (strcmp(name_ptr, ".bz2") == 0) { 49 34 archive_handle->action_data_subarchive = get_header_tar_bz2; 50 return (EXIT_SUCCESS);35 return EXIT_SUCCESS; 51 36 } 52 37 #endif 53 38 if (ENABLE_FEATURE_DEB_TAR_LZMA && !strcmp(name_ptr, ".lzma")) { 54 39 archive_handle->action_data_subarchive = get_header_tar_lzma; 55 return (EXIT_SUCCESS);40 return EXIT_SUCCESS; 56 41 } 57 42 } 58 return (EXIT_FAILURE);43 return EXIT_FAILURE; 59 44 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/filter_accept_reject_list.c
r821 r1765 6 6 */ 7 7 8 #include <stdlib.h>8 #include "libbb.h" 9 9 #include "unarchive.h" 10 10 … … 15 15 { 16 16 const char *key = archive_handle->file_header->name; 17 const llist_t *reject_entry = find_list_entry (archive_handle->reject, key);17 const llist_t *reject_entry = find_list_entry2(archive_handle->reject, key); 18 18 const llist_t *accept_entry; 19 19 20 20 /* If the key is in a reject list fail */ 21 21 if (reject_entry) { 22 return (EXIT_FAILURE);22 return EXIT_FAILURE; 23 23 } 24 accept_entry = find_list_entry (archive_handle->accept, key);24 accept_entry = find_list_entry2(archive_handle->accept, key); 25 25 26 26 /* Fail if an accept list was specified and the key wasnt in there */ 27 27 if ((accept_entry == NULL) && archive_handle->accept) { 28 return (EXIT_FAILURE);28 return EXIT_FAILURE; 29 29 } 30 30 31 31 /* Accepted */ 32 return (EXIT_SUCCESS);32 return EXIT_SUCCESS; 33 33 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/find_list_entry.c
r902 r1765 7 7 8 8 #include <fnmatch.h> 9 #include <stdlib.h>9 #include "libbb.h" 10 10 #include "unarchive.h" 11 11 12 /* Find a string in a list */12 /* Find a string in a shell pattern list */ 13 13 const llist_t *find_list_entry(const llist_t *list, const char *filename) 14 14 { 15 15 while (list) { 16 if (fnmatch(list->data, filename, FNM_LEADING_DIR) == 0) {17 return (list);16 if (fnmatch(list->data, filename, 0) == 0) { 17 return list; 18 18 } 19 19 list = list->link; 20 20 } 21 return (NULL);21 return NULL; 22 22 } 23 24 /* Same, but compares only path components present in pattern 25 * (extra trailing path components in filename are assumed to match) 26 */ 27 const llist_t *find_list_entry2(const llist_t *list, const char *filename) 28 { 29 char buf[PATH_MAX]; 30 int pattern_slash_cnt; 31 const char *c; 32 char *d; 33 34 while (list) { 35 c = list->data; 36 pattern_slash_cnt = 0; 37 while (*c) 38 if (*c++ == '/') pattern_slash_cnt++; 39 c = filename; 40 d = buf; 41 /* paranoia is better that buffer overflows */ 42 while (*c && d != buf + sizeof(buf)-1) { 43 if (*c == '/' && --pattern_slash_cnt < 0) 44 break; 45 *d++ = *c++; 46 } 47 *d = '\0'; 48 if (fnmatch(list->data, buf, 0) == 0) { 49 return list; 50 } 51 list = list->link; 52 } 53 return NULL; 54 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_ar.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* Copyright 2001 Glenn McGrath. 2 3 * … … 4 5 */ 5 6 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <unistd.h> 7 #include "libbb.h" 10 8 #include "unarchive.h" 11 #include "libbb.h"12 9 13 10 char get_header_ar(archive_handle_t *archive_handle) 14 11 { 12 int err; 15 13 file_header_t *typed = archive_handle->file_header; 16 14 union { … … 24 22 char size[10]; 25 23 char magic[2]; 26 } format ed;24 } formatted; 27 25 } ar; 28 #if def CONFIG_FEATURE_AR_LONG_FILENAMES26 #if ENABLE_FEATURE_AR_LONG_FILENAMES 29 27 static char *ar_long_names; 30 static unsigned intar_long_name_size;28 static unsigned ar_long_name_size; 31 29 #endif 32 30 33 /* dont use bb_xread as we want to handle the error ourself */31 /* dont use xread as we want to handle the error ourself */ 34 32 if (read(archive_handle->src_fd, ar.raw, 60) != 60) { 35 33 /* End Of File */ 36 return (EXIT_FAILURE);34 return EXIT_FAILURE; 37 35 } 38 36 … … 43 41 /* fix up the header, we started reading 1 byte too early */ 44 42 memmove(ar.raw, &ar.raw[1], 59); 45 ar.raw[59] = bb_xread_char(archive_handle->src_fd);43 ar.raw[59] = xread_char(archive_handle->src_fd); 46 44 archive_handle->offset++; 47 45 } … … 49 47 50 48 /* align the headers based on the header magic */ 51 if ((ar.formated.magic[0] != '`') || (ar.formated.magic[1] != '\n')) { 52 bb_error_msg_and_die("Invalid ar header"); 53 } 49 if (ar.formatted.magic[0] != '`' || ar.formatted.magic[1] != '\n') 50 bb_error_msg_and_die("invalid ar header"); 54 51 55 typed->mode = strtol(ar.formated.mode, NULL, 8); 56 typed->mtime = atoi(ar.formated.date); 57 typed->uid = atoi(ar.formated.uid); 58 typed->gid = atoi(ar.formated.gid); 59 typed->size = atoi(ar.formated.size); 52 /* FIXME: more thorough routine would be in order here */ 53 /* (we have something like that in tar) */ 54 /* but for now we are lax. This code works because */ 55 /* on misformatted numbers bb_strtou returns all-ones */ 56 typed->mode = err = bb_strtou(ar.formatted.mode, NULL, 8); 57 if (err == -1) bb_error_msg_and_die("invalid ar header"); 58 typed->mtime = err = bb_strtou(ar.formatted.date, NULL, 10); 59 if (err == -1) bb_error_msg_and_die("invalid ar header"); 60 typed->uid = err = bb_strtou(ar.formatted.uid, NULL, 10); 61 if (err == -1) bb_error_msg_and_die("invalid ar header"); 62 typed->gid = err = bb_strtou(ar.formatted.gid, NULL, 10); 63 if (err == -1) bb_error_msg_and_die("invalid ar header"); 64 typed->size = err = bb_strtou(ar.formatted.size, NULL, 10); 65 if (err == -1) bb_error_msg_and_die("invalid ar header"); 60 66 61 67 /* long filenames have '/' as the first character */ 62 if (ar.formated.name[0] == '/') { 63 #ifdef CONFIG_FEATURE_AR_LONG_FILENAMES 64 if (ar.formated.name[1] == '/') { 68 if (ar.formatted.name[0] == '/') { 69 #if ENABLE_FEATURE_AR_LONG_FILENAMES 70 unsigned long_offset; 71 72 if (ar.formatted.name[1] == '/') { 65 73 /* If the second char is a '/' then this entries data section 66 74 * stores long filename for multiple entries, they are stored … … 68 76 ar_long_name_size = typed->size; 69 77 ar_long_names = xmalloc(ar_long_name_size); 70 bb_xread_all(archive_handle->src_fd, ar_long_names, ar_long_name_size);78 xread(archive_handle->src_fd, ar_long_names, ar_long_name_size); 71 79 archive_handle->offset += ar_long_name_size; 72 80 /* This ar entries data section only contained filenames for other records 73 81 * they are stored in the static ar_long_names for future reference */ 74 return (get_header_ar(archive_handle)); /* Return next header */ 75 } else if (ar.formated.name[1] == ' ') { 82 return get_header_ar(archive_handle); /* Return next header */ 83 } 84 85 if (ar.formatted.name[1] == ' ') { 76 86 /* This is the index of symbols in the file for compilers */ 77 87 data_skip(archive_handle); 78 88 archive_handle->offset += typed->size; 79 return (get_header_ar(archive_handle)); /* Return next header */ 80 } else { 81 /* The number after the '/' indicates the offset in the ar data section 82 (saved in variable long_name) that conatains the real filename */ 83 const unsigned int long_offset = atoi(&ar.formated.name[1]); 84 if (long_offset >= ar_long_name_size) { 85 bb_error_msg_and_die("Cant resolve long filename"); 86 } 87 typed->name = bb_xstrdup(ar_long_names + long_offset); 89 return get_header_ar(archive_handle); /* Return next header */ 88 90 } 91 92 /* The number after the '/' indicates the offset in the ar data section 93 * (saved in variable long_name) that conatains the real filename */ 94 long_offset = atoi(&ar.formatted.name[1]); 95 if (long_offset >= ar_long_name_size) { 96 bb_error_msg_and_die("can't resolve long filename"); 97 } 98 typed->name = xstrdup(ar_long_names + long_offset); 89 99 #else 90 100 bb_error_msg_and_die("long filenames not supported"); … … 92 102 } else { 93 103 /* short filenames */ 94 typed->name = bb_xstrndup(ar.formated.name, 16);104 typed->name = xstrndup(ar.formatted.name, 16); 95 105 } 96 106 … … 100 110 archive_handle->action_header(typed); 101 111 if (archive_handle->sub_archive) { 102 while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS); 112 while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS) 113 /* repeat */; 103 114 } else { 104 115 archive_handle->action_data(archive_handle); … … 112 123 lseek(archive_handle->src_fd, archive_handle->offset, SEEK_SET); 113 124 114 return (EXIT_SUCCESS);125 return EXIT_SUCCESS; 115 126 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_cpio.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* Copyright 2002 Laurence Anderson 2 3 * … … 4 5 */ 5 6 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <unistd.h> 10 #include <sys/sysmacros.h> /* major() and minor() */ 7 #include "libbb.h" 11 8 #include "unarchive.h" 12 #include "libbb.h"13 9 14 10 typedef struct hardlinks_s { 15 file_header_t *entry;11 char *name; 16 12 int inode; 17 13 struct hardlinks_s *next; … … 21 17 { 22 18 static hardlinks_t *saved_hardlinks = NULL; 23 static unsigned short pending_hardlinks = 0; 19 static unsigned pending_hardlinks = 0; 20 static int inode; 21 24 22 file_header_t *file_header = archive_handle->file_header; 25 23 char cpio_header[110]; 26 24 int namesize; 27 25 char dummy[16]; 28 int major, minor, nlink , inode;26 int major, minor, nlink; 29 27 30 28 if (pending_hardlinks) { /* Deal with any pending hardlinks */ 31 hardlinks_t *tmp; 32 hardlinks_t *oldtmp; 29 hardlinks_t *tmp, *oldtmp; 33 30 34 31 tmp = saved_hardlinks; 35 32 oldtmp = NULL; 36 33 34 file_header->link_target = file_header->name; 35 file_header->size = 0; 36 37 37 while (tmp) { 38 bb_error_msg_and_die("need to fix this\n"); 39 if (tmp->entry->link_name) { /* Found a hardlink ready to be extracted */ 40 file_header = tmp->entry; 41 if (oldtmp) { 42 oldtmp->next = tmp->next; /* Remove item from linked list */ 43 } else { 44 saved_hardlinks = tmp->next; 45 } 46 free(tmp); 38 if (tmp->inode != inode) { 39 tmp = tmp->next; 47 40 continue; 48 41 } 42 43 file_header->name = tmp->name; 44 45 if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { 46 archive_handle->action_data(archive_handle); 47 archive_handle->action_header(archive_handle->file_header); 48 } 49 50 pending_hardlinks--; 51 49 52 oldtmp = tmp; 50 53 tmp = tmp->next; 54 free(oldtmp->name); 55 free(oldtmp); 56 if (oldtmp == saved_hardlinks) 57 saved_hardlinks = tmp; 51 58 } 52 pending_hardlinks = 0; /* No more pending hardlinks, read next file entry */ 59 60 file_header->name = file_header->link_target; 61 62 if (pending_hardlinks > 1) { 63 bb_error_msg("error resolving hardlink: archive made by GNU cpio 2.0-2.2?"); 64 } 65 66 /* No more pending hardlinks, read next file entry */ 67 pending_hardlinks = 0; 53 68 } 54 69 … … 57 72 58 73 if (archive_xread_all_eof(archive_handle, (unsigned char*)cpio_header, 110) == 0) { 59 return (EXIT_FAILURE);74 return EXIT_FAILURE; 60 75 } 61 76 archive_handle->offset += 110; 62 77 63 if ((strncmp(&cpio_header[0], "07070", 5) != 0) || ((cpio_header[5] != '1') && (cpio_header[5] != '2'))) { 64 bb_error_msg_and_die("Unsupported cpio format, use newc or crc"); 78 if (strncmp(&cpio_header[0], "07070", 5) != 0 79 || (cpio_header[5] != '1' && cpio_header[5] != '2') 80 ) { 81 bb_error_msg_and_die("unsupported cpio format, use newc or crc"); 65 82 } 66 83 67 84 { 68 69 85 unsigned long tmpsize; 86 sscanf(cpio_header, "%6c%8x%8x%8x%8x%8x%8lx%8lx%16c%8x%8x%8x%8c", 70 87 dummy, &inode, (unsigned int*)&file_header->mode, 71 88 (unsigned int*)&file_header->uid, (unsigned int*)&file_header->gid, 72 89 &nlink, &file_header->mtime, &tmpsize, 73 90 dummy, &major, &minor, &namesize, dummy); 74 91 file_header->size = tmpsize; 75 92 } 76 93 77 file_header->name = (char *) xzalloc(namesize + 1); 78 archive_xread_all(archive_handle, file_header->name, namesize); /* Read in filename */ 94 free(file_header->name); 95 file_header->name = xzalloc(namesize + 1); 96 /* Read in filename */ 97 xread(archive_handle->src_fd, file_header->name, namesize); 79 98 archive_handle->offset += namesize; 80 99 … … 83 102 84 103 if (strcmp(file_header->name, "TRAILER!!!") == 0) { 85 printf("%d blocks\n", (int) (archive_handle->offset % 512 ? (archive_handle->offset / 512) + 1 : archive_handle->offset / 512)); /* Always round up */ 104 /* Always round up */ 105 printf("%d blocks\n", (int) (archive_handle->offset % 512 ? 106 archive_handle->offset / 512 + 1 : 107 archive_handle->offset / 512 108 )); 86 109 if (saved_hardlinks) { /* Bummer - we still have unresolved hardlinks */ 87 110 hardlinks_t *tmp = saved_hardlinks; 88 111 hardlinks_t *oldtmp = NULL; 89 112 while (tmp) { 90 bb_error_msg("%s not created: cannot resolve hardlink", tmp-> entry->name);113 bb_error_msg("%s not created: cannot resolve hardlink", tmp->name); 91 114 oldtmp = tmp; 92 115 tmp = tmp->next; 93 free (oldtmp->entry->name); 94 free (oldtmp->entry); 95 free (oldtmp); 116 free(oldtmp->name); 117 free(oldtmp); 96 118 } 97 119 saved_hardlinks = NULL; 98 120 pending_hardlinks = 0; 99 121 } 100 return (EXIT_FAILURE);122 return EXIT_FAILURE; 101 123 } 102 124 103 125 if (S_ISLNK(file_header->mode)) { 104 file_header->link_ name = (char *)xzalloc(file_header->size + 1);105 archive_xread_all(archive_handle, file_header->link_name, file_header->size);126 file_header->link_target = xzalloc(file_header->size + 1); 127 xread(archive_handle->src_fd, file_header->link_target, file_header->size); 106 128 archive_handle->offset += file_header->size; 107 129 file_header->size = 0; /* Stop possible seeks in future */ 108 130 } else { 109 file_header->link_ name= NULL;131 file_header->link_target = NULL; 110 132 } 111 133 if (nlink > 1 && !S_ISDIR(file_header->mode)) { … … 114 136 new->next = saved_hardlinks; 115 137 new->inode = inode; 116 new->entry = file_header; 138 /* name current allocated, freed later */ 139 new->name = file_header->name; 140 file_header->name = NULL; 117 141 saved_hardlinks = new; 118 return(EXIT_SUCCESS); // Skip this one 119 } else { /* Found the file with data in */ 120 hardlinks_t *tmp = saved_hardlinks; 121 pending_hardlinks = 1; 122 while (tmp) { 123 if (tmp->inode == inode) { 124 tmp->entry->link_name = bb_xstrdup(file_header->name); 125 nlink--; 126 } 127 tmp = tmp->next; 128 } 129 if (nlink > 1) { 130 bb_error_msg("error resolving hardlink: did you create the archive with GNU cpio 2.0-2.2?"); 131 } 142 return EXIT_SUCCESS; /* Skip this one */ 132 143 } 144 /* Found the file with data in */ 145 pending_hardlinks = nlink; 133 146 } 134 147 file_header->device = makedev(major, minor); … … 143 156 archive_handle->offset += file_header->size; 144 157 145 free(file_header->link_ name);158 free(file_header->link_target); 146 159 147 return (EXIT_SUCCESS);160 return EXIT_SUCCESS; 148 161 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_tar.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 2 3 * … … 11 12 */ 12 13 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <sys/sysmacros.h> /* For makedev */ 14 #include "libbb.h" 17 15 #include "unarchive.h" 18 #include "libbb.h" 19 20 #ifdef CONFIG_FEATURE_TAR_GNU_EXTENSIONS 21 static char *longname = NULL; 22 static char *linkname = NULL; 23 #endif 24 16 17 #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 18 static char *longname; 19 static char *linkname; 20 #else 21 enum { 22 longname = 0, 23 linkname = 0, 24 }; 25 #endif 26 27 /* NB: _DESTROYS_ str[len] character! */ 28 static unsigned long long getOctal(char *str, int len) 29 { 30 unsigned long long v; 31 /* Actually, tar header allows leading spaces also. 32 * Oh well, we will be liberal and skip this... 33 * The only downside probably is that we allow "-123" too :) 34 if (*str < '0' || *str > '7') 35 bb_error_msg_and_die("corrupted octal value in tar header"); 36 */ 37 str[len] = '\0'; 38 v = strtoull(str, &str, 8); 39 if (*str && (!ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY || *str != ' ')) 40 bb_error_msg_and_die("corrupted octal value in tar header"); 41 return v; 42 } 43 #define GET_OCTAL(a) getOctal((a), sizeof(a)) 44 45 void BUG_tar_header_size(void); 25 46 char get_header_tar(archive_handle_t *archive_handle) 26 47 { 48 static smallint end; 49 27 50 file_header_t *file_header = archive_handle->file_header; 28 union{51 struct { 29 52 /* ustar header, Posix 1003.1 */ 30 unsigned char raw[512]; 31 struct { 32 char name[100]; /* 0-99 */ 33 char mode[8]; /* 100-107 */ 34 char uid[8]; /* 108-115 */ 35 char gid[8]; /* 116-123 */ 36 char size[12]; /* 124-135 */ 37 char mtime[12]; /* 136-147 */ 38 char chksum[8]; /* 148-155 */ 39 char typeflag; /* 156-156 */ 40 char linkname[100]; /* 157-256 */ 41 char magic[6]; /* 257-262 */ 42 char version[2]; /* 263-264 */ 43 char uname[32]; /* 265-296 */ 44 char gname[32]; /* 297-328 */ 45 char devmajor[8]; /* 329-336 */ 46 char devminor[8]; /* 337-344 */ 47 char prefix[155]; /* 345-499 */ 48 char padding[12]; /* 500-512 */ 49 } formated; 53 char name[100]; /* 0-99 */ 54 char mode[8]; /* 100-107 */ 55 char uid[8]; /* 108-115 */ 56 char gid[8]; /* 116-123 */ 57 char size[12]; /* 124-135 */ 58 char mtime[12]; /* 136-147 */ 59 char chksum[8]; /* 148-155 */ 60 char typeflag; /* 156-156 */ 61 char linkname[100]; /* 157-256 */ 62 char magic[6]; /* 257-262 */ 63 char version[2]; /* 263-264 */ 64 char uname[32]; /* 265-296 */ 65 char gname[32]; /* 297-328 */ 66 char devmajor[8]; /* 329-336 */ 67 char devminor[8]; /* 337-344 */ 68 char prefix[155]; /* 345-499 */ 69 char padding[12]; /* 500-512 */ 50 70 } tar; 51 long sum = 0; 52 long i; 53 static int end = 0; 54 71 char *cp; 72 int i, sum_u, sum; 73 #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY 74 int sum_s; 75 #endif 76 int parse_names; 77 78 if (sizeof(tar) != 512) 79 BUG_tar_header_size(); 80 81 #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 82 again: 83 #endif 55 84 /* Align header */ 56 85 data_align(archive_handle, 512); 57 86 58 if (bb_full_read(archive_handle->src_fd, tar.raw, 512) != 512) { 59 /* Assume end of file */ 60 bb_error_msg_and_die("Short header"); 61 //return(EXIT_FAILURE); 62 } 87 again_after_align: 88 89 xread(archive_handle->src_fd, &tar, 512); 63 90 archive_handle->offset += 512; 64 91 65 92 /* If there is no filename its an empty header */ 66 if (tar. formated.name[0] == 0) {93 if (tar.name[0] == 0) { 67 94 if (end) { 68 95 /* This is the second consecutive empty header! End of archive! 69 96 * Read until the end to empty the pipe from gz or bz2 70 97 */ 71 while (bb_full_read(archive_handle->src_fd, tar.raw, 512) == 512); 72 return(EXIT_FAILURE); 98 while (full_read(archive_handle->src_fd, &tar, 512) == 512) 99 /* repeat */; 100 return EXIT_FAILURE; 73 101 } 74 102 end = 1; 75 return (EXIT_SUCCESS);103 return EXIT_SUCCESS; 76 104 } 77 105 end = 0; … … 80 108 * 0's are for the old tar format 81 109 */ 82 if (strncmp(tar.formated.magic, "ustar", 5) != 0) { 83 #ifdef CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY 84 if (strncmp(tar.formated.magic, "\0\0\0\0\0", 5) != 0) 85 #endif 86 bb_error_msg_and_die("Invalid tar magic"); 87 } 88 /* Do checksum on headers */ 89 for (i = 0; i < 148 ; i++) { 90 sum += tar.raw[i]; 91 } 92 sum += ' ' * 8; 93 for (i = 156; i < 512 ; i++) { 94 sum += tar.raw[i]; 95 } 96 if (sum != strtol(tar.formated.chksum, NULL, 8)) { 97 bb_error_msg("Invalid tar header checksum"); 98 return(EXIT_FAILURE); 99 } 100 101 #ifdef CONFIG_FEATURE_TAR_GNU_EXTENSIONS 110 if (strncmp(tar.magic, "ustar", 5) != 0) { 111 #if ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY 112 if (memcmp(tar.magic, "\0\0\0\0", 5) != 0) 113 #endif 114 bb_error_msg_and_die("invalid tar magic"); 115 } 116 117 /* Do checksum on headers. 118 * POSIX says that checksum is done on unsigned bytes, but 119 * Sun and HP-UX gets it wrong... more details in 120 * GNU tar source. */ 121 #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY 122 sum_s = ' ' * sizeof(tar.chksum); 123 #endif 124 sum_u = ' ' * sizeof(tar.chksum); 125 for (i = 0; i < 148; i++) { 126 sum_u += ((unsigned char*)&tar)[i]; 127 #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY 128 sum_s += ((signed char*)&tar)[i]; 129 #endif 130 } 131 for (i = 156; i < 512; i++) { 132 sum_u += ((unsigned char*)&tar)[i]; 133 #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY 134 sum_s += ((signed char*)&tar)[i]; 135 #endif 136 } 137 #if ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY 138 sum = strtoul(tar.chksum, &cp, 8); 139 if ((*cp && *cp != ' ') 140 || (sum_u != sum USE_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) 141 ) { 142 bb_error_msg_and_die("invalid tar header checksum"); 143 } 144 #else 145 /* This field does not need special treatment (getOctal) */ 146 sum = xstrtoul(tar.chksum, 8); 147 if (sum_u != sum USE_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) { 148 bb_error_msg_and_die("invalid tar header checksum"); 149 } 150 #endif 151 152 /* 0 is reserved for high perf file, treat as normal file */ 153 if (!tar.typeflag) tar.typeflag = '0'; 154 parse_names = (tar.typeflag >= '0' && tar.typeflag <= '7'); 155 156 /* getOctal trashes subsequent field, therefore we call it 157 * on fields in reverse order */ 158 if (tar.devmajor[0]) { 159 unsigned minor = GET_OCTAL(tar.devminor); 160 unsigned major = GET_OCTAL(tar.devmajor); 161 file_header->device = makedev(major, minor); 162 } 163 file_header->link_target = NULL; 164 if (!linkname && parse_names && tar.linkname[0]) { 165 /* we trash magic[0] here, it's ok */ 166 tar.linkname[sizeof(tar.linkname)] = '\0'; 167 file_header->link_target = xstrdup(tar.linkname); 168 /* FIXME: what if we have non-link object with link_target? */ 169 /* Will link_target be free()ed? */ 170 } 171 file_header->mtime = GET_OCTAL(tar.mtime); 172 file_header->size = GET_OCTAL(tar.size); 173 file_header->gid = GET_OCTAL(tar.gid); 174 file_header->uid = GET_OCTAL(tar.uid); 175 /* Set bits 0-11 of the files mode */ 176 file_header->mode = 07777 & GET_OCTAL(tar.mode); 177 178 file_header->name = NULL; 179 if (!longname && parse_names) { 180 /* we trash mode[0] here, it's ok */ 181 tar.name[sizeof(tar.name)] = '\0'; 182 if (tar.prefix[0]) { 183 /* and padding[0] */ 184 tar.prefix[sizeof(tar.prefix)] = '\0'; 185 file_header->name = concat_path_file(tar.prefix, tar.name); 186 } else 187 file_header->name = xstrdup(tar.name); 188 } 189 190 /* Set bits 12-15 of the files mode */ 191 /* (typeflag was not trashed because chksum does not use getOctal) */ 192 switch (tar.typeflag) { 193 /* busybox identifies hard links as being regular files with 0 size and a link name */ 194 case '1': 195 file_header->mode |= S_IFREG; 196 break; 197 case '7': 198 /* case 0: */ 199 case '0': 200 #if ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY 201 if (last_char_is(file_header->name, '/')) { 202 file_header->mode |= S_IFDIR; 203 } else 204 #endif 205 file_header->mode |= S_IFREG; 206 break; 207 case '2': 208 file_header->mode |= S_IFLNK; 209 break; 210 case '3': 211 file_header->mode |= S_IFCHR; 212 break; 213 case '4': 214 file_header->mode |= S_IFBLK; 215 break; 216 case '5': 217 file_header->mode |= S_IFDIR; 218 break; 219 case '6': 220 file_header->mode |= S_IFIFO; 221 break; 222 #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 223 case 'L': 224 /* free: paranoia: tar with several consecutive longnames */ 225 free(longname); 226 /* For paranoia reasons we allocate extra NUL char */ 227 longname = xzalloc(file_header->size + 1); 228 /* We read ASCIZ string, including NUL */ 229 xread(archive_handle->src_fd, longname, file_header->size); 230 archive_handle->offset += file_header->size; 231 /* return get_header_tar(archive_handle); */ 232 /* gcc 4.1.1 didn't optimize it into jump */ 233 /* so we will do it ourself, this also saves stack */ 234 goto again; 235 case 'K': 236 free(linkname); 237 linkname = xzalloc(file_header->size + 1); 238 xread(archive_handle->src_fd, linkname, file_header->size); 239 archive_handle->offset += file_header->size; 240 /* return get_header_tar(archive_handle); */ 241 goto again; 242 case 'D': /* GNU dump dir */ 243 case 'M': /* Continuation of multi volume archive */ 244 case 'N': /* Old GNU for names > 100 characters */ 245 case 'S': /* Sparse file */ 246 case 'V': /* Volume header */ 247 #endif 248 case 'g': /* pax global header */ 249 case 'x': { /* pax extended header */ 250 off_t sz; 251 bb_error_msg("warning: skipping header '%c'", tar.typeflag); 252 sz = (file_header->size + 511) & ~(off_t)511; 253 archive_handle->offset += sz; 254 sz >>= 9; /* sz /= 512 but w/o contortions for signed div */ 255 while (sz--) 256 xread(archive_handle->src_fd, &tar, 512); 257 /* return get_header_tar(archive_handle); */ 258 goto again_after_align; 259 } 260 default: 261 bb_error_msg_and_die("unknown typeflag: 0x%x", tar.typeflag); 262 } 263 264 #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 102 265 if (longname) { 103 266 file_header->name = longname; 104 267 longname = NULL; 105 268 } 106 elseif (linkname) {107 file_header-> name= linkname;269 if (linkname) { 270 file_header->link_target = linkname; 108 271 linkname = NULL; 109 } else 110 #endif 111 { 112 file_header->name = bb_xstrndup(tar.formated.name,100); 113 114 if (tar.formated.prefix[0]) { 115 char *temp = file_header->name; 116 file_header->name = concat_path_file(tar.formated.prefix, temp); 117 free(temp); 118 } 119 } 120 121 file_header->uid = strtol(tar.formated.uid, NULL, 8); 122 file_header->gid = strtol(tar.formated.gid, NULL, 8); 123 file_header->size = strtol(tar.formated.size, NULL, 8); 124 file_header->mtime = strtol(tar.formated.mtime, NULL, 8); 125 file_header->link_name = (tar.formated.linkname[0] != '\0') ? 126 bb_xstrdup(tar.formated.linkname) : NULL; 127 file_header->device = makedev(strtol(tar.formated.devmajor, NULL, 8), 128 strtol(tar.formated.devminor, NULL, 8)); 129 130 /* Set bits 0-11 of the files mode */ 131 file_header->mode = 07777 & strtol(tar.formated.mode, NULL, 8); 132 133 /* Set bits 12-15 of the files mode */ 134 switch (tar.formated.typeflag) { 135 /* busybox identifies hard links as being regular files with 0 size and a link name */ 136 case '1': 137 file_header->mode |= S_IFREG; 138 break; 139 case '7': 140 /* Reserved for high performance files, treat as normal file */ 141 case 0: 142 case '0': 143 #ifdef CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY 144 if (last_char_is(file_header->name, '/')) { 145 file_header->mode |= S_IFDIR; 146 } else 147 #endif 148 file_header->mode |= S_IFREG; 149 break; 150 case '2': 151 file_header->mode |= S_IFLNK; 152 break; 153 case '3': 154 file_header->mode |= S_IFCHR; 155 break; 156 case '4': 157 file_header->mode |= S_IFBLK; 158 break; 159 case '5': 160 file_header->mode |= S_IFDIR; 161 break; 162 case '6': 163 file_header->mode |= S_IFIFO; 164 break; 165 #ifdef CONFIG_FEATURE_TAR_GNU_EXTENSIONS 166 case 'L': { 167 longname = xzalloc(file_header->size + 1); 168 archive_xread_all(archive_handle, longname, file_header->size); 169 archive_handle->offset += file_header->size; 170 171 return(get_header_tar(archive_handle)); 172 } 173 case 'K': { 174 linkname = xzalloc(file_header->size + 1); 175 archive_xread_all(archive_handle, linkname, file_header->size); 176 archive_handle->offset += file_header->size; 177 178 file_header->name = linkname; 179 return(get_header_tar(archive_handle)); 180 } 181 case 'D': /* GNU dump dir */ 182 case 'M': /* Continuation of multi volume archive*/ 183 case 'N': /* Old GNU for names > 100 characters */ 184 case 'S': /* Sparse file */ 185 case 'V': /* Volume header */ 186 #endif 187 case 'g': /* pax global header */ 188 case 'x': /* pax extended header */ 189 bb_error_msg("Ignoring extension type %c", tar.formated.typeflag); 190 break; 191 default: 192 bb_error_msg("Unknown typeflag: 0x%x", tar.formated.typeflag); 193 } 194 { /* Strip trailing '/' in directories */ 195 /* Must be done after mode is set as '/' is used to check if its a directory */ 196 char *tmp = last_char_is(file_header->name, '/'); 197 if (tmp) { 198 *tmp = '\0'; 199 } 200 } 272 } 273 #endif 274 if (!strncmp(file_header->name, "/../"+1, 3) 275 || strstr(file_header->name, "/../") 276 ) { 277 bb_error_msg_and_die("name with '..' encountered: '%s'", 278 file_header->name); 279 } 280 281 /* Strip trailing '/' in directories */ 282 /* Must be done after mode is set as '/' is used to check if it's a directory */ 283 cp = last_char_is(file_header->name, '/'); 201 284 202 285 if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { 203 286 archive_handle->action_header(archive_handle->file_header); 287 /* Note that we kill the '/' only after action_header() */ 288 /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */ 289 if (cp) *cp = '\0'; 204 290 archive_handle->flags |= ARCHIVE_EXTRACT_QUIET; 205 291 archive_handle->action_data(archive_handle); … … 207 293 } else { 208 294 data_skip(archive_handle); 295 free(file_header->name); 209 296 } 210 297 archive_handle->offset += file_header->size; 211 298 212 free(file_header->link_name); 213 214 return(EXIT_SUCCESS); 299 free(file_header->link_target); 300 /* Do not free(file_header->name)! */ 301 302 return EXIT_SUCCESS; 215 303 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_tar_bz2.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU Library General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 15 4 */ 16 5 17 #include <sys/types.h>18 #include <sys/wait.h>19 #include <signal.h>20 #include <stdio.h>21 #include <stdlib.h>22 #include <string.h>23 #include <unistd.h>24 6 #include "libbb.h" 25 7 #include "unarchive.h" … … 27 9 char get_header_tar_bz2(archive_handle_t *archive_handle) 28 10 { 29 /* Can t lseek over pipe's */30 archive_handle->seek = seek_by_ char;11 /* Can't lseek over pipes */ 12 archive_handle->seek = seek_by_read; 31 13 32 archive_handle->src_fd = open_transformer(archive_handle->src_fd, un compressStream);14 archive_handle->src_fd = open_transformer(archive_handle->src_fd, unpack_bz2_stream, "bunzip2", "bunzip2", "-cf", "-", NULL); 33 15 archive_handle->offset = 0; 34 while (get_header_tar(archive_handle) == EXIT_SUCCESS) ;16 while (get_header_tar(archive_handle) == EXIT_SUCCESS) /**/; 35 17 36 18 /* Can only do one file at a time */ 37 return (EXIT_FAILURE);19 return EXIT_FAILURE; 38 20 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_tar_gz.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU Library General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 15 4 */ 16 17 #include <stdlib.h>18 5 19 6 #include "libbb.h" … … 22 9 char get_header_tar_gz(archive_handle_t *archive_handle) 23 10 { 11 #if BB_MMU 24 12 unsigned char magic[2]; 13 #endif 25 14 26 /* Can t lseek over pipe's */27 archive_handle->seek = seek_by_ char;15 /* Can't lseek over pipes */ 16 archive_handle->seek = seek_by_read; 28 17 29 archive_xread_all(archive_handle, &magic, 2); 18 /* Check gzip magic only if open_transformer will invoke unpack_gz_stream (MMU case). 19 * Otherwise, it will invoke an external helper "gunzip -cf" (NOMMU case) which will 20 * need the header. */ 21 #if BB_MMU 22 xread(archive_handle->src_fd, &magic, 2); 30 23 if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { 31 bb_error_msg_and_die(" Invalid gzip magic");24 bb_error_msg_and_die("invalid gzip magic"); 32 25 } 33 26 34 check_header_gzip(archive_handle->src_fd); 27 check_header_gzip_or_die(archive_handle->src_fd); 28 #endif 35 29 36 archive_handle->src_fd = open_transformer(archive_handle->src_fd, inflate_gunzip);30 archive_handle->src_fd = open_transformer(archive_handle->src_fd, unpack_gz_stream, "gunzip", "gunzip", "-cf", "-", NULL); 37 31 archive_handle->offset = 0; 38 while (get_header_tar(archive_handle) == EXIT_SUCCESS) ;32 while (get_header_tar(archive_handle) == EXIT_SUCCESS) /**/; 39 33 40 34 /* Can only do one file at a time */ 41 return (EXIT_FAILURE);35 return EXIT_FAILURE; 42 36 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/get_header_tar_lzma.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * Small lzma deflate implementation. … … 6 7 */ 7 8 9 #include "libbb.h" 8 10 #include "unarchive.h" 9 11 … … 11 13 { 12 14 /* Can't lseek over pipes */ 13 archive_handle->seek = seek_by_ char;15 archive_handle->seek = seek_by_read; 14 16 15 archive_handle->src_fd = open_transformer(archive_handle->src_fd, un lzma);17 archive_handle->src_fd = open_transformer(archive_handle->src_fd, unpack_lzma_stream, "unlzma", "unlzma", "-cf", "-", NULL); 16 18 archive_handle->offset = 0; 17 while (get_header_tar(archive_handle) == EXIT_SUCCESS) ;19 while (get_header_tar(archive_handle) == EXIT_SUCCESS) /**/; 18 20 19 21 /* Can only do one file at a time */ 20 22 return EXIT_FAILURE; 21 23 } 22 23 /* vi:set ts=4: */ -
branches/2.2.5/mindi-busybox/archival/libunarchive/header_list.c
r821 r1765 1 #include <stdio.h> 1 /* vi: set sw=4 ts=4: */ 2 /* 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 4 */ 5 #include "libbb.h" 2 6 #include "unarchive.h" 3 7 -
branches/2.2.5/mindi-busybox/archival/libunarchive/header_skip.c
r821 r1765 1 #include <stdio.h> 1 /* vi: set sw=4 ts=4: */ 2 /* 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 4 */ 5 #include "libbb.h" 2 6 #include "unarchive.h" 3 7 -
branches/2.2.5/mindi-busybox/archival/libunarchive/header_verbose_list.c
r821 r1765 1 #include <stdio.h> 2 #include <string.h> 3 #include <time.h> 1 /* vi: set sw=4 ts=4: */ 2 /* 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 4 */ 5 4 6 #include "libbb.h" 5 7 #include "unarchive.h" … … 9 11 struct tm *mtime = localtime(&(file_header->mtime)); 10 12 11 printf("%s %d/%d %10u %4u-%02u-%02u %02u:%02u:%02u %s",13 printf("%s %d/%d %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s", 12 14 bb_mode_string(file_header->mode), 13 15 file_header->uid, 14 16 file_header->gid, 15 (unsigned int)file_header->size,17 file_header->size, 16 18 1900 + mtime->tm_year, 17 19 1 + mtime->tm_mon, … … 22 24 file_header->name); 23 25 24 if (file_header->link_ name) {25 printf(" -> %s", file_header->link_ name);26 if (file_header->link_target) { 27 printf(" -> %s", file_header->link_target); 26 28 } 27 29 /* putchar isnt used anywhere else i dont think */ -
branches/2.2.5/mindi-busybox/archival/libunarchive/init_handle.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 15 4 */ 16 5 17 #include <unistd.h>18 #include <string.h>19 6 #include "libbb.h" 20 7 #include "unarchive.h" … … 24 11 archive_handle_t *archive_handle; 25 12 26 /* Initiali se default values */13 /* Initialize default values */ 27 14 archive_handle = xzalloc(sizeof(archive_handle_t)); 28 archive_handle->file_header = x malloc(sizeof(file_header_t));15 archive_handle->file_header = xzalloc(sizeof(file_header_t)); 29 16 archive_handle->action_header = header_skip; 30 17 archive_handle->action_data = data_skip; … … 32 19 archive_handle->seek = seek_by_jump; 33 20 34 return (archive_handle);21 return archive_handle; 35 22 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/open_transformer.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 3 4 */ 4 5 5 #include <stdlib.h>6 #include <unistd.h>7 8 6 #include "libbb.h" 9 10 7 #include "unarchive.h" 11 8 12 9 /* transformer(), more than meets the eye */ 13 int open_transformer(int src_fd, int (*transformer)(int src_fd, int dst_fd)) 10 /* 11 * On MMU machine, the transform_prog and ... are stripped 12 * by a macro in include/unarchive.h. On NOMMU, transformer is stripped. 13 */ 14 int open_transformer(int src_fd, 15 USE_DESKTOP(long long) int (*transformer)(int src_fd, int dst_fd), 16 const char *transform_prog, ...) 14 17 { 15 18 int fd_pipe[2]; 16 19 int pid; 17 20 18 if (pipe(fd_pipe) != 0) { 19 bb_perror_msg_and_die("Can't create pipe"); 20 } 21 xpipe(fd_pipe); 21 22 23 #if BB_MMU 22 24 pid = fork(); 23 if (pid == -1) { 24 bb_perror_msg_and_die("Fork failed"); 25 } 25 #else 26 pid = vfork(); 27 #endif 28 if (pid == -1) 29 bb_perror_msg_and_die("fork failed"); 26 30 27 31 if (pid == 0) { 32 #if !BB_MMU 33 va_list ap; 34 #endif 28 35 /* child process */ 29 close(fd_pipe[0]); /* We don't wan't to read from the parent */ 30 transformer(src_fd, fd_pipe[1]); 31 close(fd_pipe[1]); /* Send EOF */ 32 close(src_fd); 33 exit(0); 34 /* notreached */ 36 close(fd_pipe[0]); /* We don't wan't to read from the parent */ 37 // FIXME: error check? 38 #if BB_MMU 39 transformer(src_fd, fd_pipe[1]); 40 if (ENABLE_FEATURE_CLEAN_UP) { 41 close(fd_pipe[1]); /* Send EOF */ 42 close(src_fd); 43 } 44 exit(0); 45 #else 46 xmove_fd(src_fd, 0); 47 xmove_fd(fd_pipe[1], 1); 48 va_start(ap, transform_prog); 49 BB_EXECVP(transform_prog, ap); 50 bb_perror_and_die("exec failed"); 51 #endif 52 /* notreached */ 35 53 } 36 54 … … 38 56 close(fd_pipe[1]); /* Don't want to write to the child */ 39 57 40 return (fd_pipe[0]);58 return fd_pipe[0]; 41 59 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/seek_by_jump.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU Library General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 15 4 */ 16 17 #include <sys/types.h>18 #include <errno.h>19 #include <unistd.h>20 #include <stdlib.h>21 5 22 6 #include "libbb.h" … … 26 10 { 27 11 if (lseek(archive_handle->src_fd, (off_t) amount, SEEK_CUR) == (off_t) -1) { 28 #if def CONFIG_FEATURE_UNARCHIVE_TAPE12 #if ENABLE_FEATURE_UNARCHIVE_TAPE 29 13 if (errno == ESPIPE) { 30 seek_by_ char(archive_handle, amount);14 seek_by_read(archive_handle, amount); 31 15 } else 32 16 #endif 33 bb_perror_msg_and_die(" Seek failure");17 bb_perror_msg_and_die("seek failure"); 34 18 } 35 19 } -
branches/2.2.5/mindi-busybox/archival/libunarchive/unpack_ar_archive.c
r821 r1765 1 /* vi: set ts=4:*/1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 4 4 */ 5 #include <fcntl.h> 6 #include <stdlib.h> 7 #include <string.h> 5 6 #include "libbb.h" 8 7 #include "unarchive.h" 9 #include "libbb.h"10 8 11 9 void unpack_ar_archive(archive_handle_t *ar_archive) … … 13 11 char magic[7]; 14 12 15 archive_xread_all(ar_archive, magic, 7);13 xread(ar_archive->src_fd, magic, 7); 16 14 if (strncmp(magic, "!<arch>", 7) != 0) { 17 bb_error_msg_and_die(" Invalid ar magic");15 bb_error_msg_and_die("invalid ar magic"); 18 16 } 19 17 ar_archive->offset += 7; -
branches/2.2.5/mindi-busybox/archival/rpm.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h> 11 #include <unistd.h> 12 #include <signal.h> 13 #include <stdlib.h> 14 #include <fcntl.h> 15 #include <netinet/in.h> /* For ntohl & htonl function */ 16 #include <string.h> /* For strncmp */ 17 #include <sys/mman.h> /* For mmap */ 18 #include <time.h> /* For ctime */ 19 20 #include "busybox.h" 10 #include "libbb.h" 21 11 #include "unarchive.h" 22 12 23 #define RPM_HEADER_MAGIC "\216\255\350"24 #define RPM_CHAR_TYPE 25 #define RPM_INT8_TYPE 26 #define RPM_INT16_TYPE 27 #define RPM_INT32_TYPE 28 /* #define RPM_INT64_TYPE 29 #define RPM_STRING_TYPE 30 #define RPM_BIN_TYPE 31 #define RPM_STRING_ARRAY_TYPE 32 #define RPM_I18NSTRING_TYPE 33 34 #define RPMTAG_NAME100035 #define RPMTAG_VERSION100136 #define RPMTAG_RELEASE100237 #define RPMTAG_SUMMARY100438 #define RPMTAG_DESCRIPTION100539 #define RPMTAG_BUILDTIME100640 #define RPMTAG_BUILDHOST100741 #define RPMTAG_SIZE100942 #define RPMTAG_VENDOR101143 #define RPMTAG_LICENSE101444 #define RPMTAG_PACKAGER101545 #define RPMTAG_GROUP101646 #define RPMTAG_URL102047 #define RPMTAG_PREIN102348 #define RPMTAG_POSTIN102449 #define RPMTAG_FILEFLAGS103750 #define RPMTAG_FILEUSERNAME103951 #define RPMTAG_FILEGROUPNAME104052 #define RPMTAG_SOURCERPM104453 #define RPMTAG_PREINPROG108554 #define RPMTAG_POSTINPROG108655 #define RPMTAG_PREFIXS109856 #define RPMTAG_DIRINDEXES111657 #define RPMTAG_BASENAMES111758 #define RPMTAG_DIRNAMES111859 #define RPMFILE_CONFIG(1 << 0)60 #define RPMFILE_DOC(1 << 1)13 #define RPM_HEADER_MAGIC "\216\255\350" 14 #define RPM_CHAR_TYPE 1 15 #define RPM_INT8_TYPE 2 16 #define RPM_INT16_TYPE 3 17 #define RPM_INT32_TYPE 4 18 /* #define RPM_INT64_TYPE 5 ---- These aren't supported (yet) */ 19 #define RPM_STRING_TYPE 6 20 #define RPM_BIN_TYPE 7 21 #define RPM_STRING_ARRAY_TYPE 8 22 #define RPM_I18NSTRING_TYPE 9 23 24 #define TAG_NAME 1000 25 #define TAG_VERSION 1001 26 #define TAG_RELEASE 1002 27 #define TAG_SUMMARY 1004 28 #define TAG_DESCRIPTION 1005 29 #define TAG_BUILDTIME 1006 30 #define TAG_BUILDHOST 1007 31 #define TAG_SIZE 1009 32 #define TAG_VENDOR 1011 33 #define TAG_LICENSE 1014 34 #define TAG_PACKAGER 1015 35 #define TAG_GROUP 1016 36 #define TAG_URL 1020 37 #define TAG_PREIN 1023 38 #define TAG_POSTIN 1024 39 #define TAG_FILEFLAGS 1037 40 #define TAG_FILEUSERNAME 1039 41 #define TAG_FILEGROUPNAME 1040 42 #define TAG_SOURCERPM 1044 43 #define TAG_PREINPROG 1085 44 #define TAG_POSTINPROG 1086 45 #define TAG_PREFIXS 1098 46 #define TAG_DIRINDEXES 1116 47 #define TAG_BASENAMES 1117 48 #define TAG_DIRNAMES 1118 49 #define RPMFILE_CONFIG (1 << 0) 50 #define RPMFILE_DOC (1 << 1) 61 51 62 52 enum rpm_functions_e { … … 81 71 static int tagcount; 82 72 83 void extract_cpio_gz(int fd); 84 rpm_index **rpm_gettags(int fd, int *num_tags); 85 int bsearch_rpmtag(const void *key, const void *item); 86 char *rpm_getstring(int tag, int itemindex); 87 int rpm_getint(int tag, int itemindex); 88 int rpm_getcount(int tag); 89 void exec_script(int progtag, int datatag, char *prefix); 90 void fileaction_dobackup(char *filename, int fileref); 91 void fileaction_setowngrp(char *filename, int fileref); 92 void fileaction_list(char *filename, int itemno); 93 void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref)); 94 73 static void extract_cpio_gz(int fd); 74 static rpm_index **rpm_gettags(int fd, int *num_tags); 75 static int bsearch_rpmtag(const void *key, const void *item); 76 static char *rpm_getstr(int tag, int itemindex); 77 static int rpm_getint(int tag, int itemindex); 78 static int rpm_getcount(int tag); 79 static void fileaction_dobackup(char *filename, int fileref); 80 static void fileaction_setowngrp(char *filename, int fileref); 81 static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref)); 82 83 int rpm_main(int argc, char **argv); 95 84 int rpm_main(int argc, char **argv) 96 85 { 97 86 int opt = 0, func = 0, rpm_fd, offset; 87 const int pagesize = getpagesize(); 98 88 99 89 while ((opt = getopt(argc, argv, "iqpldc")) != -1) { 100 90 switch (opt) { 101 case 'i': / / First arg: Install mode, with q: Information102 if (!func) func |= rpm_install;91 case 'i': /* First arg: Install mode, with q: Information */ 92 if (!func) func = rpm_install; 103 93 else func |= rpm_query_info; 104 94 break; 105 case 'q': / / First arg: Query mode106 if ( !func) func |= rpm_query;107 else bb_show_usage();108 break; 109 case 'p': / / Query a package95 case 'q': /* First arg: Query mode */ 96 if (func) bb_show_usage(); 97 func = rpm_query; 98 break; 99 case 'p': /* Query a package */ 110 100 func |= rpm_query_package; 111 101 break; 112 case 'l': / / List files in a package102 case 'l': /* List files in a package */ 113 103 func |= rpm_query_list; 114 104 break; 115 case 'd': / / List doc files in a package (implies list)105 case 'd': /* List doc files in a package (implies list) */ 116 106 func |= rpm_query_list; 117 107 func |= rpm_query_list_doc; 118 108 break; 119 case 'c': / / List config files in a package (implies list)109 case 'c': /* List config files in a package (implies list) */ 120 110 func |= rpm_query_list; 121 111 func |= rpm_query_list_config; … … 125 115 } 126 116 } 127 128 if (optind == argc) bb_show_usage(); 129 while (optind < argc) { 130 rpm_fd = bb_xopen(argv[optind], O_RDONLY); 131 mytags = rpm_gettags(rpm_fd, (int *) &tagcount); 132 offset = lseek(rpm_fd, 0, SEEK_CUR); 133 if (!mytags) { printf("Error reading rpm header\n"); exit(-1); } 134 map = mmap(0, offset > getpagesize() ? (offset + offset % getpagesize()) : getpagesize(), PROT_READ, MAP_PRIVATE, rpm_fd, 0); // Mimimum is one page 117 argv += optind; 118 argc -= optind; 119 if (!argc) bb_show_usage(); 120 121 while (*argv) { 122 rpm_fd = xopen(*argv++, O_RDONLY); 123 mytags = rpm_gettags(rpm_fd, &tagcount); 124 if (!mytags) 125 bb_error_msg_and_die("error reading rpm header"); 126 offset = xlseek(rpm_fd, 0, SEEK_CUR); 127 /* Mimimum is one page */ 128 map = mmap(0, offset > pagesize ? (offset + offset % pagesize) : pagesize, PROT_READ, MAP_PRIVATE, rpm_fd, 0); 129 135 130 if (func & rpm_install) { 136 loop_through_files(RPMTAG_BASENAMES, fileaction_dobackup); /* Backup any config files */ 137 extract_cpio_gz(rpm_fd); // Extact the archive 138 loop_through_files(RPMTAG_BASENAMES, fileaction_setowngrp); /* Set the correct file uid/gid's */ 139 } else if (func & rpm_query && func & rpm_query_package) { 140 if (!((func & rpm_query_info) || (func & rpm_query_list))) { // If just a straight query, just give package name 141 printf("%s-%s-%s\n", rpm_getstring(RPMTAG_NAME, 0), rpm_getstring(RPMTAG_VERSION, 0), rpm_getstring(RPMTAG_RELEASE, 0)); 131 /* Backup any config files */ 132 loop_through_files(TAG_BASENAMES, fileaction_dobackup); 133 /* Extact the archive */ 134 extract_cpio_gz(rpm_fd); 135 /* Set the correct file uid/gid's */ 136 loop_through_files(TAG_BASENAMES, fileaction_setowngrp); 137 } 138 else if ((func & (rpm_query|rpm_query_package)) == (rpm_query|rpm_query_package)) { 139 if (!(func & (rpm_query_info|rpm_query_list))) { 140 /* If just a straight query, just give package name */ 141 printf("%s-%s-%s\n", rpm_getstr(TAG_NAME, 0), rpm_getstr(TAG_VERSION, 0), rpm_getstr(TAG_RELEASE, 0)); 142 142 } 143 143 if (func & rpm_query_info) { … … 146 146 struct tm *bdate; 147 147 char bdatestring[50]; 148 printf("Name : %-29sRelocations: %s\n", rpm_getstr ing(RPMTAG_NAME, 0), rpm_getstring(RPMTAG_PREFIXS, 0) ? rpm_getstring(RPMTAG_PREFIXS, 0) : "(not relocateable)");149 printf("Version : %-34sVendor: %s\n", rpm_getstr ing(RPMTAG_VERSION, 0), rpm_getstring(RPMTAG_VENDOR, 0) ? rpm_getstring(RPMTAG_VENDOR, 0) : "(none)");150 bdate_time = rpm_getint( RPMTAG_BUILDTIME, 0);148 printf("Name : %-29sRelocations: %s\n", rpm_getstr(TAG_NAME, 0), rpm_getstr(TAG_PREFIXS, 0) ? rpm_getstr(TAG_PREFIXS, 0) : "(not relocateable)"); 149 printf("Version : %-34sVendor: %s\n", rpm_getstr(TAG_VERSION, 0), rpm_getstr(TAG_VENDOR, 0) ? rpm_getstr(TAG_VENDOR, 0) : "(none)"); 150 bdate_time = rpm_getint(TAG_BUILDTIME, 0); 151 151 bdate = localtime((time_t *) &bdate_time); 152 152 strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate); 153 printf("Release : %-30sBuild Date: %s\n", rpm_getstr ing(RPMTAG_RELEASE, 0), bdatestring);154 printf("Install date: %-30sBuild Host: %s\n", "(not installed)", rpm_getstr ing(RPMTAG_BUILDHOST, 0));155 printf("Group : %-30sSource RPM: %s\n", rpm_getstr ing(RPMTAG_GROUP, 0), rpm_getstring(RPMTAG_SOURCERPM, 0));156 printf("Size : %-33dLicense: %s\n", rpm_getint( RPMTAG_SIZE, 0), rpm_getstring(RPMTAG_LICENSE, 0));157 printf("URL : %s\n", rpm_getstr ing(RPMTAG_URL, 0));158 printf("Summary : %s\n", rpm_getstr ing(RPMTAG_SUMMARY, 0));159 printf("Description :\n%s\n", rpm_getstr ing(RPMTAG_DESCRIPTION, 0));153 printf("Release : %-30sBuild Date: %s\n", rpm_getstr(TAG_RELEASE, 0), bdatestring); 154 printf("Install date: %-30sBuild Host: %s\n", "(not installed)", rpm_getstr(TAG_BUILDHOST, 0)); 155 printf("Group : %-30sSource RPM: %s\n", rpm_getstr(TAG_GROUP, 0), rpm_getstr(TAG_SOURCERPM, 0)); 156 printf("Size : %-33dLicense: %s\n", rpm_getint(TAG_SIZE, 0), rpm_getstr(TAG_LICENSE, 0)); 157 printf("URL : %s\n", rpm_getstr(TAG_URL, 0)); 158 printf("Summary : %s\n", rpm_getstr(TAG_SUMMARY, 0)); 159 printf("Description :\n%s\n", rpm_getstr(TAG_DESCRIPTION, 0)); 160 160 } 161 161 if (func & rpm_query_list) { 162 162 int count, it, flags; 163 count = rpm_getcount( RPMTAG_BASENAMES);163 count = rpm_getcount(TAG_BASENAMES); 164 164 for (it = 0; it < count; it++) { 165 flags = rpm_getint(RPMTAG_FILEFLAGS, it); 166 switch ((func & rpm_query_list_doc) + (func & rpm_query_list_config)) 167 { 168 case rpm_query_list_doc: if (!(flags & RPMFILE_DOC)) continue; break; 169 case rpm_query_list_config: if (!(flags & RPMFILE_CONFIG)) continue; break; 170 case rpm_query_list_doc + rpm_query_list_config: if (!((flags & RPMFILE_CONFIG) || (flags & RPMFILE_DOC))) continue; break; 165 flags = rpm_getint(TAG_FILEFLAGS, it); 166 switch (func & (rpm_query_list_doc|rpm_query_list_config)) { 167 case rpm_query_list_doc: 168 if (!(flags & RPMFILE_DOC)) continue; 169 break; 170 case rpm_query_list_config: 171 if (!(flags & RPMFILE_CONFIG)) continue; 172 break; 173 case rpm_query_list_doc|rpm_query_list_config: 174 if (!(flags & (RPMFILE_CONFIG|RPMFILE_DOC))) continue; 175 break; 171 176 } 172 printf("%s%s\n", rpm_getstring(RPMTAG_DIRNAMES, rpm_getint(RPMTAG_DIRINDEXES, it)), rpm_getstring(RPMTAG_BASENAMES, it)); 177 printf("%s%s\n", 178 rpm_getstr(TAG_DIRNAMES, rpm_getint(TAG_DIRINDEXES, it)), 179 rpm_getstr(TAG_BASENAMES, it)); 173 180 } 174 181 } 175 182 } 176 optind++; 177 free (mytags); 183 free(mytags); 178 184 } 179 185 return 0; 180 186 } 181 187 182 void extract_cpio_gz(int fd) { 188 static void extract_cpio_gz(int fd) 189 { 183 190 archive_handle_t *archive_handle; 184 191 unsigned char magic[2]; 185 186 /* Initialise */ 192 #if BB_MMU 193 USE_DESKTOP(long long) int (*xformer)(int src_fd, int dst_fd); 194 enum { xformer_prog = 0 }; 195 #else 196 enum { xformer = 0 }; 197 const char *xformer_prog; 198 #endif 199 200 /* Initialize */ 187 201 archive_handle = init_handle(); 188 archive_handle->seek = seek_by_ char;202 archive_handle->seek = seek_by_read; 189 203 //archive_handle->action_header = header_list; 190 204 archive_handle->action_data = data_extract_all; … … 194 208 archive_handle->offset = 0; 195 209 196 bb_xread_all(archive_handle->src_fd, &magic, 2); 210 xread(archive_handle->src_fd, &magic, 2); 211 #if BB_MMU 212 xformer = unpack_gz_stream; 213 #else 214 xformer_prog = "gunzip"; 215 #endif 197 216 if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { 198 bb_error_msg_and_die("Invalid gzip magic"); 199 } 200 check_header_gzip(archive_handle->src_fd); 201 bb_xchdir("/"); // Install RPM's to root 202 203 archive_handle->src_fd = open_transformer(archive_handle->src_fd, inflate_gunzip); 217 if (ENABLE_FEATURE_RPM_BZ2 218 && (magic[0] == 0x42) && (magic[1] == 0x5a)) { 219 #if BB_MMU 220 xformer = unpack_bz2_stream; 221 #else 222 xformer_prog = "bunzip2"; 223 #endif 224 /* We can do better, need modifying unpack_bz2_stream to not require 225 * first 2 bytes. Not very hard to do... I mean, TODO :) */ 226 xlseek(archive_handle->src_fd, -2, SEEK_CUR); 227 } else 228 bb_error_msg_and_die("no gzip" 229 USE_FEATURE_RPM_BZ2("/bzip") 230 " magic"); 231 } else { 232 check_header_gzip_or_die(archive_handle->src_fd); 233 #if !BB_MMU 234 /* NOMMU version of open_transformer execs an external unzipper that should 235 * have the file position at the start of the file */ 236 xlseek(archive_handle->src_fd, 0, SEEK_SET); 237 #endif 238 } 239 240 xchdir("/"); /* Install RPM's to root */ 241 archive_handle->src_fd = open_transformer(archive_handle->src_fd, xformer, xformer_prog, xformer_prog, "-cf", "-", NULL); 204 242 archive_handle->offset = 0; 205 while (get_header_cpio(archive_handle) == EXIT_SUCCESS); 206 } 207 208 209 rpm_index **rpm_gettags(int fd, int *num_tags) 210 { 211 rpm_index **tags = xzalloc(200 * sizeof(struct rpmtag *)); /* We should never need mode than 200, and realloc later */ 243 while (get_header_cpio(archive_handle) == EXIT_SUCCESS) 244 continue; 245 } 246 247 248 static rpm_index **rpm_gettags(int fd, int *num_tags) 249 { 250 /* We should never need mode than 200, and realloc later */ 251 rpm_index **tags = xzalloc(200 * sizeof(struct rpmtag *)); 212 252 int pass, tagindex = 0; 213 lseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */ 214 215 for (pass = 0; pass < 2; pass++) { /* 1st pass is the signature headers, 2nd is the main stuff */ 253 254 xlseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */ 255 256 /* 1st pass is the signature headers, 2nd is the main stuff */ 257 for (pass = 0; pass < 2; pass++) { 216 258 struct { 217 259 char magic[3]; /* 3 byte magic: 0x8e 0xad 0xe8 */ … … 224 266 int storepos; 225 267 226 read(fd, &header, sizeof(header)); 227 if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0) return NULL; /* Invalid magic */ 228 if (header.version != 1) return NULL; /* This program only supports v1 headers */ 268 xread(fd, &header, sizeof(header)); 269 if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0) 270 return NULL; /* Invalid magic */ 271 if (header.version != 1) 272 return NULL; /* This program only supports v1 headers */ 229 273 header.size = ntohl(header.size); 230 274 header.entries = ntohl(header.entries); 231 storepos = lseek(fd,0,SEEK_CUR) + header.entries * 16;275 storepos = xlseek(fd,0,SEEK_CUR) + header.entries * 16; 232 276 233 277 while (header.entries--) { 234 278 tmpindex = tags[tagindex++] = xmalloc(sizeof(rpm_index)); 235 read(fd, tmpindex, sizeof(rpm_index)); 236 tmpindex->tag = ntohl(tmpindex->tag); tmpindex->type = ntohl(tmpindex->type); tmpindex->count = ntohl(tmpindex->count); 279 xread(fd, tmpindex, sizeof(rpm_index)); 280 tmpindex->tag = ntohl(tmpindex->tag); 281 tmpindex->type = ntohl(tmpindex->type); 282 tmpindex->count = ntohl(tmpindex->count); 237 283 tmpindex->offset = storepos + ntohl(tmpindex->offset); 238 if (pass==0) tmpindex->tag -= 743; 239 } 240 lseek(fd, header.size, SEEK_CUR); /* Seek past store */ 241 if (pass==0) lseek(fd, (8 - (lseek(fd,0,SEEK_CUR) % 8)) % 8, SEEK_CUR); /* Skip padding to 8 byte boundary after reading signature headers */ 242 } 243 tags = realloc(tags, tagindex * sizeof(struct rpmtag *)); /* realloc tags to save space */ 284 if (pass==0) 285 tmpindex->tag -= 743; 286 } 287 xlseek(fd, header.size, SEEK_CUR); /* Seek past store */ 288 /* Skip padding to 8 byte boundary after reading signature headers */ 289 if (pass==0) 290 xlseek(fd, (8 - (xlseek(fd,0,SEEK_CUR) % 8)) % 8, SEEK_CUR); 291 } 292 tags = xrealloc(tags, tagindex * sizeof(struct rpmtag *)); /* realloc tags to save space */ 244 293 *num_tags = tagindex; 245 294 return tags; /* All done, leave the file at the start of the gzipped cpio archive */ 246 295 } 247 296 248 int bsearch_rpmtag(const void *key, const void *item)297 static int bsearch_rpmtag(const void *key, const void *item) 249 298 { 250 299 int *tag = (int *)key; … … 253 302 } 254 303 255 int rpm_getcount(int tag)304 static int rpm_getcount(int tag) 256 305 { 257 306 rpm_index **found; 258 307 found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag); 259 if (!found) return 0; 260 else return found[0]->count; 261 } 262 263 char *rpm_getstring(int tag, int itemindex) 308 if (!found) 309 return 0; 310 return found[0]->count; 311 } 312 313 static char *rpm_getstr(int tag, int itemindex) 264 314 { 265 315 rpm_index **found; 266 316 found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag); 267 if (!found || itemindex >= found[0]->count) return NULL; 317 if (!found || itemindex >= found[0]->count) 318 return NULL; 268 319 if (found[0]->type == RPM_STRING_TYPE || found[0]->type == RPM_I18NSTRING_TYPE || found[0]->type == RPM_STRING_ARRAY_TYPE) { 269 320 int n; 270 321 char *tmpstr = (char *) (map + found[0]->offset); 271 for (n=0; n < itemindex; n++) tmpstr = tmpstr + strlen(tmpstr) + 1; 322 for (n=0; n < itemindex; n++) 323 tmpstr = tmpstr + strlen(tmpstr) + 1; 272 324 return tmpstr; 273 } else return NULL; 274 } 275 276 int rpm_getint(int tag, int itemindex) 325 } 326 return NULL; 327 } 328 329 static int rpm_getint(int tag, int itemindex) 277 330 { 278 331 rpm_index **found; 279 int n, *tmpint; 332 int *tmpint; /* NB: using int8_t* would be easier to code */ 333 280 334 /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ... 281 335 * it's ok to ignore it because tag won't be used as a pointer */ 282 336 found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag); 283 if (!found || itemindex >= found[0]->count) return -1; 337 if (!found || itemindex >= found[0]->count) 338 return -1; 339 284 340 tmpint = (int *) (map + found[0]->offset); 341 285 342 if (found[0]->type == RPM_INT32_TYPE) { 286 for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 4); 287 return ntohl(*tmpint); 288 } else if (found[0]->type == RPM_INT16_TYPE) { 289 for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 2); 290 return ntohs(*tmpint); 291 } else if (found[0]->type == RPM_INT8_TYPE) { 292 for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 1); 293 return ntohs(*tmpint); 294 } else return -1; 295 } 296 297 void fileaction_dobackup(char *filename, int fileref) 343 tmpint = (int *) ((char *) tmpint + itemindex*4); 344 /*return ntohl(*tmpint);*/ 345 /* int can be != int32_t */ 346 return ntohl(*(int32_t*)tmpint); 347 } 348 if (found[0]->type == RPM_INT16_TYPE) { 349 tmpint = (int *) ((char *) tmpint + itemindex*2); 350 /* ??? read int, and THEN ntohs() it?? */ 351 /*return ntohs(*tmpint);*/ 352 return ntohs(*(int16_t*)tmpint); 353 } 354 if (found[0]->type == RPM_INT8_TYPE) { 355 tmpint = (int *) ((char *) tmpint + itemindex); 356 /* ??? why we don't read byte here??? */ 357 /*return ntohs(*tmpint);*/ 358 return *(int8_t*)tmpint; 359 } 360 return -1; 361 } 362 363 static void fileaction_dobackup(char *filename, int fileref) 298 364 { 299 365 struct stat oldfile; 300 366 int stat_res; 301 367 char *newname; 302 if (rpm_getint(RPMTAG_FILEFLAGS, fileref) & RPMFILE_CONFIG) { /* Only need to backup config files */ 303 stat_res = lstat (filename, &oldfile); 304 if (stat_res == 0 && S_ISREG(oldfile.st_mode)) { /* File already exists - really should check MD5's etc to see if different */ 305 newname = bb_xstrdup(filename); 306 newname = strcat(newname, ".rpmorig"); 368 if (rpm_getint(TAG_FILEFLAGS, fileref) & RPMFILE_CONFIG) { 369 /* Only need to backup config files */ 370 stat_res = lstat(filename, &oldfile); 371 if (stat_res == 0 && S_ISREG(oldfile.st_mode)) { 372 /* File already exists - really should check MD5's etc to see if different */ 373 newname = xasprintf("%s.rpmorig", filename); 307 374 copy_file(filename, newname, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS); 308 375 remove_file(filename, FILEUTILS_RECUR | FILEUTILS_FORCE); … … 312 379 } 313 380 314 void fileaction_setowngrp(char *filename, int fileref)381 static void fileaction_setowngrp(char *filename, int fileref) 315 382 { 316 383 int uid, gid; 317 uid = bb_xgetpwnam(rpm_getstring(RPMTAG_FILEUSERNAME, fileref)); 318 gid = bb_xgetgrnam(rpm_getstring(RPMTAG_FILEGROUPNAME, fileref)); 319 chown (filename, uid, gid); 320 } 321 322 void fileaction_list(char *filename, int ATTRIBUTE_UNUSED fileref) 323 { 324 printf("%s\n", filename); 325 } 326 327 void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref)) 384 uid = xuname2uid(rpm_getstr(TAG_FILEUSERNAME, fileref)); 385 gid = xgroup2gid(rpm_getstr(TAG_FILEGROUPNAME, fileref)); 386 chown(filename, uid, gid); 387 } 388 389 static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref)) 328 390 { 329 391 int count = 0; 330 while (rpm_getstr ing(filetag, count)) {331 char * filename = bb_xasprintf("%s%s",332 rpm_getstr ing(RPMTAG_DIRNAMES, rpm_getint(RPMTAG_DIRINDEXES,333 count)), rpm_getstring(RPMTAG_BASENAMES, count));392 while (rpm_getstr(filetag, count)) { 393 char* filename = xasprintf("%s%s", 394 rpm_getstr(TAG_DIRNAMES, rpm_getint(TAG_DIRINDEXES, count)), 395 rpm_getstr(TAG_BASENAMES, count)); 334 396 fileaction(filename, count++); 335 397 free(filename); -
branches/2.2.5/mindi-busybox/archival/rpm2cpio.c
r821 r1765 5 5 * Copyright (C) 2001 by Laurence Anderson 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 20 8 */ 21 #include <sys/types.h> 22 #include <netinet/in.h> /* For ntohl & htonl function */ 23 #include <fcntl.h> 24 #include <unistd.h> 25 #include <string.h> 26 #include "busybox.h" 9 #include "libbb.h" 27 10 #include "unarchive.h" 28 11 … … 53 36 struct rpm_header header; 54 37 55 bb_xread_all(rpm_fd, &header, sizeof(struct rpm_header));38 xread(rpm_fd, &header, sizeof(struct rpm_header)); 56 39 if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0) { 57 bb_error_msg_and_die(" Invalid RPM header magic"); /* Invalid magic */40 bb_error_msg_and_die("invalid RPM header magic"); /* Invalid magic */ 58 41 } 59 42 if (header.version != 1) { 60 bb_error_msg_and_die(" Unsupported RPM header version"); /* This program only supports v1 headers */43 bb_error_msg_and_die("unsupported RPM header version"); /* This program only supports v1 headers */ 61 44 } 62 45 header.entries = ntohl(header.entries); … … 67 50 68 51 /* No getopt required */ 52 int rpm2cpio_main(int argc, char **argv); 69 53 int rpm2cpio_main(int argc, char **argv) 70 54 { … … 76 60 rpm_fd = STDIN_FILENO; 77 61 } else { 78 rpm_fd = bb_xopen(argv[1], O_RDONLY);62 rpm_fd = xopen(argv[1], O_RDONLY); 79 63 } 80 64 81 bb_xread_all(rpm_fd, &lead, sizeof(struct rpm_lead));65 xread(rpm_fd, &lead, sizeof(struct rpm_lead)); 82 66 if (strncmp((char *) &lead.magic, RPM_MAGIC, 4) != 0) { 83 bb_error_msg_and_die(" Invalid RPM magic"); /* Just check the magic, the rest is irrelevant */67 bb_error_msg_and_die("invalid RPM magic"); /* Just check the magic, the rest is irrelevant */ 84 68 } 85 69 … … 91 75 skip_header(rpm_fd); 92 76 93 bb_xread_all(rpm_fd, &magic, 2);77 xread(rpm_fd, &magic, 2); 94 78 if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { 95 bb_error_msg_and_die(" Invalid gzip magic");79 bb_error_msg_and_die("invalid gzip magic"); 96 80 } 97 81 98 check_header_gzip (rpm_fd);99 if ( inflate_gunzip(rpm_fd, STDOUT_FILENO) !=0) {100 bb_error_msg(" Error inflating");82 check_header_gzip_or_die(rpm_fd); 83 if (unpack_gz_stream(rpm_fd, STDOUT_FILENO) < 0) { 84 bb_error_msg("error inflating"); 101 85 } 102 86 -
branches/2.2.5/mindi-busybox/archival/tar.c
r821 r1765 24 24 */ 25 25 26 #include <f cntl.h>26 #include <fnmatch.h> 27 27 #include <getopt.h> 28 #include <search.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <unistd.h> 32 #include <fnmatch.h> 33 #include <string.h> 34 #include <errno.h> 35 #include <signal.h> 36 #include <sys/wait.h> 37 #include <sys/socket.h> 38 #include <sys/sysmacros.h> /* major() and minor() */ 28 #include "libbb.h" 39 29 #include "unarchive.h" 40 #include "busybox.h" 41 42 #ifdef CONFIG_FEATURE_TAR_CREATE 30 31 #define block_buf bb_common_bufsiz1 32 33 #if ENABLE_FEATURE_TAR_CREATE 43 34 44 35 /* Tar file constants */ … … 47 38 48 39 /* POSIX tar Header Block, from POSIX 1003.1-1990 */ 49 #define NAME_SIZE 100 50 struct TarHeader { /* byte offset */ 51 char name[NAME_SIZE]; /* 0-99 */ 52 char mode[8]; /* 100-107 */ 53 char uid[8]; /* 108-115 */ 54 char gid[8]; /* 116-123 */ 55 char size[12]; /* 124-135 */ 56 char mtime[12]; /* 136-147 */ 57 char chksum[8]; /* 148-155 */ 58 char typeflag; /* 156-156 */ 59 char linkname[NAME_SIZE]; /* 157-256 */ 60 char magic[6]; /* 257-262 */ 61 char version[2]; /* 263-264 */ 62 char uname[32]; /* 265-296 */ 63 char gname[32]; /* 297-328 */ 64 char devmajor[8]; /* 329-336 */ 65 char devminor[8]; /* 337-344 */ 66 char prefix[155]; /* 345-499 */ 67 char padding[12]; /* 500-512 (pad to exactly the TAR_BLOCK_SIZE) */ 40 #define NAME_SIZE 100 41 #define NAME_SIZE_STR "100" 42 typedef struct TarHeader TarHeader; 43 struct TarHeader { /* byte offset */ 44 char name[NAME_SIZE]; /* 0-99 */ 45 char mode[8]; /* 100-107 */ 46 char uid[8]; /* 108-115 */ 47 char gid[8]; /* 116-123 */ 48 char size[12]; /* 124-135 */ 49 char mtime[12]; /* 136-147 */ 50 char chksum[8]; /* 148-155 */ 51 char typeflag; /* 156-156 */ 52 char linkname[NAME_SIZE]; /* 157-256 */ 53 char magic[6]; /* 257-262 */ 54 char version[2]; /* 263-264 */ 55 char uname[32]; /* 265-296 */ 56 char gname[32]; /* 297-328 */ 57 char devmajor[8]; /* 329-336 */ 58 char devminor[8]; /* 337-344 */ 59 char prefix[155]; /* 345-499 */ 60 char padding[12]; /* 500-512 (pad to exactly the TAR_BLOCK_SIZE) */ 68 61 }; 69 typedef struct TarHeader TarHeader;70 62 71 63 /* 72 ** writeTarFile(), 64 ** writeTarFile(), writeFileToTarball(), and writeTarHeader() are 73 65 ** the only functions that deal with the HardLinkInfo structure. 74 66 ** Even these functions use the xxxHardLinkInfo() functions. … … 84 76 85 77 /* Some info to be carried along when creating a new tarball */ 78 typedef struct TarBallInfo TarBallInfo; 86 79 struct TarBallInfo { 87 char *fileName; /* File name of the tarball */88 80 int tarFd; /* Open-for-write file descriptor 89 81 for the tarball */ … … 97 89 HardLinkInfo *hlInfo; /* Hard Link Info for the current file */ 98 90 }; 99 typedef struct TarBallInfo TarBallInfo;100 91 101 92 /* A nice enum with all the possible tar file content types */ … … 116 107 117 108 /* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */ 118 static inlinevoid addHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr,109 static void addHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr, 119 110 struct stat *statbuf, 120 const char * name)111 const char *fileName) 121 112 { 122 113 /* Note: hlInfoHeadPtr can never be NULL! */ 123 114 HardLinkInfo *hlInfo; 124 115 125 hlInfo = (HardLinkInfo *) xmalloc(sizeof(HardLinkInfo) + strlen(name));116 hlInfo = xmalloc(sizeof(HardLinkInfo) + strlen(fileName)); 126 117 hlInfo->next = *hlInfoHeadPtr; 127 118 *hlInfoHeadPtr = hlInfo; … … 129 120 hlInfo->ino = statbuf->st_ino; 130 121 hlInfo->linkCount = statbuf->st_nlink; 131 strcpy(hlInfo->name, name);122 strcpy(hlInfo->name, fileName); 132 123 } 133 124 134 125 static void freeHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr) 135 126 { 136 HardLinkInfo *hlInfo = NULL;137 HardLinkInfo *hlInfoNext = NULL;127 HardLinkInfo *hlInfo; 128 HardLinkInfo *hlInfoNext; 138 129 139 130 if (hlInfoHeadPtr) { … … 146 137 *hlInfoHeadPtr = NULL; 147 138 } 148 return;149 139 } 150 140 151 141 /* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */ 152 static inlineHardLinkInfo *findHardLinkInfo(HardLinkInfo * hlInfo, struct stat *statbuf)142 static HardLinkInfo *findHardLinkInfo(HardLinkInfo * hlInfo, struct stat *statbuf) 153 143 { 154 144 while (hlInfo) { … … 157 147 hlInfo = hlInfo->next; 158 148 } 159 return (hlInfo);149 return hlInfo; 160 150 } 161 151 162 152 /* Put an octal string into the specified buffer. 163 * The number is zero and space padded and possibly null padded. 164 * Returns TRUE if successful. */ 165 static int putOctal(char *cp, int len, long value) 166 { 167 int tempLength; 168 char tempBuffer[32]; 153 * The number is zero padded and possibly null terminated. 154 * Stores low-order bits only if whole value does not fit. */ 155 static void putOctal(char *cp, int len, off_t value) 156 { 157 char tempBuffer[sizeof(off_t)*3+1]; 169 158 char *tempString = tempBuffer; 170 171 /* Create a string of the specified length with an initial space, 172 * leading zeroes and the octal number, and a trailing null. */173 sprintf(tempString, "%0*lo", len - 1, value);174 175 /* If the string is too large, suppress the leading space.*/176 tempLength = strlen(tempString) + 1;177 if (tempLength > len) {178 tempLength--;159 int width; 160 161 width = sprintf(tempBuffer, "%0*"OFF_FMT"o", len, value); 162 tempString += (width - len); 163 164 /* If string has leading zeroes, we can drop one */ 165 /* and field will have trailing '\0' */ 166 /* (increases chances of compat with other tars) */ 167 if (tempString[0] == '0') 179 168 tempString++; 180 } 181 182 /* If the string is still too large, suppress the trailing null. */ 183 if (tempLength > len) 184 tempLength--; 185 186 /* If the string is still too large, fail. */ 187 if (tempLength > len) 188 return FALSE; 189 190 /* Copy the string to the field. */ 169 170 /* Copy the string to the field */ 191 171 memcpy(cp, tempString, len); 192 193 return TRUE; 194 } 172 } 173 #define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) 174 175 static void chksum_and_xwrite(int fd, struct TarHeader* hp) 176 { 177 /* POSIX says that checksum is done on unsigned bytes 178 * (Sun and HP-UX gets it wrong... more details in 179 * GNU tar source) */ 180 const unsigned char *cp; 181 int chksum, size; 182 183 strcpy(hp->magic, "ustar "); 184 185 /* Calculate and store the checksum (i.e., the sum of all of the bytes of 186 * the header). The checksum field must be filled with blanks for the 187 * calculation. The checksum field is formatted differently from the 188 * other fields: it has 6 digits, a null, then a space -- rather than 189 * digits, followed by a null like the other fields... */ 190 memset(hp->chksum, ' ', sizeof(hp->chksum)); 191 cp = (const unsigned char *) hp; 192 chksum = 0; 193 size = sizeof(*hp); 194 do { chksum += *cp++; } while (--size); 195 putOctal(hp->chksum, sizeof(hp->chksum)-1, chksum); 196 197 /* Now write the header out to disk */ 198 xwrite(fd, hp, sizeof(*hp)); 199 } 200 201 #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 202 static void writeLongname(int fd, int type, const char *name, int dir) 203 { 204 static const struct { 205 char mode[8]; /* 100-107 */ 206 char uid[8]; /* 108-115 */ 207 char gid[8]; /* 116-123 */ 208 char size[12]; /* 124-135 */ 209 char mtime[12]; /* 136-147 */ 210 } prefilled = { 211 "0000000", 212 "0000000", 213 "0000000", 214 "00000000000", 215 "00000000000", 216 }; 217 struct TarHeader header; 218 int size; 219 220 dir = !!dir; /* normalize: 0/1 */ 221 size = strlen(name) + 1 + dir; /* GNU tar uses strlen+1 */ 222 /* + dir: account for possible '/' */ 223 224 memset(&header, 0, sizeof(header)); 225 strcpy(header.name, "././@LongLink"); 226 memcpy(header.mode, prefilled.mode, sizeof(prefilled)); 227 PUT_OCTAL(header.size, size); 228 header.typeflag = type; 229 chksum_and_xwrite(fd, &header); 230 231 /* Write filename[/] and pad the block. */ 232 /* dir=0: writes 'name<NUL>', pads */ 233 /* dir=1: writes 'name', writes '/<NUL>', pads */ 234 dir *= 2; 235 xwrite(fd, name, size - dir); 236 xwrite(fd, "/", dir); 237 size = (-size) & (TAR_BLOCK_SIZE-1); 238 memset(&header, 0, size); 239 xwrite(fd, &header, size); 240 } 241 #endif 195 242 196 243 /* Write out a tar header for the specified file/directory/whatever */ 197 static inline int writeTarHeader(struct TarBallInfo *tbInfo, 198 const char *header_name, const char *real_name, struct stat *statbuf) 199 { 200 long chksum = 0; 244 void BUG_tar_header_size(void); 245 static int writeTarHeader(struct TarBallInfo *tbInfo, 246 const char *header_name, const char *fileName, struct stat *statbuf) 247 { 201 248 struct TarHeader header; 202 const unsigned char *cp = (const unsigned char *) &header; 203 ssize_t size = sizeof(struct TarHeader); 204 205 memset(&header, 0, size); 206 207 safe_strncpy(header.name, header_name, sizeof(header.name)); 208 209 putOctal(header.mode, sizeof(header.mode), statbuf->st_mode); 210 putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); 211 putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); 212 putOctal(header.size, sizeof(header.size), 0); /* Regular file size is handled later */ 213 putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime); 214 strcpy(header.magic, "ustar "); 215 216 /* Enter the user and group names (default to root if it fails) */ 217 if (bb_getpwuid(header.uname, statbuf->st_uid, sizeof(header.uname)) == NULL) 218 strcpy(header.uname, "root"); 219 if (bb_getgrgid(header.gname, statbuf->st_gid, sizeof(header.gname)) == NULL) 220 strcpy(header.gname, "root"); 249 250 if (sizeof(header) != 512) 251 BUG_tar_header_size(); 252 253 memset(&header, 0, sizeof(struct TarHeader)); 254 255 strncpy(header.name, header_name, sizeof(header.name)); 256 257 /* POSIX says to mask mode with 07777. */ 258 PUT_OCTAL(header.mode, statbuf->st_mode & 07777); 259 PUT_OCTAL(header.uid, statbuf->st_uid); 260 PUT_OCTAL(header.gid, statbuf->st_gid); 261 memset(header.size, '0', sizeof(header.size)-1); /* Regular file size is handled later */ 262 PUT_OCTAL(header.mtime, statbuf->st_mtime); 263 264 /* Enter the user and group names */ 265 safe_strncpy(header.uname, get_cached_username(statbuf->st_uid), sizeof(header.uname)); 266 safe_strncpy(header.gname, get_cached_groupname(statbuf->st_gid), sizeof(header.gname)); 221 267 222 268 if (tbInfo->hlInfo) { … … 225 271 strncpy(header.linkname, tbInfo->hlInfo->name, 226 272 sizeof(header.linkname)); 273 #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 274 /* Write out long linkname if needed */ 275 if (header.linkname[sizeof(header.linkname)-1]) 276 writeLongname(tbInfo->tarFd, GNULONGLINK, 277 tbInfo->hlInfo->name, 0); 278 #endif 227 279 } else if (S_ISLNK(statbuf->st_mode)) { 228 char *lpath = xreadlink(real_name); 229 230 if (!lpath) /* Already printed err msg inside xreadlink() */ 231 return (FALSE); 280 char *lpath = xmalloc_readlink_or_warn(fileName); 281 if (!lpath) 282 return FALSE; 232 283 header.typeflag = SYMTYPE; 233 284 strncpy(header.linkname, lpath, sizeof(header.linkname)); 285 #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 286 /* Write out long linkname if needed */ 287 if (header.linkname[sizeof(header.linkname)-1]) 288 writeLongname(tbInfo->tarFd, GNULONGLINK, lpath, 0); 289 #else 290 /* If it is larger than 100 bytes, bail out */ 291 if (header.linkname[sizeof(header.linkname)-1]) { 292 free(lpath); 293 bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported"); 294 return FALSE; 295 } 296 #endif 234 297 free(lpath); 235 298 } else if (S_ISDIR(statbuf->st_mode)) { 236 299 header.typeflag = DIRTYPE; 237 strncat(header.name, "/", sizeof(header.name)); 300 /* Append '/' only if there is a space for it */ 301 if (!header.name[sizeof(header.name)-1]) 302 header.name[strlen(header.name)] = '/'; 238 303 } else if (S_ISCHR(statbuf->st_mode)) { 239 304 header.typeflag = CHRTYPE; 240 putOctal(header.devmajor, sizeof(header.devmajor), 241 major(statbuf->st_rdev)); 242 putOctal(header.devminor, sizeof(header.devminor), 243 minor(statbuf->st_rdev)); 305 PUT_OCTAL(header.devmajor, major(statbuf->st_rdev)); 306 PUT_OCTAL(header.devminor, minor(statbuf->st_rdev)); 244 307 } else if (S_ISBLK(statbuf->st_mode)) { 245 308 header.typeflag = BLKTYPE; 246 putOctal(header.devmajor, sizeof(header.devmajor), 247 major(statbuf->st_rdev)); 248 putOctal(header.devminor, sizeof(header.devminor), 249 minor(statbuf->st_rdev)); 309 PUT_OCTAL(header.devmajor, major(statbuf->st_rdev)); 310 PUT_OCTAL(header.devminor, minor(statbuf->st_rdev)); 250 311 } else if (S_ISFIFO(statbuf->st_mode)) { 251 312 header.typeflag = FIFOTYPE; 252 313 } else if (S_ISREG(statbuf->st_mode)) { 314 if (sizeof(statbuf->st_size) > 4 315 && statbuf->st_size > (off_t)0777777777777LL 316 ) { 317 bb_error_msg_and_die("cannot store file '%s' " 318 "of size %"OFF_FMT"d, aborting", 319 fileName, statbuf->st_size); 320 } 253 321 header.typeflag = REGTYPE; 254 putOctal(header.size, sizeof(header.size), statbuf->st_size);322 PUT_OCTAL(header.size, statbuf->st_size); 255 323 } else { 256 bb_error_msg("%s: Unknown file type", real_name); 257 return (FALSE); 258 } 259 260 /* Calculate and store the checksum (i.e., the sum of all of the bytes of 261 * the header). The checksum field must be filled with blanks for the 262 * calculation. The checksum field is formatted differently from the 263 * other fields: it has [6] digits, a null, then a space -- rather than 264 * digits, followed by a null like the other fields... */ 265 memset(header.chksum, ' ', sizeof(header.chksum)); 266 cp = (const unsigned char *) &header; 267 while (size-- > 0) 268 chksum += *cp++; 269 putOctal(header.chksum, 7, chksum); 324 bb_error_msg("%s: unknown file type", fileName); 325 return FALSE; 326 } 327 328 #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 329 /* Write out long name if needed */ 330 /* (we, like GNU tar, output long linkname *before* long name) */ 331 if (header.name[sizeof(header.name)-1]) 332 writeLongname(tbInfo->tarFd, GNULONGNAME, 333 header_name, S_ISDIR(statbuf->st_mode)); 334 #endif 270 335 271 336 /* Now write the header out to disk */ 272 if ((size = 273 bb_full_write(tbInfo->tarFd, (char *) &header, 274 sizeof(struct TarHeader))) < 0) { 275 bb_error_msg(bb_msg_io_error, real_name); 276 return (FALSE); 277 } 278 /* Pad the header up to the tar block size */ 279 for (; size < TAR_BLOCK_SIZE; size++) { 280 write(tbInfo->tarFd, "\0", 1); 281 } 337 chksum_and_xwrite(tbInfo->tarFd, &header); 338 282 339 /* Now do the verbose thing (or not) */ 283 284 340 if (tbInfo->verboseFlag) { 285 341 FILE *vbFd = stdout; … … 287 343 if (tbInfo->tarFd == STDOUT_FILENO) /* If the archive goes to stdout, verbose to stderr */ 288 344 vbFd = stderr; 289 290 fprintf(vbFd, "%s\n", header.name); 291 } 292 293 return (TRUE); 294 } 295 296 # ifdef CONFIG_FEATURE_TAR_FROM 297 static inline int exclude_file(const llist_t *excluded_files, const char *file) 345 /* GNU "tar cvvf" prints "extended" listing a-la "ls -l" */ 346 /* We don't have such excesses here: for us "v" == "vv" */ 347 /* '/' is probably a GNUism */ 348 fprintf(vbFd, "%s%s\n", header_name, 349 S_ISDIR(statbuf->st_mode) ? "/" : ""); 350 } 351 352 return TRUE; 353 } 354 355 #if ENABLE_FEATURE_TAR_FROM 356 static int exclude_file(const llist_t *excluded_files, const char *file) 298 357 { 299 358 while (excluded_files) { … … 317 376 return 0; 318 377 } 319 # 378 #else 320 379 #define exclude_file(excluded_files, file) 0 321 # 380 #endif 322 381 323 382 static int writeFileToTarball(const char *fileName, struct stat *statbuf, 324 void *userData)383 void *userData, int depth ATTRIBUTE_UNUSED) 325 384 { 326 385 struct TarBallInfo *tbInfo = (struct TarBallInfo *) userData; … … 329 388 330 389 /* 331 ** Check to see if we are dealing with a hard link.332 ** If so -333 ** Treat the first occurance of a given dev/inode as a file while334 ** treating any additional occurances as hard links. This is done335 ** by adding the file information to the HardLinkInfo linked list.390 * Check to see if we are dealing with a hard link. 391 * If so - 392 * Treat the first occurance of a given dev/inode as a file while 393 * treating any additional occurances as hard links. This is done 394 * by adding the file information to the HardLinkInfo linked list. 336 395 */ 337 396 tbInfo->hlInfo = NULL; … … 345 404 if (S_ISSOCK(statbuf->st_mode)) { 346 405 bb_error_msg("%s: socket ignored", fileName); 347 return (TRUE);406 return TRUE; 348 407 } 349 408 … … 354 413 tbInfo->statBuf.st_ino == statbuf->st_ino) { 355 414 bb_error_msg("%s: file is the archive; skipping", fileName); 356 return (TRUE);415 return TRUE; 357 416 } 358 417 359 418 header_name = fileName; 360 419 while (header_name[0] == '/') { 361 static int alreadyWarned = FALSE;362 363 if ( alreadyWarned == FALSE) {364 bb_error_msg(" Removing leading '/' from member names");365 alreadyWarned = TRUE;420 static smallint warned; 421 422 if (!warned) { 423 bb_error_msg("removing leading '/' from member names"); 424 warned = 1; 366 425 } 367 426 header_name++; 368 427 } 369 428 429 #if !ENABLE_FEATURE_TAR_GNU_EXTENSIONS 370 430 if (strlen(fileName) >= NAME_SIZE) { 371 bb_error_msg(bb_msg_name_longer_than_foo, NAME_SIZE); 372 return (TRUE); 373 } 431 bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported"); 432 return TRUE; 433 } 434 #endif 374 435 375 436 if (header_name[0] == '\0') 376 437 return TRUE; 377 438 378 if (ENABLE_FEATURE_TAR_FROM && 379 exclude_file(tbInfo->excludeList, header_name)) { 439 if (exclude_file(tbInfo->excludeList, header_name)) 380 440 return SKIP; 381 }382 441 383 442 /* Is this a regular file? */ 384 if ((tbInfo->hlInfo == NULL) && (S_ISREG(statbuf->st_mode))) { 385 443 if (tbInfo->hlInfo == NULL && S_ISREG(statbuf->st_mode)) { 386 444 /* open the file we want to archive, and make sure all is well */ 387 i f ((inputFileFd = open(fileName, O_RDONLY)) < 0) {388 bb_perror_msg("%s: Cannot open", fileName);389 return (FALSE);445 inputFileFd = open_or_warn(fileName, O_RDONLY); 446 if (inputFileFd < 0) { 447 return FALSE; 390 448 } 391 449 } … … 393 451 /* Add an entry to the tarball */ 394 452 if (writeTarHeader(tbInfo, header_name, fileName, statbuf) == FALSE) { 395 return (FALSE);453 return FALSE; 396 454 } 397 455 398 456 /* If it was a regular file, write out the body */ 399 if (inputFileFd >= 0 ) { 400 ssize_t readSize = 0; 401 402 /* write the file to the archive */ 403 readSize = bb_copyfd_eof(inputFileFd, tbInfo->tarFd); 457 if (inputFileFd >= 0) { 458 size_t readSize; 459 /* Write the file to the archive. */ 460 /* We record size into header first, */ 461 /* and then write out file. If file shrinks in between, */ 462 /* tar will be corrupted. So we don't allow for that. */ 463 /* NB: GNU tar 1.16 warns and pads with zeroes */ 464 /* or even seeks back and updates header */ 465 bb_copyfd_exact_size(inputFileFd, tbInfo->tarFd, statbuf->st_size); 466 ////off_t readSize; 467 ////readSize = bb_copyfd_size(inputFileFd, tbInfo->tarFd, statbuf->st_size); 468 ////if (readSize != statbuf->st_size && readSize >= 0) { 469 //// bb_error_msg_and_die("short read from %s, aborting", fileName); 470 ////} 471 472 /* Check that file did not grow in between? */ 473 /* if (safe_read(inputFileFd, 1) == 1) warn but continue? */ 474 404 475 close(inputFileFd); 405 476 406 477 /* Pad the file up to the tar block size */ 407 for (; (readSize % TAR_BLOCK_SIZE) != 0; readSize++) 408 write(tbInfo->tarFd, "\0", 1); 409 } 410 411 return (TRUE); 412 } 413 414 static inline int writeTarFile(const int tar_fd, const int verboseFlag, 478 /* (a few tricks here in the name of code size) */ 479 readSize = (-(int)statbuf->st_size) & (TAR_BLOCK_SIZE-1); 480 memset(block_buf, 0, readSize); 481 xwrite(tbInfo->tarFd, block_buf, readSize); 482 } 483 484 return TRUE; 485 } 486 487 static int writeTarFile(const int tar_fd, const int verboseFlag, 415 488 const unsigned long dereferenceFlag, const llist_t *include, 416 489 const llist_t *exclude, const int gzip) 417 490 { 418 491 pid_t gzipPid = 0; 419 420 492 int errorFlag = FALSE; 421 ssize_t size;422 493 struct TarBallInfo tbInfo; 423 494 … … 431 502 * can avoid including the tarball into itself.... */ 432 503 if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0) 433 bb_perror_msg_and_die(" Couldnt stat tar file");504 bb_perror_msg_and_die("cannot stat tar file"); 434 505 435 506 if ((ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2) && gzip) { … … 437 508 int gzipStatusPipe[2] = { -1, -1 }; 438 509 volatile int vfork_exec_errno = 0; 439 char *zip_exec = (gzip == 1) ? "gzip" : "bzip2"; 440 441 442 if (pipe(gzipDataPipe) < 0 || pipe(gzipStatusPipe) < 0) 443 bb_perror_msg_and_die("create pipe"); 444 445 signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ 446 447 # if __GNUC__ 448 /* Avoid vfork clobbering */ 449 (void) &include; 450 (void) &errorFlag; 451 (void) &zip_exec; 452 # endif 510 const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2"; 511 512 xpipe(gzipDataPipe); 513 xpipe(gzipStatusPipe); 514 515 signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ 516 517 #if defined(__GNUC__) && __GNUC__ 518 /* Avoid vfork clobbering */ 519 (void) &include; 520 (void) &errorFlag; 521 (void) &zip_exec; 522 #endif 453 523 454 524 gzipPid = vfork(); … … 458 528 close(gzipDataPipe[1]); 459 529 460 if (tbInfo.tarFd != 1) 461 dup2(tbInfo.tarFd, 1); 530 dup2(tbInfo.tarFd, 1); 462 531 463 532 close(gzipStatusPipe[0]); 464 533 fcntl(gzipStatusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows success */ 465 534 466 execlp(zip_exec, zip_exec, "-f", NULL);535 BB_EXECLP(zip_exec, zip_exec, "-f", NULL); 467 536 vfork_exec_errno = errno; 468 537 … … 476 545 char buf; 477 546 478 int n = bb_full_read(gzipStatusPipe[0], &buf, 1);547 int n = full_read(gzipStatusPipe[0], &buf, 1); 479 548 480 549 if (n == 0 && vfork_exec_errno != 0) { 481 550 errno = vfork_exec_errno; 482 bb_perror_msg_and_die(" Couldnot exec %s", zip_exec);551 bb_perror_msg_and_die("cannot exec %s", zip_exec); 483 552 } else if ((n < 0) && (errno == EAGAIN || errno == EINTR)) 484 553 continue; /* try it again */ … … 495 564 /* Read the directory/files and iterate over them one at a time */ 496 565 while (include) { 497 if (!recursive_action(include->data, TRUE, dereferenceFlag, 498 FALSE, writeFileToTarball, writeFileToTarball, &tbInfo)) 566 if (!recursive_action(include->data, ACTION_RECURSE | 567 (dereferenceFlag ? ACTION_FOLLOWLINKS : 0), 568 writeFileToTarball, writeFileToTarball, &tbInfo, 0)) 499 569 { 500 570 errorFlag = TRUE; … … 503 573 } 504 574 /* Write two empty blocks to the end of the archive */ 505 for (size = 0; size < (2 * TAR_BLOCK_SIZE); size++)506 write(tbInfo.tarFd, "\0", 1);575 memset(block_buf, 0, 2*TAR_BLOCK_SIZE); 576 xwrite(tbInfo.tarFd, block_buf, 2*TAR_BLOCK_SIZE); 507 577 508 578 /* To be pedantically correct, we would check if the tarball … … 519 589 520 590 if (errorFlag) 521 bb_error_msg("Error exit delayed from previous errors"); 522 523 if (gzipPid && waitpid(gzipPid, NULL, 0)==-1) 524 bb_error_msg("Couldnt wait"); 525 526 return !errorFlag; 591 bb_error_msg("error exit delayed from previous errors"); 592 593 if (gzipPid) { 594 int status; 595 if (waitpid(gzipPid, &status, 0) == -1) 596 bb_perror_msg("waitpid"); 597 else if (!WIFEXITED(status) || WEXITSTATUS(status)) 598 /* gzip was killed or has exited with nonzero! */ 599 errorFlag = TRUE; 600 } 601 return errorFlag; 527 602 } 528 603 #else … … 530 605 const unsigned long dereferenceFlag, const llist_t *include, 531 606 const llist_t *exclude, const int gzip); 532 #endif /* tar_create*/533 534 #if def CONFIG_FEATURE_TAR_FROM607 #endif /* FEATURE_TAR_CREATE */ 608 609 #if ENABLE_FEATURE_TAR_FROM 535 610 static llist_t *append_file_list_to_list(llist_t *list) 536 611 { … … 542 617 543 618 while (cur) { 544 src_stream = bb_xfopen(cur->data, "r");619 src_stream = xfopen(cur->data, "r"); 545 620 tmp = cur; 546 621 cur = cur->link; 547 622 free(tmp); 548 while ((line = bb_get_chomped_line_from_file(src_stream)) != NULL) 549 llist_add_to(&newlist, line); 623 while ((line = xmalloc_getline(src_stream)) != NULL) { 624 /* kill trailing '/' unless the string is just "/" */ 625 char *cp = last_char_is(line, '/'); 626 if (cp > line) 627 *cp = '\0'; 628 llist_add_to(&newlist, line); 629 } 550 630 fclose(src_stream); 551 631 } … … 553 633 } 554 634 #else 555 #define append_file_list_to_list(x) 556 #endif 557 558 #if def CONFIG_FEATURE_TAR_COMPRESS635 #define append_file_list_to_list(x) 0 636 #endif 637 638 #if ENABLE_FEATURE_TAR_COMPRESS 559 639 static char get_header_tar_Z(archive_handle_t *archive_handle) 560 640 { 561 /* Can t lseek over pipe's */562 archive_handle->seek = seek_by_ char;641 /* Can't lseek over pipes */ 642 archive_handle->seek = seek_by_read; 563 643 564 644 /* do the decompression, and cleanup */ 565 if ( bb_xread_char(archive_handle->src_fd) != 0x1f ||566 bb_xread_char(archive_handle->src_fd) != 0x9d)567 {568 bb_error_msg_and_die(" Invalid magic");569 } 570 571 archive_handle->src_fd = open_transformer(archive_handle->src_fd, uncompress );645 if (xread_char(archive_handle->src_fd) != 0x1f 646 || xread_char(archive_handle->src_fd) != 0x9d 647 ) { 648 bb_error_msg_and_die("invalid magic"); 649 } 650 651 archive_handle->src_fd = open_transformer(archive_handle->src_fd, uncompress, "uncompress", "uncompress", "-cf", "-", NULL); 572 652 archive_handle->offset = 0; 573 while (get_header_tar(archive_handle) == EXIT_SUCCESS); 653 while (get_header_tar(archive_handle) == EXIT_SUCCESS) 654 /* nothing */; 574 655 575 656 /* Can only do one file at a time */ 576 return (EXIT_FAILURE);657 return EXIT_FAILURE; 577 658 } 578 659 #else 579 #define get_header_tar_Z 0 580 #endif 581 582 #define CTX_TEST (1 << 0) 583 #define CTX_EXTRACT (1 << 1) 584 #define TAR_OPT_BASEDIR (1 << 2) 585 #define TAR_OPT_TARNAME (1 << 3) 586 #define TAR_OPT_2STDOUT (1 << 4) 587 #define TAR_OPT_P (1 << 5) 588 #define TAR_OPT_VERBOSE (1 << 6) 589 #define TAR_OPT_KEEP_OLD (1 << 7) 590 591 #define TAR_OPT_AFTER_START 8 592 593 #define CTX_CREATE (1 << (TAR_OPT_AFTER_START)) 594 #define TAR_OPT_DEREFERENCE (1 << (TAR_OPT_AFTER_START + 1)) 595 #ifdef CONFIG_FEATURE_TAR_CREATE 596 # define TAR_OPT_STR_CREATE "ch" 597 # define TAR_OPT_AFTER_CREATE TAR_OPT_AFTER_START + 2 598 #else 599 # define TAR_OPT_STR_CREATE "" 600 # define TAR_OPT_AFTER_CREATE TAR_OPT_AFTER_START 601 #endif 602 603 #define TAR_OPT_BZIP2 (1 << (TAR_OPT_AFTER_CREATE)) 604 #ifdef CONFIG_FEATURE_TAR_BZIP2 605 # define TAR_OPT_STR_BZIP2 "j" 606 # define TAR_OPT_AFTER_BZIP2 TAR_OPT_AFTER_CREATE + 1 607 #else 608 # define TAR_OPT_STR_BZIP2 "" 609 # define TAR_OPT_AFTER_BZIP2 TAR_OPT_AFTER_CREATE 610 #endif 611 612 #define TAR_OPT_LZMA (1 << (TAR_OPT_AFTER_BZIP2)) 613 #ifdef CONFIG_FEATURE_TAR_LZMA 614 # define TAR_OPT_STR_LZMA "a" 615 # define TAR_OPT_AFTER_LZMA TAR_OPT_AFTER_BZIP2 + 1 616 #else 617 # define TAR_OPT_STR_LZMA "" 618 # define TAR_OPT_AFTER_LZMA TAR_OPT_AFTER_BZIP2 619 #endif 620 621 #define TAR_OPT_INCLUDE_FROM (1 << (TAR_OPT_AFTER_LZMA)) 622 #define TAR_OPT_EXCLUDE_FROM (1 << (TAR_OPT_AFTER_LZMA + 1)) 623 #ifdef CONFIG_FEATURE_TAR_FROM 624 # define TAR_OPT_STR_FROM "T:X:" 625 # define TAR_OPT_AFTER_FROM TAR_OPT_AFTER_LZMA + 2 626 #else 627 # define TAR_OPT_STR_FROM "" 628 # define TAR_OPT_AFTER_FROM TAR_OPT_AFTER_LZMA 629 #endif 630 631 #define TAR_OPT_GZIP (1 << (TAR_OPT_AFTER_FROM)) 632 #ifdef CONFIG_FEATURE_TAR_GZIP 633 # define TAR_OPT_STR_GZIP "z" 634 # define TAR_OPT_AFTER_GZIP TAR_OPT_AFTER_FROM + 1 635 #else 636 # define TAR_OPT_STR_GZIP "" 637 # define TAR_OPT_AFTER_GZIP TAR_OPT_AFTER_FROM 638 #endif 639 640 #define TAR_OPT_UNCOMPRESS (1 << (TAR_OPT_AFTER_GZIP)) 641 #ifdef CONFIG_FEATURE_TAR_COMPRESS 642 # define TAR_OPT_STR_COMPRESS "Z" 643 # define TAR_OPT_AFTER_COMPRESS TAR_OPT_AFTER_GZIP + 1 644 #else 645 # define TAR_OPT_STR_COMPRESS "" 646 # define TAR_OPT_AFTER_COMPRESS TAR_OPT_AFTER_GZIP 647 #endif 648 649 #define TAR_OPT_NOPRESERVE_OWN (1 << (TAR_OPT_AFTER_COMPRESS)) 650 #define TAR_OPT_NOPRESERVE_PERM (1 << (TAR_OPT_AFTER_COMPRESS + 1)) 651 #define TAR_OPT_STR_NOPRESERVE "\203\213" 652 #define TAR_OPT_AFTER_NOPRESERVE TAR_OPT_AFTER_COMPRESS + 2 653 654 static const char tar_options[]="txC:f:Opvk" \ 655 TAR_OPT_STR_CREATE \ 656 TAR_OPT_STR_BZIP2 \ 657 TAR_OPT_STR_LZMA \ 658 TAR_OPT_STR_FROM \ 659 TAR_OPT_STR_GZIP \ 660 TAR_OPT_STR_COMPRESS \ 661 TAR_OPT_STR_NOPRESERVE; 662 663 #ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS 664 static const struct option tar_long_options[] = { 665 { "list", 0, NULL, 't' }, 666 { "extract", 0, NULL, 'x' }, 667 { "directory", 1, NULL, 'C' }, 668 { "file", 1, NULL, 'f' }, 669 { "to-stdout", 0, NULL, 'O' }, 670 { "same-permissions", 0, NULL, 'p' }, 671 { "verbose", 0, NULL, 'v' }, 672 { "keep-old", 0, NULL, 'k' }, 673 { "no-same-owner", 0, NULL, '\203' }, 674 { "no-same-permissions",0, NULL, '\213' }, 675 # ifdef CONFIG_FEATURE_TAR_CREATE 676 { "create", 0, NULL, 'c' }, 677 { "dereference", 0, NULL, 'h' }, 660 #define get_header_tar_Z NULL 661 #endif 662 663 #ifdef CHECK_FOR_CHILD_EXITCODE 664 /* Looks like it isn't needed - tar detects malformed (truncated) 665 * archive if e.g. bunzip2 fails */ 666 static int child_error; 667 668 static void handle_SIGCHLD(int status) 669 { 670 /* Actually, 'status' is a signo. We reuse it for other needs */ 671 672 /* Wait for any child without blocking */ 673 if (waitpid(-1, &status, WNOHANG) < 0) 674 /* wait failed?! I'm confused... */ 675 return; 676 677 if (WIFEXITED(status) && WEXITSTATUS(status)==0) 678 /* child exited with 0 */ 679 return; 680 /* Cannot happen? 681 if (!WIFSIGNALED(status) && !WIFEXITED(status)) return; */ 682 child_error = 1; 683 } 684 #endif 685 686 enum { 687 OPTBIT_KEEP_OLD = 7, 688 USE_FEATURE_TAR_CREATE( OPTBIT_CREATE ,) 689 USE_FEATURE_TAR_CREATE( OPTBIT_DEREFERENCE ,) 690 USE_FEATURE_TAR_BZIP2( OPTBIT_BZIP2 ,) 691 USE_FEATURE_TAR_LZMA( OPTBIT_LZMA ,) 692 USE_FEATURE_TAR_FROM( OPTBIT_INCLUDE_FROM,) 693 USE_FEATURE_TAR_FROM( OPTBIT_EXCLUDE_FROM,) 694 USE_FEATURE_TAR_GZIP( OPTBIT_GZIP ,) 695 USE_FEATURE_TAR_COMPRESS(OPTBIT_COMPRESS ,) 696 OPTBIT_NOPRESERVE_OWN, 697 OPTBIT_NOPRESERVE_PERM, 698 OPT_TEST = 1 << 0, // t 699 OPT_EXTRACT = 1 << 1, // x 700 OPT_BASEDIR = 1 << 2, // C 701 OPT_TARNAME = 1 << 3, // f 702 OPT_2STDOUT = 1 << 4, // O 703 OPT_P = 1 << 5, // p 704 OPT_VERBOSE = 1 << 6, // v 705 OPT_KEEP_OLD = 1 << 7, // k 706 OPT_CREATE = USE_FEATURE_TAR_CREATE( (1<<OPTBIT_CREATE )) + 0, // c 707 OPT_DEREFERENCE = USE_FEATURE_TAR_CREATE( (1<<OPTBIT_DEREFERENCE )) + 0, // h 708 OPT_BZIP2 = USE_FEATURE_TAR_BZIP2( (1<<OPTBIT_BZIP2 )) + 0, // j 709 OPT_LZMA = USE_FEATURE_TAR_LZMA( (1<<OPTBIT_LZMA )) + 0, // a 710 OPT_INCLUDE_FROM = USE_FEATURE_TAR_FROM( (1<<OPTBIT_INCLUDE_FROM)) + 0, // T 711 OPT_EXCLUDE_FROM = USE_FEATURE_TAR_FROM( (1<<OPTBIT_EXCLUDE_FROM)) + 0, // X 712 OPT_GZIP = USE_FEATURE_TAR_GZIP( (1<<OPTBIT_GZIP )) + 0, // z 713 OPT_COMPRESS = USE_FEATURE_TAR_COMPRESS((1<<OPTBIT_COMPRESS )) + 0, // Z 714 OPT_NOPRESERVE_OWN = 1 << OPTBIT_NOPRESERVE_OWN , // no-same-owner 715 OPT_NOPRESERVE_PERM = 1 << OPTBIT_NOPRESERVE_PERM, // no-same-permissions 716 }; 717 #if ENABLE_FEATURE_TAR_LONG_OPTIONS 718 static const char tar_longopts[] ALIGN1 = 719 "list\0" No_argument "t" 720 "extract\0" No_argument "x" 721 "directory\0" Required_argument "C" 722 "file\0" Required_argument "f" 723 "to-stdout\0" No_argument "O" 724 "same-permissions\0" No_argument "p" 725 "verbose\0" No_argument "v" 726 "keep-old\0" No_argument "k" 727 # if ENABLE_FEATURE_TAR_CREATE 728 "create\0" No_argument "c" 729 "dereference\0" No_argument "h" 678 730 # endif 679 # if def CONFIG_FEATURE_TAR_BZIP2680 { "bzip2", 0, NULL, 'j' },731 # if ENABLE_FEATURE_TAR_BZIP2 732 "bzip2\0" No_argument "j" 681 733 # endif 682 # if def CONFIG_FEATURE_TAR_LZMA683 { "lzma", 0, NULL, 'a' },734 # if ENABLE_FEATURE_TAR_LZMA 735 "lzma\0" No_argument "a" 684 736 # endif 685 # ifdef CONFIG_FEATURE_TAR_FROM 686 { "files-from", 1, NULL, 'T' }, 687 { "exclude-from", 1, NULL, 'X' }, 688 { "exclude", 1, NULL, '\n' }, 737 # if ENABLE_FEATURE_TAR_FROM 738 "files-from\0" Required_argument "T" 739 "exclude-from\0" Required_argument "X" 689 740 # endif 690 # if def CONFIG_FEATURE_TAR_GZIP691 { "gzip", 0, NULL, 'z' },741 # if ENABLE_FEATURE_TAR_GZIP 742 "gzip\0" No_argument "z" 692 743 # endif 693 # if def CONFIG_FEATURE_TAR_COMPRESS694 { "compress", 0, NULL, 'Z' },744 # if ENABLE_FEATURE_TAR_COMPRESS 745 "compress\0" No_argument "Z" 695 746 # endif 696 { 0, 0, 0, 0 } 697 }; 698 #else 699 #define tar_long_options 0 700 #endif 701 747 "no-same-owner\0" No_argument "\xfd" 748 "no-same-permissions\0" No_argument "\xfe" 749 /* --exclude takes next bit position in option mask, */ 750 /* therefore we have to either put it _after_ --no-same-perm */ 751 /* or add OPT[BIT]_EXCLUDE before OPT[BIT]_NOPRESERVE_OWN */ 752 # if ENABLE_FEATURE_TAR_FROM 753 "exclude\0" Required_argument "\xff" 754 # endif 755 ; 756 #endif 757 758 int tar_main(int argc, char **argv); 702 759 int tar_main(int argc, char **argv) 703 760 { … … 706 763 char *base_dir = NULL; 707 764 const char *tar_filename = "-"; 708 unsigned long opt; 765 unsigned opt; 766 int verboseFlag = 0; 767 #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM 709 768 llist_t *excludes = NULL; 769 #endif 710 770 711 771 /* Initialise default values */ 712 772 tar_handle = init_handle(); 713 tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL; 773 tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS 774 | ARCHIVE_PRESERVE_DATE 775 | ARCHIVE_EXTRACT_UNCONDITIONAL; 714 776 715 777 /* Prepend '-' to the first argument if required */ 716 bb_opt_complementally = ENABLE_FEATURE_TAR_CREATE ? 717 "--:X::T::\n::c:t:x:?:c--tx:t--cx:x--ct" : 718 "--:X::T::\n::t:x:?:t--x:x--t"; 719 if (ENABLE_FEATURE_TAR_LONG_OPTIONS) 720 bb_applet_long_options = tar_long_options; 721 opt = bb_getopt_ulflags(argc, argv, tar_options, 722 &base_dir, /* Change to dir <optarg> */ 723 &tar_filename /* archive filename */ 724 #ifdef CONFIG_FEATURE_TAR_FROM 725 , &(tar_handle->accept), 726 &(tar_handle->reject), 727 &excludes 728 #endif 729 ); 730 731 if (opt & CTX_TEST) { 732 if ((tar_handle->action_header == header_list) || 733 (tar_handle->action_header == header_verbose_list)) 734 { 735 tar_handle->action_header = header_verbose_list; 736 } else tar_handle->action_header = header_list; 737 } 738 if((opt & CTX_EXTRACT) && tar_handle->action_data != data_extract_to_stdout) 778 opt_complementary = "--:" // first arg is options 779 "tt:vv:" // count -t,-v 780 "?:" // bail out with usage instead of error return 781 "X::T::" // cumulative lists 782 #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM 783 "\xff::" // cumulative lists for --exclude 784 #endif 785 USE_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd 786 USE_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive 787 SKIP_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive 788 #if ENABLE_FEATURE_TAR_LONG_OPTIONS 789 applet_long_options = tar_longopts; 790 #endif 791 opt = getopt32(argv, 792 "txC:f:Opvk" 793 USE_FEATURE_TAR_CREATE( "ch" ) 794 USE_FEATURE_TAR_BZIP2( "j" ) 795 USE_FEATURE_TAR_LZMA( "a" ) 796 USE_FEATURE_TAR_FROM( "T:X:") 797 USE_FEATURE_TAR_GZIP( "z" ) 798 USE_FEATURE_TAR_COMPRESS("Z" ) 799 , &base_dir // -C dir 800 , &tar_filename // -f filename 801 USE_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T 802 USE_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X 803 #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM 804 , &excludes // --exclude 805 #endif 806 , &verboseFlag // combined count for -t and -v 807 , &verboseFlag // combined count for -t and -v 808 ); 809 810 if (verboseFlag) tar_handle->action_header = header_verbose_list; 811 if (verboseFlag == 1) tar_handle->action_header = header_list; 812 813 if (opt & OPT_EXTRACT) 739 814 tar_handle->action_data = data_extract_all; 740 815 741 if (opt & TAR_OPT_2STDOUT)816 if (opt & OPT_2STDOUT) 742 817 tar_handle->action_data = data_extract_to_stdout; 743 818 744 if (opt & TAR_OPT_VERBOSE) { 745 if ((tar_handle->action_header == header_list) || 746 (tar_handle->action_header == header_verbose_list)) 747 { 748 tar_handle->action_header = header_verbose_list; 749 } else 750 tar_handle->action_header = header_list; 751 } 752 if (opt & TAR_OPT_KEEP_OLD) 819 if (opt & OPT_KEEP_OLD) 753 820 tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL; 754 821 755 if (opt & TAR_OPT_NOPRESERVE_OWN)822 if (opt & OPT_NOPRESERVE_OWN) 756 823 tar_handle->flags |= ARCHIVE_NOPRESERVE_OWN; 757 824 758 if (opt & TAR_OPT_NOPRESERVE_PERM)825 if (opt & OPT_NOPRESERVE_PERM) 759 826 tar_handle->flags |= ARCHIVE_NOPRESERVE_PERM; 760 827 761 if ( ENABLE_FEATURE_TAR_GZIP && (opt & TAR_OPT_GZIP))828 if (opt & OPT_GZIP) 762 829 get_header_ptr = get_header_tar_gz; 763 830 764 if ( ENABLE_FEATURE_TAR_BZIP2 && (opt & TAR_OPT_BZIP2))831 if (opt & OPT_BZIP2) 765 832 get_header_ptr = get_header_tar_bz2; 766 833 767 if ( ENABLE_FEATURE_TAR_LZMA && (opt & TAR_OPT_LZMA))834 if (opt & OPT_LZMA) 768 835 get_header_ptr = get_header_tar_lzma; 769 836 770 if ( ENABLE_FEATURE_TAR_COMPRESS && (opt & TAR_OPT_UNCOMPRESS))837 if (opt & OPT_COMPRESS) 771 838 get_header_ptr = get_header_tar_Z; 772 839 773 if (ENABLE_FEATURE_TAR_FROM) { 774 tar_handle->reject = append_file_list_to_list(tar_handle->reject); 775 /* Append excludes to reject */ 776 while (excludes) { 777 llist_t *temp = excludes->link; 778 excludes->link = tar_handle->reject; 779 tar_handle->reject = excludes; 780 excludes = temp; 781 } 782 tar_handle->accept = append_file_list_to_list(tar_handle->accept); 783 } 840 #if ENABLE_FEATURE_TAR_FROM 841 tar_handle->reject = append_file_list_to_list(tar_handle->reject); 842 #if ENABLE_FEATURE_TAR_LONG_OPTIONS 843 /* Append excludes to reject */ 844 while (excludes) { 845 llist_t *next = excludes->link; 846 excludes->link = tar_handle->reject; 847 tar_handle->reject = excludes; 848 excludes = next; 849 } 850 #endif 851 tar_handle->accept = append_file_list_to_list(tar_handle->accept); 852 #endif 784 853 785 854 /* Check if we are reading from stdin */ … … 792 861 /* TODO: This is the same as in ar, separate function ? */ 793 862 while (optind < argc) { 794 char *filename_ptr = last_char_is(argv[optind], '/');795 if (filename_ptr > argv[optind])796 *filename_ptr = '\0';797 798 llist_add_to (&(tar_handle->accept), argv[optind]);863 /* kill trailing '/' unless the string is just "/" */ 864 char *cp = last_char_is(argv[optind], '/'); 865 if (cp > argv[optind]) 866 *cp = '\0'; 867 llist_add_to_end(&tar_handle->accept, argv[optind]); 799 868 optind++; 800 869 } 801 870 802 if ( (tar_handle->accept) || (tar_handle->reject))871 if (tar_handle->accept || tar_handle->reject) 803 872 tar_handle->filter = filter_accept_reject_list; 804 873 … … 808 877 int flags; 809 878 810 if ( ENABLE_FEATURE_TAR_CREATE && (opt & CTX_CREATE)) {879 if (opt & OPT_CREATE) { 811 880 /* Make sure there is at least one file to tar up. */ 812 881 if (tar_handle->accept == NULL) … … 814 883 815 884 tar_stream = stdout; 816 flags = O_WRONLY | O_CREAT | O_EXCL; 817 unlink(tar_filename); 885 /* Mimicking GNU tar 1.15.1: */ 886 flags = O_WRONLY|O_CREAT|O_TRUNC; 887 /* was doing unlink; open(O_WRONLY|O_CREAT|O_EXCL); why? */ 818 888 } else { 819 889 tar_stream = stdin; … … 821 891 } 822 892 823 if ( (tar_filename[0] == '-') && (tar_filename[1] == '\0')) {893 if (LONE_DASH(tar_filename)) { 824 894 tar_handle->src_fd = fileno(tar_stream); 825 tar_handle->seek = seek_by_ char;895 tar_handle->seek = seek_by_read; 826 896 } else { 827 tar_handle->src_fd = bb_xopen(tar_filename, flags);897 tar_handle->src_fd = xopen(tar_filename, flags); 828 898 } 829 899 } 830 900 831 901 if (base_dir) 832 bb_xchdir(base_dir); 902 xchdir(base_dir); 903 904 #ifdef CHECK_FOR_CHILD_EXITCODE 905 /* We need to know whether child (gzip/bzip/etc) exits abnormally */ 906 signal(SIGCHLD, handle_SIGCHLD); 907 #endif 833 908 834 909 /* create an archive */ 835 if (ENABLE_FEATURE_TAR_CREATE && (opt & CTX_CREATE)) { 836 int verboseFlag = FALSE; 910 if (opt & OPT_CREATE) { 837 911 int zipMode = 0; 838 839 912 if (ENABLE_FEATURE_TAR_GZIP && get_header_ptr == get_header_tar_gz) 840 913 zipMode = 1; 841 914 if (ENABLE_FEATURE_TAR_BZIP2 && get_header_ptr == get_header_tar_bz2) 842 915 zipMode = 2; 843 844 if ((tar_handle->action_header == header_list) || 845 (tar_handle->action_header == header_verbose_list)) 846 { 847 verboseFlag = TRUE; 848 } 849 writeTarFile(tar_handle->src_fd, verboseFlag, opt & TAR_OPT_DEREFERENCE, 916 /* NB: writeTarFile() closes tar_handle->src_fd */ 917 return writeTarFile(tar_handle->src_fd, verboseFlag, opt & OPT_DEREFERENCE, 850 918 tar_handle->accept, 851 tar_handle->reject, zipMode); 852 } else { 853 while (get_header_ptr(tar_handle) == EXIT_SUCCESS); 854 855 /* Check that every file that should have been extracted was */ 856 while (tar_handle->accept) { 857 if (!find_list_entry(tar_handle->reject, tar_handle->accept->data) 858 && !find_list_entry(tar_handle->passed, tar_handle->accept->data)) 859 { 860 bb_error_msg_and_die("%s: Not found in archive", tar_handle->accept->data); 861 } 862 tar_handle->accept = tar_handle->accept->link; 863 } 864 } 865 866 if (ENABLE_FEATURE_CLEAN_UP && tar_handle->src_fd != STDIN_FILENO) 919 tar_handle->reject, zipMode); 920 } 921 922 while (get_header_ptr(tar_handle) == EXIT_SUCCESS) 923 /* nothing */; 924 925 /* Check that every file that should have been extracted was */ 926 while (tar_handle->accept) { 927 if (!find_list_entry(tar_handle->reject, tar_handle->accept->data) 928 && !find_list_entry(tar_handle->passed, tar_handle->accept->data) 929 ) { 930 bb_error_msg_and_die("%s: not found in archive", 931 tar_handle->accept->data); 932 } 933 tar_handle->accept = tar_handle->accept->link; 934 } 935 if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */) 867 936 close(tar_handle->src_fd); 868 937 869 return (EXIT_SUCCESS);870 } 938 return EXIT_SUCCESS; 939 } -
branches/2.2.5/mindi-busybox/archival/unzip.c
r821 r1765 25 25 */ 26 26 27 #include <fcntl.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <unistd.h> 31 #include <errno.h> 27 #include "libbb.h" 32 28 #include "unarchive.h" 33 #include "busybox.h" 34 35 #if BB_BIG_ENDIAN 36 static inline unsigned short 37 __swap16(unsigned short x) { 38 return (((uint16_t)(x) & 0xFF) << 8) | (((uint16_t)(x) & 0xFF00) >> 8); 39 } 40 41 static inline uint32_t 42 __swap32(uint32_t x) { 43 return (((x & 0xFF) << 24) | 44 ((x & 0xFF00) << 8) | 45 ((x & 0xFF0000) >> 8) | 46 ((x & 0xFF000000) >> 24)); 47 } 48 #else /* it's little-endian */ 49 # define __swap16(x) (x) 50 # define __swap32(x) (x) 51 #endif /* BB_BIG_ENDIAN */ 52 53 #define ZIP_FILEHEADER_MAGIC __swap32(0x04034b50) 54 #define ZIP_CDS_MAGIC __swap32(0x02014b50) 55 #define ZIP_CDS_END_MAGIC __swap32(0x06054b50) 56 #define ZIP_DD_MAGIC __swap32(0x08074b50) 57 58 extern unsigned int gunzip_crc; 59 extern unsigned int gunzip_bytes_out; 29 30 #define ZIP_FILEHEADER_MAGIC SWAP_LE32(0x04034b50) 31 #define ZIP_CDS_MAGIC SWAP_LE32(0x02014b50) 32 #define ZIP_CDS_END_MAGIC SWAP_LE32(0x06054b50) 33 #define ZIP_DD_MAGIC SWAP_LE32(0x08074b50) 60 34 61 35 typedef union { … … 72 46 unsigned short filename_len; /* 22-23 */ 73 47 unsigned short extra_len; /* 24-25 */ 74 } format ed ATTRIBUTE_PACKED;48 } formatted ATTRIBUTE_PACKED; 75 49 } zip_header_t; 76 50 … … 78 52 { 79 53 if (lseek(fd, skip, SEEK_CUR) == (off_t)-1) { 80 if ((errno != ESPIPE) || (bb_copyfd_size(fd, -1, skip) != skip)) { 81 bb_error_msg_and_die("Seek failure"); 82 } 83 } 84 } 85 86 static void unzip_read(int fd, void *buf, size_t count) 87 { 88 if (bb_xread(fd, buf, count) != count) { 89 bb_error_msg_and_die(bb_msg_read_error); 54 if (errno != ESPIPE) 55 bb_error_msg_and_die("seek failure"); 56 bb_copyfd_exact_size(fd, -1, skip); 90 57 } 91 58 } … … 94 61 { 95 62 /* Create all leading directories */ 96 char *name = bb_xstrdup(fn);63 char *name = xstrdup(fn); 97 64 if (bb_make_directory(dirname(name), 0777, FILEUTILS_RECUR)) { 98 bb_error_msg_and_die(" Exiting"); /* bb_make_directory is noisy */65 bb_error_msg_and_die("exiting"); /* bb_make_directory is noisy */ 99 66 } 100 67 free(name); … … 103 70 static int unzip_extract(zip_header_t *zip_header, int src_fd, int dst_fd) 104 71 { 105 if (zip_header->format ed.method == 0) {72 if (zip_header->formatted.method == 0) { 106 73 /* Method 0 - stored (not compressed) */ 107 int size = zip_header->formated.ucmpsize; 108 if (size && (bb_copyfd_size(src_fd, dst_fd, size) != size)) { 109 bb_error_msg_and_die("Cannot complete extraction"); 110 } 111 74 off_t size = zip_header->formatted.ucmpsize; 75 if (size) 76 bb_copyfd_exact_size(src_fd, dst_fd, size); 112 77 } else { 113 78 /* Method 8 - inflate */ 114 inflate_ init(zip_header->formated.cmpsize);115 inflate_unzip(src_fd, dst_fd);116 inflate_cleanup(); 79 inflate_unzip_result res; 80 /* err = */ inflate_unzip(&res, zip_header->formatted.cmpsize, src_fd, dst_fd); 81 // we should check for -1 error return 117 82 /* Validate decompression - crc */ 118 if (zip_header->format ed.crc32 != (gunzip_crc ^ 0xffffffffL)) {119 bb_error_msg(" Invalid compressed data--crc error");83 if (zip_header->formatted.crc32 != (res.crc ^ 0xffffffffL)) { 84 bb_error_msg("invalid compressed data--%s error", "crc"); 120 85 return 1; 121 86 } 122 87 /* Validate decompression - size */ 123 if (zip_header->format ed.ucmpsize != gunzip_bytes_out) {124 bb_error_msg(" Invalid compressed data--length error");88 if (zip_header->formatted.ucmpsize != res.bytes_out) { 89 bb_error_msg("invalid compressed data--%s error", "length"); 125 90 return 1; 126 91 } … … 129 94 } 130 95 96 int unzip_main(int argc, char **argv); 131 97 int unzip_main(int argc, char **argv) 132 98 { … … 145 111 struct stat stat_buf; 146 112 147 while ((opt = getopt(argc, argv, "-d:lnopqx")) != -1) {148 switch (opt_range) {113 while ((opt = getopt(argc, argv, "-d:lnopqx")) != -1) { 114 switch (opt_range) { 149 115 case 0: /* Options */ 150 switch (opt) {116 switch (opt) { 151 117 case 'l': /* List */ 152 118 verbosity = v_list; … … 169 135 170 136 case 1 : /* The zip file */ 171 src_fn = bb_xstrndup(optarg, strlen(optarg)+4); 137 src_fn = xmalloc(strlen(optarg)+4); 138 strcpy(src_fn, optarg); 172 139 opt_range++; 173 140 break; … … 218 185 219 186 /* Open input file */ 220 if ( strcmp("-", src_fn) == 0) {187 if (LONE_DASH(src_fn)) { 221 188 src_fd = STDIN_FILENO; 222 189 /* Cannot use prompt mode since zip data is arriving on STDIN */ 223 190 overwrite = (overwrite == o_prompt) ? o_never : overwrite; 224 225 191 } else { 226 192 static const char *const extn[] = {"", ".zip", ".ZIP"}; 227 193 int orig_src_fn_len = strlen(src_fn); 228 for (i = 0; (i < 3) && (src_fd == -1); i++) {194 for (i = 0; (i < 3) && (src_fd == -1); i++) { 229 195 strcpy(src_fn + orig_src_fn_len, extn[i]); 230 196 src_fd = open(src_fn, O_RDONLY); 231 197 } 232 198 if (src_fd == -1) { 233 src_fn[orig_src_fn_len] = 0;234 bb_error_msg_and_die(" Cannot open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn);199 src_fn[orig_src_fn_len] = '\0'; 200 bb_error_msg_and_die("cannot open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn); 235 201 } 236 202 } … … 238 204 /* Change dir if necessary */ 239 205 if (base_dir) 240 bb_xchdir(base_dir);206 xchdir(base_dir); 241 207 242 208 if (verbosity != v_silent) … … 249 215 250 216 /* Check magic number */ 251 unzip_read(src_fd, &magic, 4);217 xread(src_fd, &magic, 4); 252 218 if (magic == ZIP_CDS_MAGIC) { 253 219 break; 254 220 } else if (magic != ZIP_FILEHEADER_MAGIC) { 255 bb_error_msg_and_die(" Invalid zip magic %08X", magic);221 bb_error_msg_and_die("invalid zip magic %08X", magic); 256 222 } 257 223 258 224 /* Read the file header */ 259 unzip_read(src_fd, zip_header.raw, 26); 260 #if BB_BIG_ENDIAN 261 zip_header.formated.version = __swap16(zip_header.formated.version); 262 zip_header.formated.flags = __swap16(zip_header.formated.flags); 263 zip_header.formated.method = __swap16(zip_header.formated.method); 264 zip_header.formated.modtime = __swap16(zip_header.formated.modtime); 265 zip_header.formated.moddate = __swap16(zip_header.formated.moddate); 266 zip_header.formated.crc32 = __swap32(zip_header.formated.crc32); 267 zip_header.formated.cmpsize = __swap32(zip_header.formated.cmpsize); 268 zip_header.formated.ucmpsize = __swap32(zip_header.formated.ucmpsize); 269 zip_header.formated.filename_len = __swap16(zip_header.formated.filename_len); 270 zip_header.formated.extra_len = __swap16(zip_header.formated.extra_len); 271 #endif /* BB_BIG_ENDIAN */ 272 if ((zip_header.formated.method != 0) && (zip_header.formated.method != 8)) { 273 bb_error_msg_and_die("Unsupported compression method %d", zip_header.formated.method); 225 xread(src_fd, zip_header.raw, 26); 226 zip_header.formatted.version = SWAP_LE32(zip_header.formatted.version); 227 zip_header.formatted.flags = SWAP_LE32(zip_header.formatted.flags); 228 zip_header.formatted.method = SWAP_LE32(zip_header.formatted.method); 229 zip_header.formatted.modtime = SWAP_LE32(zip_header.formatted.modtime); 230 zip_header.formatted.moddate = SWAP_LE32(zip_header.formatted.moddate); 231 zip_header.formatted.crc32 = SWAP_LE32(zip_header.formatted.crc32); 232 zip_header.formatted.cmpsize = SWAP_LE32(zip_header.formatted.cmpsize); 233 zip_header.formatted.ucmpsize = SWAP_LE32(zip_header.formatted.ucmpsize); 234 zip_header.formatted.filename_len = SWAP_LE32(zip_header.formatted.filename_len); 235 zip_header.formatted.extra_len = SWAP_LE32(zip_header.formatted.extra_len); 236 if ((zip_header.formatted.method != 0) && (zip_header.formatted.method != 8)) { 237 bb_error_msg_and_die("unsupported compression method %d", zip_header.formatted.method); 274 238 } 275 239 276 240 /* Read filename */ 277 241 free(dst_fn); 278 dst_fn = xzalloc(zip_header.format ed.filename_len + 1);279 unzip_read(src_fd, dst_fn, zip_header.formated.filename_len);242 dst_fn = xzalloc(zip_header.formatted.filename_len + 1); 243 xread(src_fd, dst_fn, zip_header.formatted.filename_len); 280 244 281 245 /* Skip extra header bytes */ 282 unzip_skip(src_fd, zip_header.format ed.extra_len);246 unzip_skip(src_fd, zip_header.formatted.extra_len); 283 247 284 248 if ((verbosity == v_list) && !list_header_done){ 285 p rintf(" Length Date Time Name\n"286 " -------- ---- ---- ----\n");249 puts(" Length Date Time Name\n" 250 " -------- ---- ---- ----"); 287 251 list_header_done = 1; 288 252 } … … 294 258 295 259 } else { /* Extract entry */ 296 total_size += zip_header.format ed.ucmpsize;260 total_size += zip_header.formatted.ucmpsize; 297 261 298 262 if (verbosity == v_list) { /* List entry */ 299 unsigned int dostime = zip_header.format ed.modtime | (zip_header.formated.moddate << 16);263 unsigned int dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16); 300 264 printf("%9u %02u-%02u-%02u %02u:%02u %s\n", 301 zip_header.format ed.ucmpsize,265 zip_header.formatted.ucmpsize, 302 266 (dostime & 0x01e00000) >> 21, 303 267 (dostime & 0x001f0000) >> 16, … … 308 272 total_entries++; 309 273 i = 'n'; 310 311 274 } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */ 312 275 i = -1; 313 314 276 } else if (last_char_is(dst_fn, '/')) { /* Extract directory */ 315 277 if (stat(dst_fn, &stat_buf) == -1) { 316 278 if (errno != ENOENT) { 317 bb_perror_msg_and_die(" Cannot stat '%s'",dst_fn);279 bb_perror_msg_and_die("cannot stat '%s'",dst_fn); 318 280 } 319 281 if (verbosity == v_normal) { … … 322 284 unzip_create_leading_dirs(dst_fn); 323 285 if (bb_make_directory(dst_fn, 0777, 0)) { 324 bb_error_msg_and_die(" Exiting");286 bb_error_msg_and_die("exiting"); 325 287 } 326 288 } else { … … 332 294 333 295 } else { /* Extract file */ 334 296 _check_file: 335 297 if (stat(dst_fn, &stat_buf) == -1) { /* File does not exist */ 336 298 if (errno != ENOENT) { 337 bb_perror_msg_and_die(" Cannot stat '%s'",dst_fn);299 bb_perror_msg_and_die("cannot stat '%s'",dst_fn); 338 300 } 339 301 i = 'y'; 340 341 302 } else { /* File already exists */ 342 303 if (overwrite == o_never) { 343 304 i = 'n'; 344 345 305 } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */ 346 306 if (overwrite == o_always) { … … 349 309 printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); 350 310 if (!fgets(key_buf, 512, stdin)) { 351 bb_perror_msg_and_die(" Cannot read input");311 bb_perror_msg_and_die("cannot read input"); 352 312 } 353 313 i = key_buf[0]; 354 314 } 355 356 315 } else { /* File is not regular file */ 357 316 bb_error_msg_and_die("'%s' exists but is not regular file",dst_fn); … … 366 325 case 'y': /* Open file and fall into unzip */ 367 326 unzip_create_leading_dirs(dst_fn); 368 dst_fd = bb_xopen(dst_fn, O_WRONLY | O_CREAT);327 dst_fd = xopen(dst_fn, O_WRONLY | O_CREAT | O_TRUNC); 369 328 case -1: /* Unzip */ 370 329 if (verbosity == v_normal) { … … 372 331 } 373 332 if (unzip_extract(&zip_header, src_fd, dst_fd)) { 374 333 failed = 1; 375 334 } 376 335 if (dst_fd != STDOUT_FILENO) { … … 384 343 case 'n': 385 344 /* Skip entry data */ 386 unzip_skip(src_fd, zip_header.format ed.cmpsize);345 unzip_skip(src_fd, zip_header.formatted.cmpsize); 387 346 break; 388 347 … … 391 350 printf("new name: "); 392 351 if (!fgets(key_buf, 512, stdin)) { 393 bb_perror_msg_and_die(" Cannot read input");352 bb_perror_msg_and_die("cannot read input"); 394 353 } 395 354 free(dst_fn); 396 dst_fn = bb_xstrdup(key_buf);355 dst_fn = xstrdup(key_buf); 397 356 chomp(dst_fn); 398 357 goto _check_file; … … 404 363 405 364 /* Data descriptor section */ 406 if (zip_header.format ed.flags & 4) {365 if (zip_header.formatted.flags & 4) { 407 366 /* skip over duplicate crc, compressed size and uncompressed size */ 408 367 unzip_skip(src_fd, 12);
Note:
See TracChangeset
for help on using the changeset viewer.