41
42
#include "dpkg-split.h"
43
static unsigned long unsignedlong(const char *value, const char *fn, const char *what) {
45
parse_intmax(const char *value, const char *fn, const char *what)
47
r= strtoul(value,&endp,10);
50
r = strtoimax(value, &endp, 10);
48
51
if (value == endp || *endp)
49
52
ohshit(_("file `%.250s' is corrupt - bad digit (code %d) in %s"),fn,*endp,what);
53
static unsigned long parseheaderlength(const char *inh, size_t len,
54
const char *fn, const char *what) {
57
if (memchr(inh,0,len))
58
ohshit(_("file `%.250s' is corrupt - %.250s length contains nulls"),fn,what);
59
assert(sizeof(lintbuf) > len);
60
memcpy(lintbuf,inh,len);
62
*strchr(lintbuf, ' ') = '\0';
63
return unsignedlong(lintbuf,fn,what);
66
56
static char *nextline(char **ripp, const char *fn, const char *what) {
67
57
char *newline, *rip;
71
* Read a deb-split part archive.
73
* @return Part info (nfmalloc'd) if was an archive part and we read it,
80
76
struct partinfo *read_info(FILE *partfile, const char *fn, struct partinfo *ir) {
81
/* returns info (nfmalloc'd) if was an archive part and we read it, 0 if it wasn't */
82
77
static char *readinfobuf= NULL;
83
78
static size_t readinfobuflen= 0;
86
unsigned int templong;
87
char magicbuf[strlen(DPKG_AR_MAGIC)], *rip, *partnums, *slash;
82
char magicbuf[sizeof(DPKG_AR_MAGIC) - 1], *rip, *partnums, *slash;
92
87
if (fread(magicbuf, 1, sizeof(magicbuf), partfile) != sizeof(magicbuf)) {
93
if (ferror(partfile)) rerr(fn); else return NULL;
89
ohshite(_("error reading %.250s"), fn);
95
93
if (memcmp(magicbuf, DPKG_AR_MAGIC, sizeof(magicbuf)))
98
96
if (fread(&arh,1,sizeof(arh),partfile) != sizeof(arh)) rerreof(partfile,fn);
100
98
dpkg_ar_normalize_name(&arh);
104
102
if (memcmp(arh.ar_fmag,ARFMAG,sizeof(arh.ar_fmag)))
105
103
ohshit(_("file `%.250s' is corrupt - bad magic at end of first header"),fn);
106
thisilen = parseheaderlength(arh.ar_size, sizeof(arh.ar_size), fn,
104
thisilen = dpkg_ar_member_get_size(fn, &arh);
108
105
if (thisilen >= readinfobuflen) {
109
106
readinfobuflen= thisilen+1;
110
107
readinfobuf= m_realloc(readinfobuf,readinfobuflen);
134
131
strspn(ir->md5sum, "0123456789abcdef") != MD5HASHLEN)
135
132
ohshit(_("file `%.250s' is corrupt - bad MD5 checksum `%.250s'"),fn,ir->md5sum);
137
ir->orglength = unsignedlong(nextline(&rip, fn, _("total length")), fn,
139
ir->maxpartlen = unsignedlong(nextline(&rip, fn, _("part offset")), fn,
142
partnums = nextline(&rip, fn, _("part numbers"));
134
ir->orglength = parse_intmax(nextline(&rip, fn, _("archive total size")),
135
fn, _("archive total size"));
136
ir->maxpartlen = parse_intmax(nextline(&rip, fn, _("archive part offset")),
137
fn, _("archive part offset"));
139
partnums = nextline(&rip, fn, _("archive part numbers"));
143
140
slash= strchr(partnums,'/');
144
if (!slash) ohshit(_("file `%.250s' is corrupt - no slash between part numbers"),fn);
142
ohshit(_("file '%.250s' is corrupt - no slash between archive part numbers"), fn);
147
templong = unsignedlong(slash, fn, _("number of parts"));
145
templong = parse_intmax(slash, fn, _("number of archive parts"));
148
146
if (templong <= 0 || templong > INT_MAX)
149
ohshit(_("file '%.250s' is corrupt - bad number of parts"), fn);
147
ohshit(_("file '%.250s' is corrupt - bad number of archive parts"), fn);
150
148
ir->maxpartn= templong;
151
templong = unsignedlong(partnums, fn, _("parts number"));
149
templong = parse_intmax(partnums, fn, _("archive parts number"));
152
150
if (templong <= 0 || templong > ir->maxpartn)
153
ohshit(_("file `%.250s' is corrupt - bad part number"),fn);
151
ohshit(_("file '%.250s' is corrupt - bad archive part number"),fn);
154
152
ir->thispartn= templong;
156
154
if (fread(&arh,1,sizeof(arh),partfile) != sizeof(arh)) rerreof(partfile,fn);
162
160
if (strncmp(arh.ar_name,"data",4))
163
161
ohshit(_("file `%.250s' is corrupt - second member is not data member"),fn);
165
ir->thispartlen = parseheaderlength(arh.ar_size, sizeof(arh.ar_size), fn,
163
ir->thispartlen = dpkg_ar_member_get_size(fn, &arh);
167
164
ir->thispartoffset= (ir->thispartn-1)*ir->maxpartlen;
169
166
if (ir->maxpartn != (ir->orglength+ir->maxpartlen-1)/ir->maxpartlen)
180
177
if (fstat(fileno(partfile),&stab)) ohshite(_("unable to fstat part file `%.250s'"),fn);
181
178
if (S_ISREG(stab.st_mode)) {
182
179
/* Don't do this check if it's coming from a pipe or something. It's
183
* only an extra sanity check anyway.
180
* only an extra sanity check anyway. */
185
181
if (stab.st_size < ir->filesize)
186
182
ohshit(_("file `%.250s' is corrupt - too short"),fn);
189
185
ir->headerlen = strlen(DPKG_AR_MAGIC) +
190
186
sizeof(arh) + thisilen + (thisilen & 1) + sizeof(arh);
195
191
void mustgetpartinfo(const char *filename, struct partinfo *ri) {
198
194
part= fopen(filename,"r");
199
195
if (!part) ohshite(_("cannot open archive part file `%.250s'"),filename);
200
196
if (!read_info(part,filename,ri))
208
204
" Part of package: %s\n"
209
205
" ... version: %s\n"
210
206
" ... MD5 checksum: %s\n"
211
" ... length: %lu bytes\n"
212
" ... split every: %lu bytes\n"
207
" ... length: %jd bytes\n"
208
" ... split every: %jd bytes\n"
213
209
" Part number: %d/%d\n"
214
" Part length: %zi bytes\n"
215
" Part offset: %lu bytes\n"
216
" Part file size (used portion): %lu bytes\n\n"),
210
" Part length: %jd bytes\n"
211
" Part offset: %jd bytes\n"
212
" Part file size (used portion): %jd bytes\n\n"),
218
(intmax_t)pi->orglength,
219
(intmax_t)pi->maxpartlen,
228
(unsigned long)pi->filesize);
222
(intmax_t)pi->thispartlen,
223
(intmax_t)pi->thispartoffset,
224
(intmax_t)pi->filesize);
231
void do_info(const char *const *argv) {
228
do_info(const char *const *argv)
232
230
const char *thisarg;
233
231
struct partinfo *pi, ps;