Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/pax/pax-cpio.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1987-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
22
/*
23
* pax { asc aschk binary cpio } formats
24
*/
25
26
#include "format.h"
27
28
#define ASC 1
29
#define ASCHK 2
30
#define BINARY 3
31
#define CPIO 4
32
33
#define CPIO_MAGIC 070707
34
#define CPIO_EXTENDED 1
35
#define CPIO_HEADER 76
36
#define CPIO_TRAILER "TRAILER!!!"
37
#define CPIO_TRUNCATE(x) ((x)&0177777)
38
#define CPIO_NAMESIZE 256
39
#define CPIO_ALIGN 0
40
41
#define ASC_HEADER 110
42
#define ASC_MAGIC 070701
43
#define ASC_NAMESIZE 1024
44
#define ASC_ALIGN 4
45
46
#define ASCHK_MAGIC 070702
47
48
#define BINARY_HEADER sizeof(Binary_header_t)
49
#define BINARY_NAMESIZE 256
50
#define BINARY_ALIGN 2
51
52
typedef struct Binary_header_s
53
{
54
short magic;
55
unsigned short dev;
56
unsigned short ino;
57
unsigned short mode;
58
unsigned short uid;
59
unsigned short gid;
60
short links;
61
unsigned short rdev;
62
unsigned short mtime[2];
63
short namesize;
64
unsigned short size[2];
65
} Binary_header_t;
66
67
typedef struct Localstat_s
68
{
69
long dev;
70
long ino;
71
long mode;
72
long uid;
73
long gid;
74
long nlink;
75
long rdev;
76
long mtime;
77
off_t size;
78
long dev_major;
79
long dev_minor;
80
long rdev_major;
81
long rdev_minor;
82
long checksum;
83
} Localstat_t;
84
85
typedef struct Cpio_s
86
{
87
int trailer;
88
#if CPIO_EXTENDED
89
char opsbuf[PATH_MAX]; /* extended ops buffer */
90
char* ops; /* opsbuf output pointer */
91
#endif
92
} Cpio_t;
93
94
#if CPIO_EXTENDED
95
96
/*
97
* get and execute extended ops from input
98
*/
99
100
static void
101
getxops(register Archive_t* ap, register File_t* f)
102
{
103
register char* p;
104
register char* s;
105
register int c;
106
107
if (f->namesize > (c = strlen(f->name) + 1))
108
for (p = f->name + c; c = *p++;)
109
{
110
for (s = p; *p; p++);
111
p++;
112
message((-2, "%s: %s: entry %d.%d op = %c%s", ap->name, f->name, ap->volume, ap->entry, c, s));
113
switch (c)
114
{
115
case 'd':
116
IDEVICE(f->st, strtol(s, NiL, 16));
117
break;
118
case 'g':
119
f->st->st_gid = strtol(s, NiL, 16);
120
break;
121
case 's':
122
f->st->st_size = strtoll(s, NiL, 16);
123
break;
124
case 'u':
125
f->st->st_uid = strtol(s, NiL, 16);
126
break;
127
case 'G':
128
f->gidname = s;
129
break;
130
case 'U':
131
f->uidname = s;
132
break;
133
134
/*
135
* NOTE: ignore unknown ops for future extensions
136
*/
137
}
138
}
139
}
140
141
/*
142
* set end of extended ops
143
*/
144
145
static void
146
setxops(Archive_t* ap, register File_t* f)
147
{
148
register Cpio_t* cpio = (Cpio_t*)ap->data;
149
register int n;
150
151
if (n = cpio->ops - cpio->opsbuf)
152
{
153
n++;
154
*cpio->ops++ = 0;
155
if ((f->namesize += n) > CPIO_NAMESIZE)
156
error(1, "%s: extended ops may crash older cpio programs", f->name);
157
}
158
}
159
160
/*
161
* output filename and extended ops
162
*/
163
164
static void
165
putxops(Pax_t* pax, Archive_t* ap, register File_t* f)
166
{
167
register Cpio_t* cpio = (Cpio_t*)ap->data;
168
register int n;
169
170
n = cpio->ops - cpio->opsbuf;
171
paxwrite(pax, ap, f->name, f->namesize -= n);
172
if (n)
173
paxwrite(pax, ap, cpio->ops = cpio->opsbuf, n);
174
}
175
176
177
/*
178
* add extended op string
179
*/
180
181
static void
182
addxopstr(Archive_t* ap, int op, register char* s)
183
{
184
register Cpio_t* cpio = (Cpio_t*)ap->data;
185
register char* p = cpio->ops;
186
register char* e = cpio->opsbuf + sizeof(cpio->opsbuf) - 3;
187
188
if (p < e)
189
{
190
*p++ = op;
191
while (*s && p < e)
192
*p++ = *s++;
193
*p++ = 0;
194
cpio->ops = p;
195
}
196
#if DEBUG
197
if (*s)
198
error(PANIC, "addxopstr('%c',\"%s\") overflow", op, s);
199
#endif
200
}
201
202
/*
203
* add extended op number
204
*/
205
206
static void
207
addxopnum(Archive_t* ap, int op, Sflong_t n)
208
{
209
char buf[33];
210
211
sfsprintf(buf, sizeof(buf), "%I*x", sizeof(n), n);
212
addxopstr(ap, op, buf);
213
}
214
215
#endif
216
217
static int
218
init(Archive_t* ap)
219
{
220
register Cpio_t* cpio;
221
222
if (ap->data)
223
{
224
cpio = (Cpio_t*)ap->data;
225
memset(cpio, 0, sizeof(*cpio));
226
}
227
else
228
{
229
if (!(cpio = newof(0, Cpio_t, 1, 0)))
230
nospace();
231
ap->data = cpio;
232
}
233
#if CPIO_EXTENDED
234
cpio->ops = cpio->opsbuf;
235
#endif
236
return 1;
237
}
238
239
static int
240
cpio_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size)
241
{
242
int magic;
243
244
if (size >= CPIO_HEADER && buf[0] == '0' && sfsscanf((char*)buf, "%6o", &magic) == 1 && magic == CPIO_MAGIC)
245
return init(ap);
246
return 0;
247
}
248
249
static int
250
cpio_common(Pax_t* pax, register Archive_t* ap, register File_t* f, int align, int header)
251
{
252
char* s;
253
254
f->linktype = NOLINK;
255
f->linkpath = 0;
256
f->uidname = 0;
257
f->gidname = 0;
258
switch (ap->format->variant)
259
{
260
case BINARY:
261
align = BINARY_ALIGN;
262
header = BINARY_HEADER;
263
break;
264
case ASC:
265
case ASCHK:
266
align = ASC_ALIGN;
267
header = ASC_HEADER;
268
break;
269
default:
270
align = 0;
271
break;
272
}
273
if (align)
274
{
275
if (header = (header + f->namesize) % align)
276
align -= header;
277
else
278
align = 0;
279
}
280
f->name = paxstash(pax, &ap->stash.head, NiL, f->namesize + align);
281
paxread(pax, ap, f->name, (off_t)0, (off_t)(f->namesize + align), 1);
282
if (f->name[f->namesize - 1])
283
{
284
paxunread(pax, ap, &f->name[f->namesize - 1], 1);
285
f->name[f->namesize - 1] = 0;
286
error(state.keepgoing ? 1 : 3, "%s: entry %d.%d file name terminating null missing", ap->name, ap->volume, ap->entry);
287
}
288
#if CPIO_EXTENDED
289
getxops(ap, f);
290
#endif
291
if (streq(f->name, CPIO_TRAILER))
292
{
293
((Cpio_t*)ap->data)->trailer++;
294
getdeltaheader(ap, f);
295
if (ap->delta)
296
setinfo(ap, f);
297
return 0;
298
}
299
switch (f->type = X_ITYPE(f->st->st_mode))
300
{
301
case X_IFBLK:
302
case X_IFCHR:
303
case X_IFDIR:
304
case X_IFIFO:
305
case X_IFLNK:
306
case X_IFREG:
307
case X_IFSOCK:
308
break;
309
default:
310
error(1, "%s: %s: unknown file type %07o -- regular file assumed", ap->name, f->name, f->type);
311
f->type = X_IFREG;
312
break;
313
}
314
f->st->st_mode &= X_IPERM;
315
f->st->st_mode |= f->type;
316
switch (f->type)
317
{
318
case X_IFLNK:
319
f->linkpath = paxstash(pax, &ap->stash.link, NiL, f->st->st_size);
320
f->linktype = SOFTLINK;
321
s = f->linkpath;
322
while (paxread(pax, ap, s, (off_t)1, (off_t)1, 1) > 0)
323
{
324
f->st->st_size--;
325
if (!*s++)
326
break;
327
if (!f->st->st_size)
328
{
329
*s = 0;
330
break;
331
}
332
}
333
break;
334
default:
335
f->linktype = NOLINK;
336
break;
337
}
338
return 1;
339
}
340
341
static int
342
cpio_done(Pax_t* pax, register Archive_t* ap)
343
{
344
if (ap->data)
345
{
346
free(ap->data);
347
ap->data = 0;
348
}
349
return 0;
350
}
351
352
static int
353
cpio_getheader(Pax_t* pax, Archive_t* ap, register File_t* f)
354
{
355
Localstat_t lst;
356
357
if (paxread(pax, ap, state.tmp.buffer, (off_t)0, (off_t)CPIO_HEADER, 0) <= 0)
358
return 0;
359
state.tmp.buffer[CPIO_HEADER] = 0;
360
if (state.tmp.buffer[0] == '0' && sfsscanf(state.tmp.buffer, "%6o%6lo%6lo%6lo%6lo%6lo%6lo%6lo%11lo%6o%11I*o",
361
&f->magic,
362
&lst.dev,
363
&lst.ino,
364
&lst.mode,
365
&lst.uid,
366
&lst.gid,
367
&lst.nlink,
368
&lst.rdev,
369
&lst.mtime,
370
&f->namesize,
371
sizeof(lst.size), &lst.size) == 11 && f->magic == CPIO_MAGIC)
372
{
373
f->st->st_dev = lst.dev;
374
f->st->st_ino = lst.ino;
375
f->st->st_mode = lst.mode;
376
f->st->st_uid = lst.uid;
377
f->st->st_gid = lst.gid;
378
f->st->st_nlink = lst.nlink;
379
IDEVICE(f->st, lst.rdev);
380
f->st->st_mtime = lst.mtime;
381
f->st->st_size = lst.size;
382
return cpio_common(pax, ap, f, CPIO_ALIGN, CPIO_HEADER);
383
}
384
paxunread(pax, ap, state.tmp.buffer, CPIO_HEADER);
385
return 0;
386
}
387
388
static int
389
cpio_getepilogue(Pax_t* pax, register Archive_t* ap)
390
{
391
register Cpio_t* cpio = (Cpio_t*)ap->data;
392
393
if (!cpio->trailer)
394
{
395
error(2, "%s: %s format corrupt -- epilogue (%s) not found", ap->name, ap->format->name, CPIO_TRAILER);
396
return -1;
397
}
398
return 0;
399
}
400
401
static int
402
cpio_putprologue(Pax_t* pax, Archive_t* ap, int append)
403
{
404
return init(ap);
405
}
406
407
static int
408
cpio_putheader(Pax_t* pax, Archive_t* ap, register File_t* f)
409
{
410
if (state.complete)
411
complete(ap, f, CPIO_HEADER + f->namesize);
412
#if CPIO_EXTENDED
413
if (!f->skip && !state.strict)
414
{
415
getidnames(f);
416
addxopstr(ap, 'U', f->uidname);
417
addxopstr(ap, 'G', f->gidname);
418
if (CPIO_TRUNCATE(idevice(f->st)) != idevice(f->st))
419
addxopnum(ap, 'd', (Sflong_t)idevice(f->st));
420
#if NUMBER_EVEN_THOUGH_NAME
421
if (CPIO_TRUNCATE(f->st->st_gid) != f->st->st_gid)
422
addxopnum(ap, 'g', (Sflong_t)f->st->st_gid);
423
if (CPIO_TRUNCATE(f->st->st_uid) != f->st->st_uid)
424
addxopnum(ap, 'u', (Sflong_t)f->st->st_uid);
425
#endif
426
if (f->st->st_size > 0x7fffffff)
427
addxopnum(ap, 's', (Sflong_t)f->st->st_size);
428
setxops(ap, f);
429
}
430
else
431
#endif
432
{
433
if (CPIO_TRUNCATE(idevice(f->st)) != idevice(f->st))
434
error(1, "%s: special device number truncated", f->name);
435
if (CPIO_TRUNCATE(f->st->st_gid) != f->st->st_gid)
436
error(1, "%s: gid number truncated", f->name);
437
if (CPIO_TRUNCATE(f->st->st_uid) != f->st->st_uid)
438
error(1, "%s: uid number truncated", f->name);
439
}
440
sfsprintf(state.tmp.buffer, state.tmp.buffersize, "%0.6lo%0.6lo%0.6lo%0.6lo%0.6lo%0.6lo%0.6lo%0.6lo%0.11lo%0.6o%0.11I*o",
441
(long)CPIO_TRUNCATE(CPIO_MAGIC),
442
(long)CPIO_TRUNCATE(f->st->st_dev),
443
(long)CPIO_TRUNCATE(f->st->st_ino),
444
(long)CPIO_TRUNCATE(f->st->st_mode),
445
(long)CPIO_TRUNCATE(f->st->st_uid),
446
(long)CPIO_TRUNCATE(f->st->st_gid),
447
(long)CPIO_TRUNCATE(f->st->st_nlink),
448
(long)CPIO_TRUNCATE(idevice(f->st)),
449
(long)f->st->st_mtime,
450
(long)f->namesize,
451
sizeof(intmax_t), (intmax_t)(f->st->st_size + (f->type == X_IFLNK ? f->linkpathsize : 0)));
452
paxwrite(pax, ap, state.tmp.buffer, CPIO_HEADER);
453
#if CPIO_EXTENDED
454
putxops(pax, ap, f);
455
#else
456
paxwrite(pax, ap, f->name, f->namesize);
457
#endif
458
if (f->type == X_IFLNK)
459
{
460
if (streq(f->name, f->linkpath))
461
error(1, "%s: symbolic link loops to self", f->name);
462
paxwrite(pax, ap, f->linkpath, f->linkpathsize);
463
putdeltaheader(ap, f);
464
}
465
return 1;
466
}
467
468
static off_t
469
cpio_putepilogue(Pax_t* pax, Archive_t* ap)
470
{
471
char buf[sizeof(CPIO_TRAILER)];
472
473
putinfo(ap, strcpy(buf, CPIO_TRAILER), ap->delta && !(ap->delta->format->flags & PSEUDO) ? ap->delta->index + 1 : 0, 0);
474
return ap->io->unblocked ? BLOCKSIZE : state.blocksize;
475
}
476
477
static int
478
cpio_event(Pax_t* pax, Archive_t* ap, File_t* f, void* data, unsigned long event)
479
{
480
off_t n;
481
482
switch (event)
483
{
484
case PAX_EVENT_BUG_19951031:
485
/*
486
* compensate for a pre 19951031 pax bug
487
* that added linknamesize to st_size
488
*/
489
490
if (f->st->st_size == f->linkpathsize && paxread(pax, ap, state.tmp.buffer, (off_t)0, n = f->st->st_size + 6, 0) > 0)
491
{
492
paxunread(pax, ap, state.tmp.buffer, n);
493
state.tmp.buffer[6] = 0;
494
state.tmp.buffer[n] = 0;
495
if (strtol(state.tmp.buffer, NiL, 8) == CPIO_MAGIC && strtol(state.tmp.buffer + f->st->st_size, NiL, 8) != CPIO_MAGIC)
496
{
497
f->st->st_size = 0;
498
if (!ap->warnlinkhead)
499
{
500
ap->warnlinkhead = 1;
501
error(1, "%s: compensating for invalid %s header hard link sizes", ap->name, ap->format->name);
502
}
503
}
504
}
505
return 1;
506
case PAX_EVENT_DELTA_EXTEND:
507
return 1;
508
}
509
return 0;
510
}
511
512
static int
513
asc_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size)
514
{
515
unsigned int magic;
516
517
if (size >= ASC_HEADER && buf[0] == '0' && sfsscanf((char*)buf, "%6o", &magic) == 1 && magic == ASC_MAGIC)
518
return init(ap);
519
return 0;
520
}
521
522
static int
523
asc_getheader(Pax_t* pax, Archive_t* ap, register File_t* f)
524
{
525
Localstat_t lst;
526
527
if (paxread(pax, ap, state.tmp.buffer, (off_t)0, (off_t)ASC_HEADER, 0) <= 0)
528
return 0;
529
state.tmp.buffer[ASC_HEADER] = 0;
530
if (state.tmp.buffer[0] == '0' && sfsscanf(state.tmp.buffer, "%6o%8lx%8lx%8lx%8lx%8lx%8lx%8I*x%8lx%8lx%8lx%8lx%8x%8lx",
531
&f->magic,
532
&lst.ino,
533
&lst.mode,
534
&lst.uid,
535
&lst.gid,
536
&lst.nlink,
537
&lst.mtime,
538
sizeof(lst.size), &lst.size,
539
&lst.dev_major,
540
&lst.dev_minor,
541
&lst.rdev_major,
542
&lst.rdev_minor,
543
&f->namesize,
544
&lst.checksum) == 14 && f->magic == ASC_MAGIC)
545
{
546
f->checksum = lst.checksum;
547
f->st->st_dev = makedev(lst.dev_major, lst.dev_minor);
548
f->st->st_ino = lst.ino;
549
f->st->st_mode = lst.mode;
550
f->st->st_uid = lst.uid;
551
f->st->st_gid = lst.gid;
552
f->st->st_nlink = lst.nlink;
553
IDEVICE(f->st, makedev(lst.rdev_major, lst.rdev_minor));
554
f->st->st_mtime = lst.mtime;
555
f->st->st_size = lst.size;
556
return cpio_common(pax, ap, f, ASC_ALIGN, ASC_HEADER);
557
}
558
paxunread(pax, ap, state.tmp.buffer, ASC_HEADER);
559
return 0;
560
}
561
562
static int
563
asc_putheader(Pax_t* pax, Archive_t* ap, register File_t* f)
564
{
565
int n;
566
567
if (state.complete)
568
complete(ap, f, ASC_HEADER + f->namesize);
569
if (ap->format->variant == ASC)
570
f->checksum = 0;
571
sfsprintf(state.tmp.buffer, state.tmp.buffersize, "%0.6lo%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx",
572
(long)(ap->format->variant == ASC ? ASC_MAGIC : ASCHK_MAGIC),
573
(long)f->st->st_ino,
574
(long)f->st->st_mode,
575
(long)f->st->st_uid,
576
(long)f->st->st_gid,
577
(long)f->st->st_nlink,
578
(long)f->st->st_mtime,
579
(long)f->st->st_size + (long)f->linkpathsize,
580
(long)major(f->st->st_dev),
581
(long)minor(f->st->st_dev),
582
(long)major(idevice(f->st)),
583
(long)minor(idevice(f->st)),
584
(long)f->namesize,
585
f->checksum);
586
paxwrite(pax, ap, state.tmp.buffer, ASC_HEADER);
587
paxwrite(pax, ap, f->name, f->namesize);
588
if (n = (ASC_HEADER + f->namesize) % ASC_ALIGN)
589
while (n++ < ASC_ALIGN)
590
paxwrite(pax, ap, "", 1);
591
return 1;
592
}
593
594
static int
595
aschk_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size)
596
{
597
unsigned int magic;
598
599
if (size >= ASC_HEADER && buf[0] == '0' && sfsscanf((char*)buf, "%6o", &magic) == 1 && magic == ASCHK_MAGIC)
600
return init(ap);
601
return 0;
602
}
603
604
static int
605
aschk_getheader(Pax_t* pax, Archive_t* ap, register File_t* f)
606
{
607
Localstat_t lst;
608
609
if (paxread(pax, ap, state.tmp.buffer, (off_t)0, (off_t)ASC_HEADER, 0) <= 0)
610
return 0;
611
state.tmp.buffer[ASC_HEADER] = 0;
612
if (state.tmp.buffer[0] == '0' && sfsscanf(state.tmp.buffer, "%6o%8lx%8lx%8lx%8lx%8lx%8lx%8I*x%8lx%8lx%8lx%8lx%8x%8lx",
613
&f->magic,
614
&lst.ino,
615
&lst.mode,
616
&lst.uid,
617
&lst.gid,
618
&lst.nlink,
619
&lst.mtime,
620
sizeof(lst.size), &lst.size,
621
&lst.dev_major,
622
&lst.dev_minor,
623
&lst.rdev_major,
624
&lst.rdev_minor,
625
&f->namesize,
626
&lst.checksum) == 14 && f->magic == ASCHK_MAGIC)
627
{
628
f->checksum = lst.checksum;
629
f->st->st_dev = makedev(lst.dev_major, lst.dev_minor);
630
f->st->st_ino = lst.ino;
631
f->st->st_mode = lst.mode;
632
f->st->st_uid = lst.uid;
633
f->st->st_gid = lst.gid;
634
f->st->st_nlink = lst.nlink;
635
IDEVICE(f->st, makedev(lst.rdev_major, lst.rdev_minor));
636
f->st->st_mtime = lst.mtime;
637
f->st->st_size = lst.size;
638
return cpio_common(pax, ap, f, ASC_ALIGN, ASC_HEADER);
639
}
640
paxunread(pax, ap, state.tmp.buffer, ASC_HEADER);
641
return 0;
642
}
643
644
static unsigned long
645
aschk_checksum(Pax_t* pax, Archive_t* ap, File_t* f, void* ab, size_t n, register unsigned long sum)
646
{
647
register unsigned char* b = (unsigned char*)ab;
648
register unsigned char* e;
649
650
e = b + n;
651
while (b < e)
652
sum += *b++;
653
return sum;
654
}
655
656
/*
657
* convert binary header shorts to long
658
*/
659
660
static long
661
binary_long(register unsigned short* s)
662
{
663
Integral_t u;
664
665
u.l = 1;
666
if (u.c[0])
667
{
668
u.s[0] = s[1];
669
u.s[1] = s[0];
670
}
671
else
672
{
673
u.s[0] = s[0];
674
u.s[1] = s[1];
675
}
676
return u.l;
677
}
678
679
/*
680
* convert long to binary header shorts
681
*/
682
683
static void
684
binary_short(register unsigned short* s, long n)
685
{
686
Integral_t u;
687
688
u.l = 1;
689
if (u.c[0])
690
{
691
u.l = n;
692
s[0] = u.s[1];
693
s[1] = u.s[0];
694
}
695
else
696
{
697
u.l = n;
698
s[0] = u.s[0];
699
s[1] = u.s[1];
700
}
701
}
702
703
static int
704
binary_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size)
705
{
706
short magic = CPIO_MAGIC;
707
int swap;
708
709
if (size >= BINARY_HEADER && (swap = swapop(&magic, buf, 2)) >= 0)
710
{
711
ap->swap = swap;
712
return init(ap);
713
}
714
return 0;
715
}
716
717
static int
718
binary_getheader(Pax_t* pax, Archive_t* ap, register File_t* f)
719
{
720
Binary_header_t hdr;
721
722
if (paxread(pax, ap, &hdr, (off_t)BINARY_HEADER, (off_t)BINARY_HEADER, 0) <= 0)
723
return 0;
724
if (ap->swap)
725
{
726
memcpy(state.tmp.buffer, &hdr, BINARY_HEADER);
727
swapmem(ap->swap, &hdr, &hdr, BINARY_HEADER);
728
}
729
f->magic = hdr.magic;
730
if (f->magic == CPIO_MAGIC)
731
{
732
f->namesize = hdr.namesize;
733
f->st->st_dev = hdr.dev;
734
f->st->st_ino = hdr.ino;
735
f->st->st_mode = hdr.mode;
736
f->st->st_uid = hdr.uid;
737
f->st->st_gid = hdr.gid;
738
f->st->st_nlink = hdr.links;
739
IDEVICE(f->st, hdr.rdev);
740
f->st->st_mtime = binary_long(hdr.mtime);
741
f->st->st_size = binary_long(hdr.size);
742
return cpio_common(pax, ap, f, CPIO_ALIGN, CPIO_HEADER);
743
}
744
paxunread(pax, ap, state.tmp.buffer, CPIO_HEADER);
745
return 0;
746
}
747
748
static int
749
binary_putheader(Pax_t* pax, Archive_t* ap, register File_t* f)
750
{
751
Binary_header_t hdr;
752
int n;
753
754
if (state.complete)
755
complete(ap, f, BINARY_HEADER + f->namesize);
756
hdr.magic = CPIO_MAGIC;
757
hdr.namesize = f->namesize;
758
binary_short(hdr.size, f->st->st_size + (f->type == X_IFLNK ? f->linkpathsize : 0));
759
hdr.dev = f->st->st_dev;
760
hdr.ino = f->st->st_ino;
761
hdr.mode = f->st->st_mode;
762
hdr.uid = f->st->st_uid;
763
hdr.gid = f->st->st_gid;
764
hdr.links = f->st->st_nlink;
765
hdr.rdev = idevice(f->st);
766
if (hdr.rdev != idevice(f->st))
767
error(1, "%s: special device numbers truncated", f->name);
768
binary_short(hdr.mtime, (long)f->st->st_mtime);
769
paxwrite(pax, ap, &hdr, BINARY_HEADER);
770
paxwrite(pax, ap, f->name, f->namesize);
771
if (n = (BINARY_HEADER + f->namesize) % BINARY_ALIGN)
772
while (n++ < BINARY_ALIGN)
773
paxwrite(pax, ap, "", 1);
774
if (f->type == X_IFLNK)
775
{
776
if (streq(f->name, f->linkpath))
777
error(1, "%s: symbolic link loops to self", f->name);
778
paxwrite(pax, ap, f->linkpath, f->linkpathsize);
779
putdeltaheader(ap, f);
780
}
781
return 1;
782
}
783
784
static int
785
binary_validate(Pax_t* pax, Archive_t* ap, File_t* f)
786
{
787
if (f->namesize > (CPIO_NAMESIZE + 1))
788
{
789
error(2, "%s: file name too long", f->name);
790
return 0;
791
}
792
return 1;
793
}
794
795
Format_t pax_asc_format =
796
{
797
"asc",
798
0,
799
"s5r4 extended cpio character",
800
ASC,
801
ARCHIVE|IN|OUT|APPEND,
802
DEFBUFFER,
803
DEFBLOCKS,
804
4,
805
pax_asc_next,
806
0,
807
cpio_done,
808
asc_getprologue,
809
asc_getheader,
810
0,
811
0,
812
cpio_getepilogue,
813
cpio_putprologue,
814
asc_putheader,
815
0,
816
0,
817
cpio_putepilogue,
818
0,
819
0,
820
0
821
};
822
823
Format_t pax_aschk_format =
824
{
825
"aschk",
826
0,
827
"s5r4 extended cpio character with checksum",
828
ASCHK,
829
ARCHIVE|IN|OUT|APPEND,
830
DEFBUFFER,
831
DEFBLOCKS,
832
4,
833
pax_aschk_next,
834
0,
835
cpio_done,
836
aschk_getprologue,
837
aschk_getheader,
838
0,
839
0,
840
cpio_getepilogue,
841
cpio_putprologue,
842
asc_putheader,
843
0,
844
0,
845
cpio_putepilogue,
846
0,
847
0,
848
aschk_checksum
849
};
850
851
Format_t pax_binary_format =
852
{
853
"binary",
854
"binary-cpio",
855
"cpio binary with symlinks",
856
BINARY,
857
ARCHIVE|IN|OUT|APPEND,
858
DEFBUFFER,
859
DEFBLOCKS,
860
2,
861
pax_binary_next,
862
0,
863
cpio_done,
864
binary_getprologue,
865
binary_getheader,
866
0,
867
0,
868
cpio_getepilogue,
869
cpio_putprologue,
870
binary_putheader,
871
0,
872
0,
873
cpio_putepilogue,
874
0,
875
0,
876
0,
877
binary_validate
878
};
879
880
Format_t pax_cpio_format =
881
{
882
"cpio",
883
0,
884
"cpio character with symlinks",
885
CPIO,
886
ARCHIVE|IN|OUT|APPEND,
887
DEFBUFFER,
888
DEFBLOCKS,
889
0,
890
PAXNEXT(cpio),
891
0,
892
cpio_done,
893
cpio_getprologue,
894
cpio_getheader,
895
0,
896
0,
897
cpio_getepilogue,
898
cpio_putprologue,
899
cpio_putheader,
900
0,
901
0,
902
cpio_putepilogue,
903
0,
904
0,
905
0,
906
0,
907
cpio_event,
908
PAX_EVENT_BUG_19951031|PAX_EVENT_DELTA_EXTEND
909
};
910
911
PAXLIB(cpio)
912
913