libarchive-static 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/Makefile +6 -0
- data/ext/extconf.rb +61 -0
- data/ext/libarchive-0.1.1/COPYING.libarchive +60 -0
- data/ext/libarchive-0.1.1/LICENSE.libbzip2 +42 -0
- data/ext/libarchive-0.1.1/README.txt +143 -0
- data/ext/libarchive-0.1.1/ext/Makefile.in +0 -0
- data/ext/libarchive-0.1.1/ext/archive_read_support_compression.c +31 -0
- data/ext/libarchive-0.1.1/ext/archive_read_support_compression.h +6 -0
- data/ext/libarchive-0.1.1/ext/archive_read_support_format.c +32 -0
- data/ext/libarchive-0.1.1/ext/archive_read_support_format.h +6 -0
- data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.c +29 -0
- data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.h +6 -0
- data/ext/libarchive-0.1.1/ext/archive_write_set_compression.c +32 -0
- data/ext/libarchive-0.1.1/ext/archive_write_set_compression.h +6 -0
- data/ext/libarchive-0.1.1/ext/config.h.in +22 -0
- data/ext/libarchive-0.1.1/ext/configure +3904 -0
- data/ext/libarchive-0.1.1/ext/configure.in +11 -0
- data/ext/libarchive-0.1.1/ext/depend +19 -0
- data/ext/libarchive-0.1.1/ext/extconf.rb +6 -0
- data/ext/libarchive-0.1.1/ext/install-sh +250 -0
- data/ext/libarchive-0.1.1/ext/libarchive.c +89 -0
- data/ext/libarchive-0.1.1/ext/libarchive_archive.c +84 -0
- data/ext/libarchive-0.1.1/ext/libarchive_entry.c +1015 -0
- data/ext/libarchive-0.1.1/ext/libarchive_internal.h +155 -0
- data/ext/libarchive-0.1.1/ext/libarchive_reader.c +328 -0
- data/ext/libarchive-0.1.1/ext/libarchive_win32.h +52 -0
- data/ext/libarchive-0.1.1/ext/libarchive_writer.c +246 -0
- data/ext/libarchive-0.1.1/libarchive.c +1762 -0
- data/ext/libarchive-2.8.4/Makefile.in +7076 -0
- data/ext/libarchive-2.8.4/build/autoconf/check_stdcall_func.m4 +51 -0
- data/ext/libarchive-2.8.4/build/autoconf/compile +143 -0
- data/ext/libarchive-2.8.4/build/autoconf/config.guess +1502 -0
- data/ext/libarchive-2.8.4/build/autoconf/config.sub +1708 -0
- data/ext/libarchive-2.8.4/build/autoconf/depcomp +630 -0
- data/ext/libarchive-2.8.4/build/autoconf/install-sh +291 -0
- data/ext/libarchive-2.8.4/build/autoconf/la_uid_t.m4 +20 -0
- data/ext/libarchive-2.8.4/build/autoconf/ltmain.sh +8406 -0
- data/ext/libarchive-2.8.4/build/autoconf/missing +376 -0
- data/ext/libarchive-2.8.4/build/pkgconfig/libarchive.pc.in +10 -0
- data/ext/libarchive-2.8.4/config.h.in +772 -0
- data/ext/libarchive-2.8.4/configure +17916 -0
- data/ext/libarchive-2.8.4/libarchive/archive.h +741 -0
- data/ext/libarchive-2.8.4/libarchive/archive_check_magic.c +134 -0
- data/ext/libarchive-2.8.4/libarchive/archive_crc32.h +66 -0
- data/ext/libarchive-2.8.4/libarchive/archive_endian.h +162 -0
- data/ext/libarchive-2.8.4/libarchive/archive_entry.c +2202 -0
- data/ext/libarchive-2.8.4/libarchive/archive_entry.h +524 -0
- data/ext/libarchive-2.8.4/libarchive/archive_entry_copy_bhfi.c +74 -0
- data/ext/libarchive-2.8.4/libarchive/archive_entry_copy_stat.c +77 -0
- data/ext/libarchive-2.8.4/libarchive/archive_entry_link_resolver.c +405 -0
- data/ext/libarchive-2.8.4/libarchive/archive_entry_private.h +184 -0
- data/ext/libarchive-2.8.4/libarchive/archive_entry_stat.c +118 -0
- data/ext/libarchive-2.8.4/libarchive/archive_entry_strmode.c +87 -0
- data/ext/libarchive-2.8.4/libarchive/archive_entry_xattr.c +158 -0
- data/ext/libarchive-2.8.4/libarchive/archive_hash.h +281 -0
- data/ext/libarchive-2.8.4/libarchive/archive_platform.h +165 -0
- data/ext/libarchive-2.8.4/libarchive/archive_private.h +124 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read.c +1249 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_data_into_fd.c +93 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_disk.c +198 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_disk_entry_from_file.c +570 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_disk_private.h +62 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_disk_set_standard_lookup.c +303 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_extract.c +182 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_open_fd.c +190 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_open_file.c +165 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_open_filename.c +272 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_open_memory.c +156 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_private.h +199 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_all.c +60 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_bzip2.c +353 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_compress.c +444 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_gzip.c +465 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_none.c +40 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_program.c +459 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_rpm.c +287 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_uu.c +627 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_xz.c +708 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_all.c +43 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_ar.c +584 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_cpio.c +777 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_empty.c +93 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_iso9660.c +2830 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_mtree.c +1304 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_raw.c +185 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_tar.c +2418 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_xar.c +3151 -0
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_zip.c +903 -0
- data/ext/libarchive-2.8.4/libarchive/archive_string.c +453 -0
- data/ext/libarchive-2.8.4/libarchive/archive_string.h +148 -0
- data/ext/libarchive-2.8.4/libarchive/archive_string_sprintf.c +164 -0
- data/ext/libarchive-2.8.4/libarchive/archive_util.c +391 -0
- data/ext/libarchive-2.8.4/libarchive/archive_virtual.c +94 -0
- data/ext/libarchive-2.8.4/libarchive/archive_windows.c +1236 -0
- data/ext/libarchive-2.8.4/libarchive/archive_windows.h +347 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write.c +466 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_disk.c +2628 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_disk_private.h +38 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_disk_set_standard_lookup.c +262 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_open_fd.c +141 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_open_file.c +105 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_open_filename.c +162 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_open_memory.c +126 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_private.h +122 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_bzip2.c +408 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_compress.c +492 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_gzip.c +477 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_none.c +257 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_program.c +347 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_xz.c +438 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format.c +72 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_ar.c +550 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_by_name.c +76 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio.c +344 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio_newc.c +295 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_mtree.c +1050 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_pax.c +1386 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_shar.c +626 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_ustar.c +587 -0
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_zip.c +667 -0
- data/ext/libarchive-2.8.4/libarchive/config_freebsd.h +154 -0
- data/ext/libarchive-2.8.4/libarchive/filter_fork.c +161 -0
- data/ext/libarchive-2.8.4/libarchive/filter_fork.h +41 -0
- data/ext/libarchive-2.8.4/libarchive/filter_fork_windows.c +113 -0
- data/ext/libarchive-static-makefile +80 -0
- data/ext/libarchive-static-wrapper-makefile +22 -0
- data/ext/zlib-1.2.5/Makefile.in +257 -0
- data/ext/zlib-1.2.5/adler32.c +169 -0
- data/ext/zlib-1.2.5/compress.c +80 -0
- data/ext/zlib-1.2.5/configure +596 -0
- data/ext/zlib-1.2.5/crc32.c +442 -0
- data/ext/zlib-1.2.5/crc32.h +441 -0
- data/ext/zlib-1.2.5/deflate.c +1834 -0
- data/ext/zlib-1.2.5/deflate.h +342 -0
- data/ext/zlib-1.2.5/example.c +565 -0
- data/ext/zlib-1.2.5/gzclose.c +25 -0
- data/ext/zlib-1.2.5/gzguts.h +132 -0
- data/ext/zlib-1.2.5/gzlib.c +537 -0
- data/ext/zlib-1.2.5/gzread.c +653 -0
- data/ext/zlib-1.2.5/gzwrite.c +531 -0
- data/ext/zlib-1.2.5/infback.c +632 -0
- data/ext/zlib-1.2.5/inffast.c +340 -0
- data/ext/zlib-1.2.5/inffast.h +11 -0
- data/ext/zlib-1.2.5/inffixed.h +94 -0
- data/ext/zlib-1.2.5/inflate.c +1480 -0
- data/ext/zlib-1.2.5/inflate.h +122 -0
- data/ext/zlib-1.2.5/inftrees.c +330 -0
- data/ext/zlib-1.2.5/inftrees.h +62 -0
- data/ext/zlib-1.2.5/minigzip.c +440 -0
- data/ext/zlib-1.2.5/trees.c +1244 -0
- data/ext/zlib-1.2.5/trees.h +128 -0
- data/ext/zlib-1.2.5/uncompr.c +59 -0
- data/ext/zlib-1.2.5/zconf.h +428 -0
- data/ext/zlib-1.2.5/zlib.h +1613 -0
- data/ext/zlib-1.2.5/zutil.c +318 -0
- data/ext/zlib-1.2.5/zutil.h +274 -0
- metadata +211 -0
|
@@ -0,0 +1,777 @@
|
|
|
1
|
+
/*-
|
|
2
|
+
* Copyright (c) 2003-2007 Tim Kientzle
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
|
6
|
+
* modification, are permitted provided that the following conditions
|
|
7
|
+
* are met:
|
|
8
|
+
* 1. Redistributions of source code must retain the above copyright
|
|
9
|
+
* notice, this list of conditions and the following disclaimer.
|
|
10
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
|
11
|
+
* notice, this list of conditions and the following disclaimer in the
|
|
12
|
+
* documentation and/or other materials provided with the distribution.
|
|
13
|
+
*
|
|
14
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
|
15
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
16
|
+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
17
|
+
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
18
|
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
19
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
20
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
21
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
22
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
23
|
+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
#include "archive_platform.h"
|
|
27
|
+
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_cpio.c 201163 2009-12-29 05:50:34Z kientzle $");
|
|
28
|
+
|
|
29
|
+
#ifdef HAVE_ERRNO_H
|
|
30
|
+
#include <errno.h>
|
|
31
|
+
#endif
|
|
32
|
+
/* #include <stdint.h> */ /* See archive_platform.h */
|
|
33
|
+
#ifdef HAVE_STDLIB_H
|
|
34
|
+
#include <stdlib.h>
|
|
35
|
+
#endif
|
|
36
|
+
#ifdef HAVE_STRING_H
|
|
37
|
+
#include <string.h>
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
#include "archive.h"
|
|
41
|
+
#include "archive_entry.h"
|
|
42
|
+
#include "archive_private.h"
|
|
43
|
+
#include "archive_read_private.h"
|
|
44
|
+
|
|
45
|
+
struct cpio_bin_header {
|
|
46
|
+
unsigned char c_magic[2];
|
|
47
|
+
unsigned char c_dev[2];
|
|
48
|
+
unsigned char c_ino[2];
|
|
49
|
+
unsigned char c_mode[2];
|
|
50
|
+
unsigned char c_uid[2];
|
|
51
|
+
unsigned char c_gid[2];
|
|
52
|
+
unsigned char c_nlink[2];
|
|
53
|
+
unsigned char c_rdev[2];
|
|
54
|
+
unsigned char c_mtime[4];
|
|
55
|
+
unsigned char c_namesize[2];
|
|
56
|
+
unsigned char c_filesize[4];
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
struct cpio_odc_header {
|
|
60
|
+
char c_magic[6];
|
|
61
|
+
char c_dev[6];
|
|
62
|
+
char c_ino[6];
|
|
63
|
+
char c_mode[6];
|
|
64
|
+
char c_uid[6];
|
|
65
|
+
char c_gid[6];
|
|
66
|
+
char c_nlink[6];
|
|
67
|
+
char c_rdev[6];
|
|
68
|
+
char c_mtime[11];
|
|
69
|
+
char c_namesize[6];
|
|
70
|
+
char c_filesize[11];
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
struct cpio_newc_header {
|
|
74
|
+
char c_magic[6];
|
|
75
|
+
char c_ino[8];
|
|
76
|
+
char c_mode[8];
|
|
77
|
+
char c_uid[8];
|
|
78
|
+
char c_gid[8];
|
|
79
|
+
char c_nlink[8];
|
|
80
|
+
char c_mtime[8];
|
|
81
|
+
char c_filesize[8];
|
|
82
|
+
char c_devmajor[8];
|
|
83
|
+
char c_devminor[8];
|
|
84
|
+
char c_rdevmajor[8];
|
|
85
|
+
char c_rdevminor[8];
|
|
86
|
+
char c_namesize[8];
|
|
87
|
+
char c_crc[8];
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
struct links_entry {
|
|
91
|
+
struct links_entry *next;
|
|
92
|
+
struct links_entry *previous;
|
|
93
|
+
int links;
|
|
94
|
+
dev_t dev;
|
|
95
|
+
int64_t ino;
|
|
96
|
+
char *name;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
#define CPIO_MAGIC 0x13141516
|
|
100
|
+
struct cpio {
|
|
101
|
+
int magic;
|
|
102
|
+
int (*read_header)(struct archive_read *, struct cpio *,
|
|
103
|
+
struct archive_entry *, size_t *, size_t *);
|
|
104
|
+
struct links_entry *links_head;
|
|
105
|
+
struct archive_string entry_name;
|
|
106
|
+
struct archive_string entry_linkname;
|
|
107
|
+
off_t entry_bytes_remaining;
|
|
108
|
+
off_t entry_offset;
|
|
109
|
+
off_t entry_padding;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
static int64_t atol16(const char *, unsigned);
|
|
113
|
+
static int64_t atol8(const char *, unsigned);
|
|
114
|
+
static int archive_read_format_cpio_bid(struct archive_read *);
|
|
115
|
+
static int archive_read_format_cpio_cleanup(struct archive_read *);
|
|
116
|
+
static int archive_read_format_cpio_read_data(struct archive_read *,
|
|
117
|
+
const void **, size_t *, off_t *);
|
|
118
|
+
static int archive_read_format_cpio_read_header(struct archive_read *,
|
|
119
|
+
struct archive_entry *);
|
|
120
|
+
static int be4(const unsigned char *);
|
|
121
|
+
static int find_odc_header(struct archive_read *);
|
|
122
|
+
static int find_newc_header(struct archive_read *);
|
|
123
|
+
static int header_bin_be(struct archive_read *, struct cpio *,
|
|
124
|
+
struct archive_entry *, size_t *, size_t *);
|
|
125
|
+
static int header_bin_le(struct archive_read *, struct cpio *,
|
|
126
|
+
struct archive_entry *, size_t *, size_t *);
|
|
127
|
+
static int header_newc(struct archive_read *, struct cpio *,
|
|
128
|
+
struct archive_entry *, size_t *, size_t *);
|
|
129
|
+
static int header_odc(struct archive_read *, struct cpio *,
|
|
130
|
+
struct archive_entry *, size_t *, size_t *);
|
|
131
|
+
static int is_octal(const char *, size_t);
|
|
132
|
+
static int is_hex(const char *, size_t);
|
|
133
|
+
static int le4(const unsigned char *);
|
|
134
|
+
static void record_hardlink(struct cpio *cpio, struct archive_entry *entry);
|
|
135
|
+
|
|
136
|
+
int
|
|
137
|
+
archive_read_support_format_cpio(struct archive *_a)
|
|
138
|
+
{
|
|
139
|
+
struct archive_read *a = (struct archive_read *)_a;
|
|
140
|
+
struct cpio *cpio;
|
|
141
|
+
int r;
|
|
142
|
+
|
|
143
|
+
cpio = (struct cpio *)malloc(sizeof(*cpio));
|
|
144
|
+
if (cpio == NULL) {
|
|
145
|
+
archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
|
|
146
|
+
return (ARCHIVE_FATAL);
|
|
147
|
+
}
|
|
148
|
+
memset(cpio, 0, sizeof(*cpio));
|
|
149
|
+
cpio->magic = CPIO_MAGIC;
|
|
150
|
+
|
|
151
|
+
r = __archive_read_register_format(a,
|
|
152
|
+
cpio,
|
|
153
|
+
"cpio",
|
|
154
|
+
archive_read_format_cpio_bid,
|
|
155
|
+
NULL,
|
|
156
|
+
archive_read_format_cpio_read_header,
|
|
157
|
+
archive_read_format_cpio_read_data,
|
|
158
|
+
NULL,
|
|
159
|
+
archive_read_format_cpio_cleanup);
|
|
160
|
+
|
|
161
|
+
if (r != ARCHIVE_OK)
|
|
162
|
+
free(cpio);
|
|
163
|
+
return (ARCHIVE_OK);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
static int
|
|
168
|
+
archive_read_format_cpio_bid(struct archive_read *a)
|
|
169
|
+
{
|
|
170
|
+
const void *h;
|
|
171
|
+
const unsigned char *p;
|
|
172
|
+
struct cpio *cpio;
|
|
173
|
+
int bid;
|
|
174
|
+
|
|
175
|
+
cpio = (struct cpio *)(a->format->data);
|
|
176
|
+
|
|
177
|
+
if ((h = __archive_read_ahead(a, 6, NULL)) == NULL)
|
|
178
|
+
return (-1);
|
|
179
|
+
|
|
180
|
+
p = (const unsigned char *)h;
|
|
181
|
+
bid = 0;
|
|
182
|
+
if (memcmp(p, "070707", 6) == 0) {
|
|
183
|
+
/* ASCII cpio archive (odc, POSIX.1) */
|
|
184
|
+
cpio->read_header = header_odc;
|
|
185
|
+
bid += 48;
|
|
186
|
+
/*
|
|
187
|
+
* XXX TODO: More verification; Could check that only octal
|
|
188
|
+
* digits appear in appropriate header locations. XXX
|
|
189
|
+
*/
|
|
190
|
+
} else if (memcmp(p, "070701", 6) == 0) {
|
|
191
|
+
/* ASCII cpio archive (SVR4 without CRC) */
|
|
192
|
+
cpio->read_header = header_newc;
|
|
193
|
+
bid += 48;
|
|
194
|
+
/*
|
|
195
|
+
* XXX TODO: More verification; Could check that only hex
|
|
196
|
+
* digits appear in appropriate header locations. XXX
|
|
197
|
+
*/
|
|
198
|
+
} else if (memcmp(p, "070702", 6) == 0) {
|
|
199
|
+
/* ASCII cpio archive (SVR4 with CRC) */
|
|
200
|
+
/* XXX TODO: Flag that we should check the CRC. XXX */
|
|
201
|
+
cpio->read_header = header_newc;
|
|
202
|
+
bid += 48;
|
|
203
|
+
/*
|
|
204
|
+
* XXX TODO: More verification; Could check that only hex
|
|
205
|
+
* digits appear in appropriate header locations. XXX
|
|
206
|
+
*/
|
|
207
|
+
} else if (p[0] * 256 + p[1] == 070707) {
|
|
208
|
+
/* big-endian binary cpio archives */
|
|
209
|
+
cpio->read_header = header_bin_be;
|
|
210
|
+
bid += 16;
|
|
211
|
+
/* Is more verification possible here? */
|
|
212
|
+
} else if (p[0] + p[1] * 256 == 070707) {
|
|
213
|
+
/* little-endian binary cpio archives */
|
|
214
|
+
cpio->read_header = header_bin_le;
|
|
215
|
+
bid += 16;
|
|
216
|
+
/* Is more verification possible here? */
|
|
217
|
+
} else
|
|
218
|
+
return (ARCHIVE_WARN);
|
|
219
|
+
|
|
220
|
+
return (bid);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
static int
|
|
224
|
+
archive_read_format_cpio_read_header(struct archive_read *a,
|
|
225
|
+
struct archive_entry *entry)
|
|
226
|
+
{
|
|
227
|
+
struct cpio *cpio;
|
|
228
|
+
const void *h;
|
|
229
|
+
size_t namelength;
|
|
230
|
+
size_t name_pad;
|
|
231
|
+
int r;
|
|
232
|
+
|
|
233
|
+
cpio = (struct cpio *)(a->format->data);
|
|
234
|
+
r = (cpio->read_header(a, cpio, entry, &namelength, &name_pad));
|
|
235
|
+
|
|
236
|
+
if (r < ARCHIVE_WARN)
|
|
237
|
+
return (r);
|
|
238
|
+
|
|
239
|
+
/* Read name from buffer. */
|
|
240
|
+
h = __archive_read_ahead(a, namelength + name_pad, NULL);
|
|
241
|
+
if (h == NULL)
|
|
242
|
+
return (ARCHIVE_FATAL);
|
|
243
|
+
__archive_read_consume(a, namelength + name_pad);
|
|
244
|
+
archive_strncpy(&cpio->entry_name, (const char *)h, namelength);
|
|
245
|
+
archive_entry_set_pathname(entry, cpio->entry_name.s);
|
|
246
|
+
cpio->entry_offset = 0;
|
|
247
|
+
|
|
248
|
+
/* If this is a symlink, read the link contents. */
|
|
249
|
+
if (archive_entry_filetype(entry) == AE_IFLNK) {
|
|
250
|
+
h = __archive_read_ahead(a, cpio->entry_bytes_remaining, NULL);
|
|
251
|
+
if (h == NULL)
|
|
252
|
+
return (ARCHIVE_FATAL);
|
|
253
|
+
__archive_read_consume(a, cpio->entry_bytes_remaining);
|
|
254
|
+
archive_strncpy(&cpio->entry_linkname, (const char *)h,
|
|
255
|
+
cpio->entry_bytes_remaining);
|
|
256
|
+
archive_entry_set_symlink(entry, cpio->entry_linkname.s);
|
|
257
|
+
cpio->entry_bytes_remaining = 0;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/* XXX TODO: If the full mode is 0160200, then this is a Solaris
|
|
261
|
+
* ACL description for the following entry. Read this body
|
|
262
|
+
* and parse it as a Solaris-style ACL, then read the next
|
|
263
|
+
* header. XXX */
|
|
264
|
+
|
|
265
|
+
/* Compare name to "TRAILER!!!" to test for end-of-archive. */
|
|
266
|
+
if (namelength == 11 && strcmp((const char *)h, "TRAILER!!!") == 0) {
|
|
267
|
+
/* TODO: Store file location of start of block. */
|
|
268
|
+
archive_set_error(&a->archive, 0, NULL);
|
|
269
|
+
return (ARCHIVE_EOF);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/* Detect and record hardlinks to previously-extracted entries. */
|
|
273
|
+
record_hardlink(cpio, entry);
|
|
274
|
+
|
|
275
|
+
return (r);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
static int
|
|
279
|
+
archive_read_format_cpio_read_data(struct archive_read *a,
|
|
280
|
+
const void **buff, size_t *size, off_t *offset)
|
|
281
|
+
{
|
|
282
|
+
ssize_t bytes_read;
|
|
283
|
+
struct cpio *cpio;
|
|
284
|
+
|
|
285
|
+
cpio = (struct cpio *)(a->format->data);
|
|
286
|
+
if (cpio->entry_bytes_remaining > 0) {
|
|
287
|
+
*buff = __archive_read_ahead(a, 1, &bytes_read);
|
|
288
|
+
if (bytes_read <= 0)
|
|
289
|
+
return (ARCHIVE_FATAL);
|
|
290
|
+
if (bytes_read > cpio->entry_bytes_remaining)
|
|
291
|
+
bytes_read = cpio->entry_bytes_remaining;
|
|
292
|
+
*size = bytes_read;
|
|
293
|
+
*offset = cpio->entry_offset;
|
|
294
|
+
cpio->entry_offset += bytes_read;
|
|
295
|
+
cpio->entry_bytes_remaining -= bytes_read;
|
|
296
|
+
__archive_read_consume(a, bytes_read);
|
|
297
|
+
return (ARCHIVE_OK);
|
|
298
|
+
} else {
|
|
299
|
+
while (cpio->entry_padding > 0) {
|
|
300
|
+
*buff = __archive_read_ahead(a, 1, &bytes_read);
|
|
301
|
+
if (bytes_read <= 0)
|
|
302
|
+
return (ARCHIVE_FATAL);
|
|
303
|
+
if (bytes_read > cpio->entry_padding)
|
|
304
|
+
bytes_read = cpio->entry_padding;
|
|
305
|
+
__archive_read_consume(a, bytes_read);
|
|
306
|
+
cpio->entry_padding -= bytes_read;
|
|
307
|
+
}
|
|
308
|
+
*buff = NULL;
|
|
309
|
+
*size = 0;
|
|
310
|
+
*offset = cpio->entry_offset;
|
|
311
|
+
return (ARCHIVE_EOF);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/*
|
|
316
|
+
* Skip forward to the next cpio newc header by searching for the
|
|
317
|
+
* 07070[12] string. This should be generalized and merged with
|
|
318
|
+
* find_odc_header below.
|
|
319
|
+
*/
|
|
320
|
+
static int
|
|
321
|
+
is_hex(const char *p, size_t len)
|
|
322
|
+
{
|
|
323
|
+
while (len-- > 0) {
|
|
324
|
+
if ((*p >= '0' && *p <= '9')
|
|
325
|
+
|| (*p >= 'a' && *p <= 'f')
|
|
326
|
+
|| (*p >= 'A' && *p <= 'F'))
|
|
327
|
+
++p;
|
|
328
|
+
else
|
|
329
|
+
return (0);
|
|
330
|
+
}
|
|
331
|
+
return (1);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
static int
|
|
335
|
+
find_newc_header(struct archive_read *a)
|
|
336
|
+
{
|
|
337
|
+
const void *h;
|
|
338
|
+
const char *p, *q;
|
|
339
|
+
size_t skip, skipped = 0;
|
|
340
|
+
ssize_t bytes;
|
|
341
|
+
|
|
342
|
+
for (;;) {
|
|
343
|
+
h = __archive_read_ahead(a, sizeof(struct cpio_newc_header), &bytes);
|
|
344
|
+
if (h == NULL)
|
|
345
|
+
return (ARCHIVE_FATAL);
|
|
346
|
+
p = h;
|
|
347
|
+
q = p + bytes;
|
|
348
|
+
|
|
349
|
+
/* Try the typical case first, then go into the slow search.*/
|
|
350
|
+
if (memcmp("07070", p, 5) == 0
|
|
351
|
+
&& (p[5] == '1' || p[5] == '2')
|
|
352
|
+
&& is_hex(p, sizeof(struct cpio_newc_header)))
|
|
353
|
+
return (ARCHIVE_OK);
|
|
354
|
+
|
|
355
|
+
/*
|
|
356
|
+
* Scan ahead until we find something that looks
|
|
357
|
+
* like an odc header.
|
|
358
|
+
*/
|
|
359
|
+
while (p + sizeof(struct cpio_newc_header) <= q) {
|
|
360
|
+
switch (p[5]) {
|
|
361
|
+
case '1':
|
|
362
|
+
case '2':
|
|
363
|
+
if (memcmp("07070", p, 5) == 0
|
|
364
|
+
&& is_hex(p, sizeof(struct cpio_newc_header))) {
|
|
365
|
+
skip = p - (const char *)h;
|
|
366
|
+
__archive_read_consume(a, skip);
|
|
367
|
+
skipped += skip;
|
|
368
|
+
if (skipped > 0) {
|
|
369
|
+
archive_set_error(&a->archive,
|
|
370
|
+
0,
|
|
371
|
+
"Skipped %d bytes before "
|
|
372
|
+
"finding valid header",
|
|
373
|
+
(int)skipped);
|
|
374
|
+
return (ARCHIVE_WARN);
|
|
375
|
+
}
|
|
376
|
+
return (ARCHIVE_OK);
|
|
377
|
+
}
|
|
378
|
+
p += 2;
|
|
379
|
+
break;
|
|
380
|
+
case '0':
|
|
381
|
+
p++;
|
|
382
|
+
break;
|
|
383
|
+
default:
|
|
384
|
+
p += 6;
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
skip = p - (const char *)h;
|
|
389
|
+
__archive_read_consume(a, skip);
|
|
390
|
+
skipped += skip;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
static int
|
|
395
|
+
header_newc(struct archive_read *a, struct cpio *cpio,
|
|
396
|
+
struct archive_entry *entry, size_t *namelength, size_t *name_pad)
|
|
397
|
+
{
|
|
398
|
+
const void *h;
|
|
399
|
+
const struct cpio_newc_header *header;
|
|
400
|
+
int r;
|
|
401
|
+
|
|
402
|
+
r = find_newc_header(a);
|
|
403
|
+
if (r < ARCHIVE_WARN)
|
|
404
|
+
return (r);
|
|
405
|
+
|
|
406
|
+
/* Read fixed-size portion of header. */
|
|
407
|
+
h = __archive_read_ahead(a, sizeof(struct cpio_newc_header), NULL);
|
|
408
|
+
if (h == NULL)
|
|
409
|
+
return (ARCHIVE_FATAL);
|
|
410
|
+
__archive_read_consume(a, sizeof(struct cpio_newc_header));
|
|
411
|
+
|
|
412
|
+
/* Parse out hex fields. */
|
|
413
|
+
header = (const struct cpio_newc_header *)h;
|
|
414
|
+
|
|
415
|
+
if (memcmp(header->c_magic, "070701", 6) == 0) {
|
|
416
|
+
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_NOCRC;
|
|
417
|
+
a->archive.archive_format_name = "ASCII cpio (SVR4 with no CRC)";
|
|
418
|
+
} else if (memcmp(header->c_magic, "070702", 6) == 0) {
|
|
419
|
+
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_CRC;
|
|
420
|
+
a->archive.archive_format_name = "ASCII cpio (SVR4 with CRC)";
|
|
421
|
+
} else {
|
|
422
|
+
/* TODO: Abort here? */
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
archive_entry_set_devmajor(entry, atol16(header->c_devmajor, sizeof(header->c_devmajor)));
|
|
426
|
+
archive_entry_set_devminor(entry, atol16(header->c_devminor, sizeof(header->c_devminor)));
|
|
427
|
+
archive_entry_set_ino(entry, atol16(header->c_ino, sizeof(header->c_ino)));
|
|
428
|
+
archive_entry_set_mode(entry, atol16(header->c_mode, sizeof(header->c_mode)));
|
|
429
|
+
archive_entry_set_uid(entry, atol16(header->c_uid, sizeof(header->c_uid)));
|
|
430
|
+
archive_entry_set_gid(entry, atol16(header->c_gid, sizeof(header->c_gid)));
|
|
431
|
+
archive_entry_set_nlink(entry, atol16(header->c_nlink, sizeof(header->c_nlink)));
|
|
432
|
+
archive_entry_set_rdevmajor(entry, atol16(header->c_rdevmajor, sizeof(header->c_rdevmajor)));
|
|
433
|
+
archive_entry_set_rdevminor(entry, atol16(header->c_rdevminor, sizeof(header->c_rdevminor)));
|
|
434
|
+
archive_entry_set_mtime(entry, atol16(header->c_mtime, sizeof(header->c_mtime)), 0);
|
|
435
|
+
*namelength = atol16(header->c_namesize, sizeof(header->c_namesize));
|
|
436
|
+
/* Pad name to 2 more than a multiple of 4. */
|
|
437
|
+
*name_pad = (2 - *namelength) & 3;
|
|
438
|
+
|
|
439
|
+
/*
|
|
440
|
+
* Note: entry_bytes_remaining is at least 64 bits and
|
|
441
|
+
* therefore guaranteed to be big enough for a 33-bit file
|
|
442
|
+
* size.
|
|
443
|
+
*/
|
|
444
|
+
cpio->entry_bytes_remaining =
|
|
445
|
+
atol16(header->c_filesize, sizeof(header->c_filesize));
|
|
446
|
+
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
|
|
447
|
+
/* Pad file contents to a multiple of 4. */
|
|
448
|
+
cpio->entry_padding = 3 & -cpio->entry_bytes_remaining;
|
|
449
|
+
return (r);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/*
|
|
453
|
+
* Skip forward to the next cpio odc header by searching for the
|
|
454
|
+
* 070707 string. This is a hand-optimized search that could
|
|
455
|
+
* probably be easily generalized to handle all character-based
|
|
456
|
+
* cpio variants.
|
|
457
|
+
*/
|
|
458
|
+
static int
|
|
459
|
+
is_octal(const char *p, size_t len)
|
|
460
|
+
{
|
|
461
|
+
while (len-- > 0) {
|
|
462
|
+
if (*p < '0' || *p > '7')
|
|
463
|
+
return (0);
|
|
464
|
+
++p;
|
|
465
|
+
}
|
|
466
|
+
return (1);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
static int
|
|
470
|
+
find_odc_header(struct archive_read *a)
|
|
471
|
+
{
|
|
472
|
+
const void *h;
|
|
473
|
+
const char *p, *q;
|
|
474
|
+
size_t skip, skipped = 0;
|
|
475
|
+
ssize_t bytes;
|
|
476
|
+
|
|
477
|
+
for (;;) {
|
|
478
|
+
h = __archive_read_ahead(a, sizeof(struct cpio_odc_header), &bytes);
|
|
479
|
+
if (h == NULL)
|
|
480
|
+
return (ARCHIVE_FATAL);
|
|
481
|
+
p = h;
|
|
482
|
+
q = p + bytes;
|
|
483
|
+
|
|
484
|
+
/* Try the typical case first, then go into the slow search.*/
|
|
485
|
+
if (memcmp("070707", p, 6) == 0
|
|
486
|
+
&& is_octal(p, sizeof(struct cpio_odc_header)))
|
|
487
|
+
return (ARCHIVE_OK);
|
|
488
|
+
|
|
489
|
+
/*
|
|
490
|
+
* Scan ahead until we find something that looks
|
|
491
|
+
* like an odc header.
|
|
492
|
+
*/
|
|
493
|
+
while (p + sizeof(struct cpio_odc_header) <= q) {
|
|
494
|
+
switch (p[5]) {
|
|
495
|
+
case '7':
|
|
496
|
+
if (memcmp("070707", p, 6) == 0
|
|
497
|
+
&& is_octal(p, sizeof(struct cpio_odc_header))) {
|
|
498
|
+
skip = p - (const char *)h;
|
|
499
|
+
__archive_read_consume(a, skip);
|
|
500
|
+
skipped += skip;
|
|
501
|
+
if (skipped > 0) {
|
|
502
|
+
archive_set_error(&a->archive,
|
|
503
|
+
0,
|
|
504
|
+
"Skipped %d bytes before "
|
|
505
|
+
"finding valid header",
|
|
506
|
+
(int)skipped);
|
|
507
|
+
return (ARCHIVE_WARN);
|
|
508
|
+
}
|
|
509
|
+
return (ARCHIVE_OK);
|
|
510
|
+
}
|
|
511
|
+
p += 2;
|
|
512
|
+
break;
|
|
513
|
+
case '0':
|
|
514
|
+
p++;
|
|
515
|
+
break;
|
|
516
|
+
default:
|
|
517
|
+
p += 6;
|
|
518
|
+
break;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
skip = p - (const char *)h;
|
|
522
|
+
__archive_read_consume(a, skip);
|
|
523
|
+
skipped += skip;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
static int
|
|
528
|
+
header_odc(struct archive_read *a, struct cpio *cpio,
|
|
529
|
+
struct archive_entry *entry, size_t *namelength, size_t *name_pad)
|
|
530
|
+
{
|
|
531
|
+
const void *h;
|
|
532
|
+
int r;
|
|
533
|
+
const struct cpio_odc_header *header;
|
|
534
|
+
|
|
535
|
+
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX;
|
|
536
|
+
a->archive.archive_format_name = "POSIX octet-oriented cpio";
|
|
537
|
+
|
|
538
|
+
/* Find the start of the next header. */
|
|
539
|
+
r = find_odc_header(a);
|
|
540
|
+
if (r < ARCHIVE_WARN)
|
|
541
|
+
return (r);
|
|
542
|
+
|
|
543
|
+
/* Read fixed-size portion of header. */
|
|
544
|
+
h = __archive_read_ahead(a, sizeof(struct cpio_odc_header), NULL);
|
|
545
|
+
if (h == NULL)
|
|
546
|
+
return (ARCHIVE_FATAL);
|
|
547
|
+
__archive_read_consume(a, sizeof(struct cpio_odc_header));
|
|
548
|
+
|
|
549
|
+
/* Parse out octal fields. */
|
|
550
|
+
header = (const struct cpio_odc_header *)h;
|
|
551
|
+
|
|
552
|
+
archive_entry_set_dev(entry, atol8(header->c_dev, sizeof(header->c_dev)));
|
|
553
|
+
archive_entry_set_ino(entry, atol8(header->c_ino, sizeof(header->c_ino)));
|
|
554
|
+
archive_entry_set_mode(entry, atol8(header->c_mode, sizeof(header->c_mode)));
|
|
555
|
+
archive_entry_set_uid(entry, atol8(header->c_uid, sizeof(header->c_uid)));
|
|
556
|
+
archive_entry_set_gid(entry, atol8(header->c_gid, sizeof(header->c_gid)));
|
|
557
|
+
archive_entry_set_nlink(entry, atol8(header->c_nlink, sizeof(header->c_nlink)));
|
|
558
|
+
archive_entry_set_rdev(entry, atol8(header->c_rdev, sizeof(header->c_rdev)));
|
|
559
|
+
archive_entry_set_mtime(entry, atol8(header->c_mtime, sizeof(header->c_mtime)), 0);
|
|
560
|
+
*namelength = atol8(header->c_namesize, sizeof(header->c_namesize));
|
|
561
|
+
*name_pad = 0; /* No padding of filename. */
|
|
562
|
+
|
|
563
|
+
/*
|
|
564
|
+
* Note: entry_bytes_remaining is at least 64 bits and
|
|
565
|
+
* therefore guaranteed to be big enough for a 33-bit file
|
|
566
|
+
* size.
|
|
567
|
+
*/
|
|
568
|
+
cpio->entry_bytes_remaining =
|
|
569
|
+
atol8(header->c_filesize, sizeof(header->c_filesize));
|
|
570
|
+
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
|
|
571
|
+
cpio->entry_padding = 0;
|
|
572
|
+
return (r);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
static int
|
|
576
|
+
header_bin_le(struct archive_read *a, struct cpio *cpio,
|
|
577
|
+
struct archive_entry *entry, size_t *namelength, size_t *name_pad)
|
|
578
|
+
{
|
|
579
|
+
const void *h;
|
|
580
|
+
const struct cpio_bin_header *header;
|
|
581
|
+
|
|
582
|
+
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_LE;
|
|
583
|
+
a->archive.archive_format_name = "cpio (little-endian binary)";
|
|
584
|
+
|
|
585
|
+
/* Read fixed-size portion of header. */
|
|
586
|
+
h = __archive_read_ahead(a, sizeof(struct cpio_bin_header), NULL);
|
|
587
|
+
if (h == NULL)
|
|
588
|
+
return (ARCHIVE_FATAL);
|
|
589
|
+
__archive_read_consume(a, sizeof(struct cpio_bin_header));
|
|
590
|
+
|
|
591
|
+
/* Parse out binary fields. */
|
|
592
|
+
header = (const struct cpio_bin_header *)h;
|
|
593
|
+
|
|
594
|
+
archive_entry_set_dev(entry, header->c_dev[0] + header->c_dev[1] * 256);
|
|
595
|
+
archive_entry_set_ino(entry, header->c_ino[0] + header->c_ino[1] * 256);
|
|
596
|
+
archive_entry_set_mode(entry, header->c_mode[0] + header->c_mode[1] * 256);
|
|
597
|
+
archive_entry_set_uid(entry, header->c_uid[0] + header->c_uid[1] * 256);
|
|
598
|
+
archive_entry_set_gid(entry, header->c_gid[0] + header->c_gid[1] * 256);
|
|
599
|
+
archive_entry_set_nlink(entry, header->c_nlink[0] + header->c_nlink[1] * 256);
|
|
600
|
+
archive_entry_set_rdev(entry, header->c_rdev[0] + header->c_rdev[1] * 256);
|
|
601
|
+
archive_entry_set_mtime(entry, le4(header->c_mtime), 0);
|
|
602
|
+
*namelength = header->c_namesize[0] + header->c_namesize[1] * 256;
|
|
603
|
+
*name_pad = *namelength & 1; /* Pad to even. */
|
|
604
|
+
|
|
605
|
+
cpio->entry_bytes_remaining = le4(header->c_filesize);
|
|
606
|
+
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
|
|
607
|
+
cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
|
|
608
|
+
return (ARCHIVE_OK);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
static int
|
|
612
|
+
header_bin_be(struct archive_read *a, struct cpio *cpio,
|
|
613
|
+
struct archive_entry *entry, size_t *namelength, size_t *name_pad)
|
|
614
|
+
{
|
|
615
|
+
const void *h;
|
|
616
|
+
const struct cpio_bin_header *header;
|
|
617
|
+
|
|
618
|
+
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_BE;
|
|
619
|
+
a->archive.archive_format_name = "cpio (big-endian binary)";
|
|
620
|
+
|
|
621
|
+
/* Read fixed-size portion of header. */
|
|
622
|
+
h = __archive_read_ahead(a, sizeof(struct cpio_bin_header), NULL);
|
|
623
|
+
if (h == NULL)
|
|
624
|
+
return (ARCHIVE_FATAL);
|
|
625
|
+
__archive_read_consume(a, sizeof(struct cpio_bin_header));
|
|
626
|
+
|
|
627
|
+
/* Parse out binary fields. */
|
|
628
|
+
header = (const struct cpio_bin_header *)h;
|
|
629
|
+
archive_entry_set_dev(entry, header->c_dev[0] * 256 + header->c_dev[1]);
|
|
630
|
+
archive_entry_set_ino(entry, header->c_ino[0] * 256 + header->c_ino[1]);
|
|
631
|
+
archive_entry_set_mode(entry, header->c_mode[0] * 256 + header->c_mode[1]);
|
|
632
|
+
archive_entry_set_uid(entry, header->c_uid[0] * 256 + header->c_uid[1]);
|
|
633
|
+
archive_entry_set_gid(entry, header->c_gid[0] * 256 + header->c_gid[1]);
|
|
634
|
+
archive_entry_set_nlink(entry, header->c_nlink[0] * 256 + header->c_nlink[1]);
|
|
635
|
+
archive_entry_set_rdev(entry, header->c_rdev[0] * 256 + header->c_rdev[1]);
|
|
636
|
+
archive_entry_set_mtime(entry, be4(header->c_mtime), 0);
|
|
637
|
+
*namelength = header->c_namesize[0] * 256 + header->c_namesize[1];
|
|
638
|
+
*name_pad = *namelength & 1; /* Pad to even. */
|
|
639
|
+
|
|
640
|
+
cpio->entry_bytes_remaining = be4(header->c_filesize);
|
|
641
|
+
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
|
|
642
|
+
cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
|
|
643
|
+
return (ARCHIVE_OK);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
static int
|
|
647
|
+
archive_read_format_cpio_cleanup(struct archive_read *a)
|
|
648
|
+
{
|
|
649
|
+
struct cpio *cpio;
|
|
650
|
+
|
|
651
|
+
cpio = (struct cpio *)(a->format->data);
|
|
652
|
+
/* Free inode->name map */
|
|
653
|
+
while (cpio->links_head != NULL) {
|
|
654
|
+
struct links_entry *lp = cpio->links_head->next;
|
|
655
|
+
|
|
656
|
+
if (cpio->links_head->name)
|
|
657
|
+
free(cpio->links_head->name);
|
|
658
|
+
free(cpio->links_head);
|
|
659
|
+
cpio->links_head = lp;
|
|
660
|
+
}
|
|
661
|
+
archive_string_free(&cpio->entry_name);
|
|
662
|
+
free(cpio);
|
|
663
|
+
(a->format->data) = NULL;
|
|
664
|
+
return (ARCHIVE_OK);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
static int
|
|
668
|
+
le4(const unsigned char *p)
|
|
669
|
+
{
|
|
670
|
+
return ((p[0]<<16) + (p[1]<<24) + (p[2]<<0) + (p[3]<<8));
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
static int
|
|
675
|
+
be4(const unsigned char *p)
|
|
676
|
+
{
|
|
677
|
+
return ((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + (p[3]));
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/*
|
|
681
|
+
* Note that this implementation does not (and should not!) obey
|
|
682
|
+
* locale settings; you cannot simply substitute strtol here, since
|
|
683
|
+
* it does obey locale.
|
|
684
|
+
*/
|
|
685
|
+
static int64_t
|
|
686
|
+
atol8(const char *p, unsigned char_cnt)
|
|
687
|
+
{
|
|
688
|
+
int64_t l;
|
|
689
|
+
int digit;
|
|
690
|
+
|
|
691
|
+
l = 0;
|
|
692
|
+
while (char_cnt-- > 0) {
|
|
693
|
+
if (*p >= '0' && *p <= '7')
|
|
694
|
+
digit = *p - '0';
|
|
695
|
+
else
|
|
696
|
+
return (l);
|
|
697
|
+
p++;
|
|
698
|
+
l <<= 3;
|
|
699
|
+
l |= digit;
|
|
700
|
+
}
|
|
701
|
+
return (l);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
static int64_t
|
|
705
|
+
atol16(const char *p, unsigned char_cnt)
|
|
706
|
+
{
|
|
707
|
+
int64_t l;
|
|
708
|
+
int digit;
|
|
709
|
+
|
|
710
|
+
l = 0;
|
|
711
|
+
while (char_cnt-- > 0) {
|
|
712
|
+
if (*p >= 'a' && *p <= 'f')
|
|
713
|
+
digit = *p - 'a' + 10;
|
|
714
|
+
else if (*p >= 'A' && *p <= 'F')
|
|
715
|
+
digit = *p - 'A' + 10;
|
|
716
|
+
else if (*p >= '0' && *p <= '9')
|
|
717
|
+
digit = *p - '0';
|
|
718
|
+
else
|
|
719
|
+
return (l);
|
|
720
|
+
p++;
|
|
721
|
+
l <<= 4;
|
|
722
|
+
l |= digit;
|
|
723
|
+
}
|
|
724
|
+
return (l);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
static void
|
|
728
|
+
record_hardlink(struct cpio *cpio, struct archive_entry *entry)
|
|
729
|
+
{
|
|
730
|
+
struct links_entry *le;
|
|
731
|
+
dev_t dev;
|
|
732
|
+
int64_t ino;
|
|
733
|
+
|
|
734
|
+
if (archive_entry_nlink(entry) <= 1)
|
|
735
|
+
return;
|
|
736
|
+
|
|
737
|
+
dev = archive_entry_dev(entry);
|
|
738
|
+
ino = archive_entry_ino64(entry);
|
|
739
|
+
|
|
740
|
+
/*
|
|
741
|
+
* First look in the list of multiply-linked files. If we've
|
|
742
|
+
* already dumped it, convert this entry to a hard link entry.
|
|
743
|
+
*/
|
|
744
|
+
for (le = cpio->links_head; le; le = le->next) {
|
|
745
|
+
if (le->dev == dev && le->ino == ino) {
|
|
746
|
+
archive_entry_copy_hardlink(entry, le->name);
|
|
747
|
+
|
|
748
|
+
if (--le->links <= 0) {
|
|
749
|
+
if (le->previous != NULL)
|
|
750
|
+
le->previous->next = le->next;
|
|
751
|
+
if (le->next != NULL)
|
|
752
|
+
le->next->previous = le->previous;
|
|
753
|
+
if (cpio->links_head == le)
|
|
754
|
+
cpio->links_head = le->next;
|
|
755
|
+
free(le->name);
|
|
756
|
+
free(le);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
le = (struct links_entry *)malloc(sizeof(struct links_entry));
|
|
764
|
+
if (le == NULL)
|
|
765
|
+
__archive_errx(1, "Out of memory adding file to list");
|
|
766
|
+
if (cpio->links_head != NULL)
|
|
767
|
+
cpio->links_head->previous = le;
|
|
768
|
+
le->next = cpio->links_head;
|
|
769
|
+
le->previous = NULL;
|
|
770
|
+
cpio->links_head = le;
|
|
771
|
+
le->dev = dev;
|
|
772
|
+
le->ino = ino;
|
|
773
|
+
le->links = archive_entry_nlink(entry) - 1;
|
|
774
|
+
le->name = strdup(archive_entry_pathname(entry));
|
|
775
|
+
if (le->name == NULL)
|
|
776
|
+
__archive_errx(1, "Out of memory adding file to list");
|
|
777
|
+
}
|