Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | /* vi: set sw=4 ts=4: */
#ifndef UNARCHIVE_H
#define UNARCHIVE_H 1
PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
enum {
#if BB_BIG_ENDIAN
COMPRESS_MAGIC = 0x1f9d,
GZIP_MAGIC = 0x1f8b,
BZIP2_MAGIC = 'B' * 256 + 'Z',
/* .xz signature: 0xfd, '7', 'z', 'X', 'Z', 0x00 */
/* More info at: http://tukaani.org/xz/xz-file-format.txt */
XZ_MAGIC1 = 0xfd * 256 + '7',
XZ_MAGIC2 = (('z' * 256 + 'X') * 256 + 'Z') * 256 + 0,
/* Different form: 32 bits, then 16 bits: */
XZ_MAGIC1a = ((0xfd * 256 + '7') * 256 + 'z') * 256 + 'X',
XZ_MAGIC2a = 'Z' * 256 + 0,
#else
COMPRESS_MAGIC = 0x9d1f,
GZIP_MAGIC = 0x8b1f,
BZIP2_MAGIC = 'Z' * 256 + 'B',
XZ_MAGIC1 = '7' * 256 + 0xfd,
XZ_MAGIC2 = ((0 * 256 + 'Z') * 256 + 'X') * 256 + 'z',
XZ_MAGIC1a = (('X' * 256 + 'z') * 256 + '7') * 256 + 0xfd,
XZ_MAGIC2a = 0 * 256 + 'Z',
#endif
};
typedef struct file_header_t {
char *name;
char *link_target;
#if ENABLE_FEATURE_TAR_UNAME_GNAME
char *tar__uname;
char *tar__gname;
#endif
off_t size;
uid_t uid;
gid_t gid;
mode_t mode;
time_t mtime;
dev_t device;
} file_header_t;
struct hardlinks_t;
typedef struct archive_handle_t {
/* Flags. 1st since it is most used member */
unsigned ah_flags;
/* The raw stream as read from disk or stdin */
int src_fd;
/* Define if the header and data component should be processed */
char FAST_FUNC (*filter)(struct archive_handle_t *);
/* List of files that have been accepted */
llist_t *accept;
/* List of files that have been rejected */
llist_t *reject;
/* List of files that have successfully been worked on */
llist_t *passed;
/* Currently processed file's header */
file_header_t *file_header;
/* Process the header component, e.g. tar -t */
void FAST_FUNC (*action_header)(const file_header_t *);
/* Process the data component, e.g. extract to filesystem */
void FAST_FUNC (*action_data)(struct archive_handle_t *);
/* Function that skips data */
void FAST_FUNC (*seek)(int fd, off_t amount);
/* Count processed bytes */
off_t offset;
/* Archiver specific. Can make it a union if it ever gets big */
#if ENABLE_TAR || ENABLE_DPKG || ENABLE_DPKG_DEB
smallint tar__end;
# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
char* tar__longname;
char* tar__linkname;
# endif
#if ENABLE_FEATURE_TAR_TO_COMMAND
char* tar__to_command;
#endif
# if ENABLE_FEATURE_TAR_SELINUX
char* tar__global_sctx;
char* tar__next_file_sctx;
# endif
#endif
#if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM
uoff_t cpio__blocks;
struct hardlinks_t *cpio__hardlinks_to_create;
struct hardlinks_t *cpio__created_hardlinks;
#endif
#if ENABLE_DPKG || ENABLE_DPKG_DEB
/* Temporary storage */
char *dpkg__buffer;
/* How to process any sub archive, e.g. get_header_tar_gz */
char FAST_FUNC (*dpkg__action_data_subarchive)(struct archive_handle_t *);
/* Contains the handle to a sub archive */
struct archive_handle_t *dpkg__sub_archive;
#endif
#if ENABLE_FEATURE_AR_CREATE
const char *ar__name;
struct archive_handle_t *ar__out;
#endif
} archive_handle_t;
/* bits in ah_flags */
#define ARCHIVE_RESTORE_DATE (1 << 0)
#define ARCHIVE_CREATE_LEADING_DIRS (1 << 1)
#define ARCHIVE_UNLINK_OLD (1 << 2)
#define ARCHIVE_EXTRACT_QUIET (1 << 3)
#define ARCHIVE_EXTRACT_NEWER (1 << 4)
#define ARCHIVE_DONT_RESTORE_OWNER (1 << 5)
#define ARCHIVE_DONT_RESTORE_PERM (1 << 6)
#define ARCHIVE_NUMERIC_OWNER (1 << 7)
#define ARCHIVE_O_TRUNC (1 << 8)
/* POSIX tar Header Block, from POSIX 1003.1-1990 */
#define TAR_BLOCK_SIZE 512
#define NAME_SIZE 100
#define NAME_SIZE_STR "100"
typedef struct tar_header_t { /* byte offset */
char name[NAME_SIZE]; /* 0-99 */
char mode[8]; /* 100-107 */
char uid[8]; /* 108-115 */
char gid[8]; /* 116-123 */
char size[12]; /* 124-135 */
char mtime[12]; /* 136-147 */
char chksum[8]; /* 148-155 */
char typeflag; /* 156-156 */
char linkname[NAME_SIZE]; /* 157-256 */
/* POSIX: "ustar" NUL "00" */
/* GNU tar: "ustar " NUL */
/* Normally it's defined as magic[6] followed by
* version[2], but we put them together to save code.
*/
char magic[8]; /* 257-264 */
char uname[32]; /* 265-296 */
char gname[32]; /* 297-328 */
char devmajor[8]; /* 329-336 */
char devminor[8]; /* 337-344 */
char prefix[155]; /* 345-499 */
char padding[12]; /* 500-512 (pad to exactly TAR_BLOCK_SIZE) */
} tar_header_t;
struct BUG_tar_header {
char c[sizeof(tar_header_t) == TAR_BLOCK_SIZE ? 1 : -1];
};
/* Info struct unpackers can fill out to inform users of thing like
* timestamps of unpacked files */
typedef struct unpack_info_t {
time_t mtime;
} unpack_info_t;
extern archive_handle_t *init_handle(void) FAST_FUNC;
extern char filter_accept_all(archive_handle_t *archive_handle) FAST_FUNC;
extern char filter_accept_list(archive_handle_t *archive_handle) FAST_FUNC;
extern char filter_accept_list_reassign(archive_handle_t *archive_handle) FAST_FUNC;
extern char filter_accept_reject_list(archive_handle_t *archive_handle) FAST_FUNC;
extern void unpack_ar_archive(archive_handle_t *ar_archive) FAST_FUNC;
extern void data_skip(archive_handle_t *archive_handle) FAST_FUNC;
extern void data_extract_all(archive_handle_t *archive_handle) FAST_FUNC;
extern void data_extract_to_stdout(archive_handle_t *archive_handle) FAST_FUNC;
extern void data_extract_to_command(archive_handle_t *archive_handle) FAST_FUNC;
extern void header_skip(const file_header_t *file_header) FAST_FUNC;
extern void header_list(const file_header_t *file_header) FAST_FUNC;
extern void header_verbose_list(const file_header_t *file_header) FAST_FUNC;
extern char get_header_ar(archive_handle_t *archive_handle) FAST_FUNC;
extern char get_header_cpio(archive_handle_t *archive_handle) FAST_FUNC;
extern char get_header_tar(archive_handle_t *archive_handle) FAST_FUNC;
extern char get_header_tar_gz(archive_handle_t *archive_handle) FAST_FUNC;
extern char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC;
extern char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC;
extern void seek_by_jump(int fd, off_t amount) FAST_FUNC;
extern void seek_by_read(int fd, off_t amount) FAST_FUNC;
extern void data_align(archive_handle_t *archive_handle, unsigned boundary) FAST_FUNC;
extern const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_FUNC;
extern const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_FUNC;
/* A bit of bunzip2 internals are exposed for compressed help support: */
typedef struct bunzip_data bunzip_data;
int start_bunzip(bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC;
/* NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes
* in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0: */
int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC;
void dealloc_bunzip(bunzip_data *bd) FAST_FUNC;
typedef struct inflate_unzip_result {
off_t bytes_out;
uint32_t crc;
} inflate_unzip_result;
IF_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd) FAST_FUNC;
/* xz unpacker takes .xz stream from offset 6 */
IF_DESKTOP(long long) int unpack_xz_stream(int src_fd, int dst_fd) FAST_FUNC;
/* lzma unpacker takes .lzma stream from offset 0 */
IF_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC;
/* the rest wants 2 first bytes already skipped by the caller */
IF_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd) FAST_FUNC;
IF_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_FUNC;
IF_DESKTOP(long long) int unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) FAST_FUNC;
IF_DESKTOP(long long) int unpack_Z_stream(int src_fd, int dst_fd) FAST_FUNC;
/* wrapper which checks first two bytes to be "BZ" */
IF_DESKTOP(long long) int unpack_bz2_stream_prime(int src_fd, int dst_fd) FAST_FUNC;
char* append_ext(char *filename, const char *expected_ext) FAST_FUNC;
int bbunpack(char **argv,
IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info),
char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext),
const char *expected_ext
) FAST_FUNC;
#if BB_MMU
void open_transformer(int fd,
IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd)) FAST_FUNC;
#define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transformer)
#else
void open_transformer(int src_fd, const char *transform_prog) FAST_FUNC;
#define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transform_prog)
#endif
POP_SAVED_FUNCTION_VISIBILITY
#endif
|