GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: bin/pax/cpio.c Lines: 0 346 0.0 %
Date: 2016-12-06 Branches: 0 252 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: cpio.c,v 1.27 2015/03/19 05:14:24 guenther Exp $	*/
2
/*	$NetBSD: cpio.c,v 1.5 1995/03/21 09:07:13 cgd Exp $	*/
3
4
/*-
5
 * Copyright (c) 1992 Keith Muller.
6
 * Copyright (c) 1992, 1993
7
 *	The Regents of the University of California.  All rights reserved.
8
 *
9
 * This code is derived from software contributed to Berkeley by
10
 * Keith Muller of the University of California, San Diego.
11
 *
12
 * Redistribution and use in source and binary forms, with or without
13
 * modification, are permitted provided that the following conditions
14
 * are met:
15
 * 1. Redistributions of source code must retain the above copyright
16
 *    notice, this list of conditions and the following disclaimer.
17
 * 2. Redistributions in binary form must reproduce the above copyright
18
 *    notice, this list of conditions and the following disclaimer in the
19
 *    documentation and/or other materials provided with the distribution.
20
 * 3. Neither the name of the University nor the names of its contributors
21
 *    may be used to endorse or promote products derived from this software
22
 *    without specific prior written permission.
23
 *
24
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34
 * SUCH DAMAGE.
35
 */
36
37
#include <sys/types.h>
38
#include <sys/time.h>
39
#include <sys/stat.h>
40
#include <limits.h>
41
#include <string.h>
42
#include <stdio.h>
43
#include <unistd.h>
44
#include <stdlib.h>
45
#include "pax.h"
46
#include "cpio.h"
47
#include "extern.h"
48
49
static int rd_nm(ARCHD *, int);
50
static int rd_ln_nm(ARCHD *);
51
static int com_rd(ARCHD *);
52
53
/*
54
 * Routines which support the different cpio versions
55
 */
56
57
static int swp_head;		/* binary cpio header byte swap */
58
59
/*
60
 * Routines common to all versions of cpio
61
 */
62
63
/*
64
 * cpio_strd()
65
 *	Fire up the hard link detection code
66
 * Return:
67
 *      0 if ok -1 otherwise (the return values of lnk_start())
68
 */
69
70
int
71
cpio_strd(void)
72
{
73
	return(lnk_start());
74
}
75
76
/*
77
 * cpio_trail()
78
 *	Called to determine if a header block is a valid trailer. We are
79
 *	passed the block, the in_sync flag (which tells us we are in resync
80
 *	mode; looking for a valid header), and cnt (which starts at zero)
81
 *	which is used to count the number of empty blocks we have seen so far.
82
 * Return:
83
 *	0 if a valid trailer, -1 if not a valid trailer,
84
 */
85
86
int
87
cpio_trail(ARCHD *arcn, char *notused, int notused2, int *notused3)
88
{
89
	/*
90
	 * look for trailer id in file we are about to process
91
	 */
92
	if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0))
93
		return(0);
94
	return(-1);
95
}
96
97
/*
98
 * com_rd()
99
 *	operations common to all cpio read functions.
100
 * Return:
101
 *	0
102
 */
103
104
static int
105
com_rd(ARCHD *arcn)
106
{
107
	arcn->skip = 0;
108
	arcn->pat = NULL;
109
	arcn->org_name = arcn->name;
110
	switch (arcn->sb.st_mode & C_IFMT) {
111
	case C_ISFIFO:
112
		arcn->type = PAX_FIF;
113
		break;
114
	case C_ISDIR:
115
		arcn->type = PAX_DIR;
116
		break;
117
	case C_ISBLK:
118
		arcn->type = PAX_BLK;
119
		break;
120
	case C_ISCHR:
121
		arcn->type = PAX_CHR;
122
		break;
123
	case C_ISLNK:
124
		arcn->type = PAX_SLK;
125
		break;
126
	case C_ISOCK:
127
		arcn->type = PAX_SCK;
128
		break;
129
	case C_ISCTG:
130
	case C_ISREG:
131
	default:
132
		/*
133
		 * we have file data, set up skip (pad is set in the format
134
		 * specific sections)
135
		 */
136
		arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG;
137
		arcn->type = PAX_REG;
138
		arcn->skip = arcn->sb.st_size;
139
		break;
140
	}
141
	if (chk_lnk(arcn) < 0)
142
		return(-1);
143
	return(0);
144
}
145
146
/*
147
 * cpio_endwr()
148
 *	write the special file with the name trailer in the proper format
149
 * Return:
150
 *	result of the write of the trailer from the cpio specific write func
151
 */
152
153
int
154
cpio_endwr(void)
155
{
156
	ARCHD last;
157
158
	/*
159
	 * create a trailer request and call the proper format write function
160
	 */
161
	memset(&last, 0, sizeof(last));
162
	last.nlen = sizeof(TRAILER) - 1;
163
	last.type = PAX_REG;
164
	last.sb.st_nlink = 1;
165
	(void)strlcpy(last.name, TRAILER, sizeof(last.name));
166
	return((*frmt->wr)(&last));
167
}
168
169
/*
170
 * rd_nm()
171
 *	read in the file name which follows the cpio header
172
 * Return:
173
 *	0 if ok, -1 otherwise
174
 */
175
176
static int
177
rd_nm(ARCHD *arcn, int nsz)
178
{
179
	/*
180
	 * do not even try bogus values
181
	 */
182
	if ((nsz == 0) || (nsz > sizeof(arcn->name))) {
183
		paxwarn(1, "Cpio file name length %d is out of range", nsz);
184
		return(-1);
185
	}
186
187
	/*
188
	 * read the name and make sure it is not empty and is \0 terminated
189
	 */
190
	if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') ||
191
	    (arcn->name[0] == '\0')) {
192
		paxwarn(1, "Cpio file name in header is corrupted");
193
		return(-1);
194
	}
195
	return(0);
196
}
197
198
/*
199
 * rd_ln_nm()
200
 *	read in the link name for a file with links. The link name is stored
201
 *	like file data (and is NOT \0 terminated!)
202
 * Return:
203
 *	0 if ok, -1 otherwise
204
 */
205
206
static int
207
rd_ln_nm(ARCHD *arcn)
208
{
209
	/*
210
	 * check the length specified for bogus values
211
	 */
212
	if ((arcn->sb.st_size == 0) ||
213
	    (arcn->sb.st_size >= sizeof(arcn->ln_name))) {
214
		paxwarn(1, "Cpio link name length is invalid: %llu",
215
		    arcn->sb.st_size);
216
		return(-1);
217
	}
218
219
	/*
220
	 * read in the link name and \0 terminate it
221
	 */
222
	if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) !=
223
	    (int)arcn->sb.st_size) {
224
		paxwarn(1, "Cpio link name read error");
225
		return(-1);
226
	}
227
	arcn->ln_nlen = arcn->sb.st_size;
228
	arcn->ln_name[arcn->ln_nlen] = '\0';
229
230
	/*
231
	 * watch out for those empty link names
232
	 */
233
	if (arcn->ln_name[0] == '\0') {
234
		paxwarn(1, "Cpio link name is corrupt");
235
		return(-1);
236
	}
237
	return(0);
238
}
239
240
/*
241
 * Routines common to the extended byte oriented cpio format
242
 */
243
244
/*
245
 * cpio_id()
246
 *      determine if a block given to us is a valid extended byte oriented
247
 *	cpio header
248
 * Return:
249
 *      0 if a valid header, -1 otherwise
250
 */
251
252
int
253
cpio_id(char *blk, int size)
254
{
255
	if ((size < sizeof(HD_CPIO)) ||
256
	    (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0))
257
		return(-1);
258
	return(0);
259
}
260
261
/*
262
 * cpio_rd()
263
 *	determine if a buffer is a byte oriented extended cpio archive entry.
264
 *	convert and store the values in the ARCHD parameter.
265
 * Return:
266
 *	0 if a valid header, -1 otherwise.
267
 */
268
269
int
270
cpio_rd(ARCHD *arcn, char *buf)
271
{
272
	int nsz;
273
	u_quad_t val;
274
	HD_CPIO *hd;
275
276
	/*
277
	 * check that this is a valid header, if not return -1
278
	 */
279
	if (cpio_id(buf, sizeof(HD_CPIO)) < 0)
280
		return(-1);
281
	hd = (HD_CPIO *)buf;
282
283
	/*
284
	 * byte oriented cpio (posix) does not have padding! extract the octal
285
	 * ascii fields from the header
286
	 */
287
	arcn->pad = 0L;
288
	arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT);
289
	arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT);
290
	arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT);
291
	arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT);
292
	arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT);
293
	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
294
	    OCT);
295
	arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT);
296
	val = asc_uqd(hd->c_mtime, sizeof(hd->c_mtime), OCT);
297
	if ((time_t)val < 0 || (time_t)val != val)
298
		arcn->sb.st_mtime = INT_MAX;			/* XXX 2038 */
299
	else
300
		arcn->sb.st_mtime = val;
301
	arcn->sb.st_mtim.tv_nsec = 0;
302
	arcn->sb.st_ctim = arcn->sb.st_atim = arcn->sb.st_mtim;
303
	arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize),
304
	    OCT);
305
306
	/*
307
	 * check name size and if valid, read in the name of this entry (name
308
	 * follows header in the archive)
309
	 */
310
	if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2)
311
		return(-1);
312
	arcn->nlen = nsz - 1;
313
	if (rd_nm(arcn, nsz) < 0)
314
		return(-1);
315
316
	if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
317
		/*
318
		 * no link name to read for this file
319
		 */
320
		arcn->ln_nlen = 0;
321
		arcn->ln_name[0] = '\0';
322
		return(com_rd(arcn));
323
	}
324
325
	/*
326
	 * check link name size and read in the link name. Link names are
327
	 * stored like file data.
328
	 */
329
	if (rd_ln_nm(arcn) < 0)
330
		return(-1);
331
332
	/*
333
	 * we have a valid header (with a link)
334
	 */
335
	return(com_rd(arcn));
336
}
337
338
/*
339
 * cpio_endrd()
340
 *      no cleanup needed here, just return size of the trailer (for append)
341
 * Return:
342
 *      size of trailer header in this format
343
 */
344
345
off_t
346
cpio_endrd(void)
347
{
348
	return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER)));
349
}
350
351
/*
352
 * cpio_stwr()
353
 *	start up the device mapping table
354
 * Return:
355
 *	0 if ok, -1 otherwise (what dev_start() returns)
356
 */
357
358
int
359
cpio_stwr(void)
360
{
361
	return(dev_start());
362
}
363
364
/*
365
 * cpio_wr()
366
 *	copy the data in the ARCHD to buffer in extended byte oriented cpio
367
 *	format.
368
 * Return
369
 *      0 if file has data to be written after the header, 1 if file has NO
370
 *	data to write after the header, -1 if archive write failed
371
 */
372
373
int
374
cpio_wr(ARCHD *arcn)
375
{
376
	HD_CPIO *hd;
377
	int nsz;
378
	char hdblk[sizeof(HD_CPIO)];
379
380
	/*
381
	 * check and repair truncated device and inode fields in the header
382
	 */
383
	if (map_dev(arcn, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0)
384
		return(-1);
385
386
	arcn->pad = 0L;
387
	nsz = arcn->nlen + 1;
388
	hd = (HD_CPIO *)hdblk;
389
	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
390
		arcn->sb.st_rdev = 0;
391
392
	switch (arcn->type) {
393
	case PAX_CTG:
394
	case PAX_REG:
395
	case PAX_HRG:
396
		/*
397
		 * set data size for file data
398
		 */
399
		if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
400
		    sizeof(hd->c_filesize), OCT)) {
401
			paxwarn(1,"File is too large for cpio format %s",
402
			    arcn->org_name);
403
			return(1);
404
		}
405
		break;
406
	case PAX_SLK:
407
		/*
408
		 * set data size to hold link name
409
		 */
410
		if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
411
		    sizeof(hd->c_filesize), OCT))
412
			goto out;
413
		break;
414
	default:
415
		/*
416
		 * all other file types have no file data
417
		 */
418
		if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize),
419
		     OCT))
420
			goto out;
421
		break;
422
	}
423
424
	/*
425
	 * copy the values to the header using octal ascii
426
	 */
427
	if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) ||
428
	    ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev),
429
		OCT) ||
430
	    ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
431
		OCT) ||
432
	    ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
433
		OCT) ||
434
	    ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
435
		OCT) ||
436
	    ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
437
		OCT) ||
438
	    ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
439
		 OCT) ||
440
	    ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev),
441
		OCT) ||
442
	    uqd_asc(arcn->sb.st_mtime < 0 ? 0 : arcn->sb.st_mtime, hd->c_mtime,
443
		sizeof(hd->c_mtime), OCT) ||
444
	    ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT))
445
		goto out;
446
447
	/*
448
	 * write the file name to the archive
449
	 */
450
	if ((wr_rdbuf(hdblk, (int)sizeof(HD_CPIO)) < 0) ||
451
	    (wr_rdbuf(arcn->name, nsz) < 0)) {
452
		paxwarn(1, "Unable to write cpio header for %s", arcn->org_name);
453
		return(-1);
454
	}
455
456
	/*
457
	 * if this file has data, we are done. The caller will write the file
458
	 * data, if we are link tell caller we are done, go to next file
459
	 */
460
	if (PAX_IS_REG(arcn->type) || (arcn->type == PAX_HRG))
461
		return(0);
462
	if (arcn->type != PAX_SLK)
463
		return(1);
464
465
	/*
466
	 * write the link name to the archive, tell the caller to go to the
467
	 * next file as we are done.
468
	 */
469
	if (wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) {
470
		paxwarn(1,"Unable to write cpio link name for %s",arcn->org_name);
471
		return(-1);
472
	}
473
	return(1);
474
475
    out:
476
	/*
477
	 * header field is out of range
478
	 */
479
	paxwarn(1, "Cpio header field is too small to store file %s",
480
	    arcn->org_name);
481
	return(1);
482
}
483
484
/*
485
 * Routines common to the system VR4 version of cpio (with/without file CRC)
486
 */
487
488
/*
489
 * vcpio_id()
490
 *      determine if a block given to us is a valid system VR4 cpio header
491
 *	WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header
492
 *	uses HEX
493
 * Return:
494
 *      0 if a valid header, -1 otherwise
495
 */
496
497
int
498
vcpio_id(char *blk, int size)
499
{
500
	if ((size < sizeof(HD_VCPIO)) ||
501
	    (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0))
502
		return(-1);
503
	return(0);
504
}
505
506
/*
507
 * crc_id()
508
 *      determine if a block given to us is a valid system VR4 cpio header
509
 *	WITH crc. WATCH it the magic cookies are in OCTAL the header uses HEX
510
 * Return:
511
 *      0 if a valid header, -1 otherwise
512
 */
513
514
int
515
crc_id(char *blk, int size)
516
{
517
	if ((size < sizeof(HD_VCPIO)) ||
518
	    (strncmp(blk, AVCMAGIC, sizeof(AVCMAGIC) - 1) != 0))
519
		return(-1);
520
	return(0);
521
}
522
523
/*
524
 * crc_strd()
525
 w	set file data CRC calculations. Fire up the hard link detection code
526
 * Return:
527
 *      0 if ok -1 otherwise (the return values of lnk_start())
528
 */
529
530
int
531
crc_strd(void)
532
{
533
	docrc = 1;
534
	return(lnk_start());
535
}
536
537
/*
538
 * vcpio_rd()
539
 *	determine if a buffer is a system VR4 archive entry. (with/without CRC)
540
 *	convert and store the values in the ARCHD parameter.
541
 * Return:
542
 *	0 if a valid header, -1 otherwise.
543
 */
544
545
int
546
vcpio_rd(ARCHD *arcn, char *buf)
547
{
548
	HD_VCPIO *hd;
549
	dev_t devminor;
550
	dev_t devmajor;
551
	int nsz;
552
553
	/*
554
	 * during the id phase it was determined if we were using CRC, use the
555
	 * proper id routine.
556
	 */
557
	if (docrc) {
558
		if (crc_id(buf, sizeof(HD_VCPIO)) < 0)
559
			return(-1);
560
	} else {
561
		if (vcpio_id(buf, sizeof(HD_VCPIO)) < 0)
562
			return(-1);
563
	}
564
565
	hd = (HD_VCPIO *)buf;
566
	arcn->pad = 0L;
567
568
	/*
569
	 * extract the hex ascii fields from the header
570
	 */
571
	arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX);
572
	arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX);
573
	arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX);
574
	arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX);
575
	arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX);
576
	arcn->sb.st_mtim.tv_nsec = 0;
577
	arcn->sb.st_ctim = arcn->sb.st_atim = arcn->sb.st_mtim;
578
	arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,
579
	    sizeof(hd->c_filesize), HEX);
580
	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
581
	    HEX);
582
	devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX);
583
	devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX);
584
	arcn->sb.st_dev = TODEV(devmajor, devminor);
585
	devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX);
586
	devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX);
587
	arcn->sb.st_rdev = TODEV(devmajor, devminor);
588
	arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX);
589
590
	/*
591
	 * check the length of the file name, if ok read it in, return -1 if
592
	 * bogus
593
	 */
594
	if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2)
595
		return(-1);
596
	arcn->nlen = nsz - 1;
597
	if (rd_nm(arcn, nsz) < 0)
598
		return(-1);
599
600
	/*
601
	 * skip padding. header + filename is aligned to 4 byte boundaries
602
	 */
603
	if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)
604
		return(-1);
605
606
	/*
607
	 * if not a link (or a file with no data), calculate pad size (for
608
	 * padding which follows the file data), clear the link name and return
609
	 */
610
	if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
611
		/*
612
		 * we have a valid header (not a link)
613
		 */
614
		arcn->ln_nlen = 0;
615
		arcn->ln_name[0] = '\0';
616
		arcn->pad = VCPIO_PAD(arcn->sb.st_size);
617
		return(com_rd(arcn));
618
	}
619
620
	/*
621
	 * read in the link name and skip over the padding
622
	 */
623
	if ((rd_ln_nm(arcn) < 0) ||
624
	    (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0))
625
		return(-1);
626
627
	/*
628
	 * we have a valid header (with a link)
629
	 */
630
	return(com_rd(arcn));
631
}
632
633
/*
634
 * vcpio_endrd()
635
 *      no cleanup needed here, just return size of the trailer (for append)
636
 * Return:
637
 *      size of trailer header in this format
638
 */
639
640
off_t
641
vcpio_endrd(void)
642
{
643
	return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) +
644
		(VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER)))));
645
}
646
647
/*
648
 * crc_stwr()
649
 *	start up the device mapping table, enable crc file calculation
650
 * Return:
651
 *	0 if ok, -1 otherwise (what dev_start() returns)
652
 */
653
654
int
655
crc_stwr(void)
656
{
657
	docrc = 1;
658
	return(dev_start());
659
}
660
661
/*
662
 * vcpio_wr()
663
 *	copy the data in the ARCHD to buffer in system VR4 cpio
664
 *	(with/without crc) format.
665
 * Return
666
 *	0 if file has data to be written after the header, 1 if file has
667
 *	NO data to write after the header, -1 if archive write failed
668
 */
669
670
int
671
vcpio_wr(ARCHD *arcn)
672
{
673
	HD_VCPIO *hd;
674
	unsigned int nsz;
675
	char hdblk[sizeof(HD_VCPIO)];
676
677
	/*
678
	 * check and repair truncated device and inode fields in the cpio
679
	 * header
680
	 */
681
	if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0)
682
		return(-1);
683
	nsz = arcn->nlen + 1;
684
	hd = (HD_VCPIO *)hdblk;
685
	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
686
		arcn->sb.st_rdev = 0;
687
688
	/*
689
	 * add the proper magic value depending whether we were asked for
690
	 * file data crc's, and the crc if needed.
691
	 */
692
	if (docrc) {
693
		if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic),
694
			OCT) ||
695
		    ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum),
696
			HEX))
697
			goto out;
698
	} else {
699
		if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic),
700
			OCT) ||
701
		    ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX))
702
			goto out;
703
	}
704
705
	switch (arcn->type) {
706
	case PAX_CTG:
707
	case PAX_REG:
708
	case PAX_HRG:
709
		/*
710
		 * caller will copy file data to the archive. tell him how
711
		 * much to pad.
712
		 */
713
		arcn->pad = VCPIO_PAD(arcn->sb.st_size);
714
		if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
715
		    sizeof(hd->c_filesize), HEX)) {
716
			paxwarn(1,"File is too large for sv4cpio format %s",
717
			    arcn->org_name);
718
			return(1);
719
		}
720
		break;
721
	case PAX_SLK:
722
		/*
723
		 * no file data for the caller to process, the file data has
724
		 * the size of the link
725
		 */
726
		arcn->pad = 0L;
727
		if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
728
		    sizeof(hd->c_filesize), HEX))
729
			goto out;
730
		break;
731
	default:
732
		/*
733
		 * no file data for the caller to process
734
		 */
735
		arcn->pad = 0L;
736
		if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize),
737
		    HEX))
738
			goto out;
739
		break;
740
	}
741
742
	/*
743
	 * set the other fields in the header
744
	 */
745
	if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
746
		HEX) ||
747
	    ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
748
		HEX) ||
749
	    ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
750
		HEX) ||
751
	    ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
752
		HEX) ||
753
	    ul_asc(arcn->sb.st_mtime < 0 ? 0 : arcn->sb.st_mtime, hd->c_mtime,
754
		sizeof(hd->c_mtime), HEX) ||
755
	    ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
756
		HEX) ||
757
	    ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj),
758
		HEX) ||
759
	    ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min),
760
		HEX) ||
761
	    ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj),
762
		HEX) ||
763
	    ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min),
764
		HEX) ||
765
	    ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX))
766
		goto out;
767
768
	/*
769
	 * write the header, the file name and padding as required.
770
	 */
771
	if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) ||
772
	    (wr_rdbuf(arcn->name, (int)nsz) < 0)  ||
773
	    (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) {
774
		paxwarn(1,"Could not write sv4cpio header for %s",arcn->org_name);
775
		return(-1);
776
	}
777
778
	/*
779
	 * if we have file data, tell the caller we are done, copy the file
780
	 */
781
	if (PAX_IS_REG(arcn->type) || (arcn->type == PAX_HRG))
782
		return(0);
783
784
	/*
785
	 * if we are not a link, tell the caller we are done, go to next file
786
	 */
787
	if (arcn->type != PAX_SLK)
788
		return(1);
789
790
	/*
791
	 * write the link name, tell the caller we are done.
792
	 */
793
	if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
794
	    (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) {
795
		paxwarn(1,"Could not write sv4cpio link name for %s",
796
		    arcn->org_name);
797
		return(-1);
798
	}
799
	return(1);
800
801
    out:
802
	/*
803
	 * header field is out of range
804
	 */
805
	paxwarn(1,"Sv4cpio header field is too small for file %s",arcn->org_name);
806
	return(1);
807
}
808
809
/*
810
 * Routines common to the old binary header cpio
811
 */
812
813
/*
814
 * bcpio_id()
815
 *      determine if a block given to us is a old binary cpio header
816
 *	(with/without header byte swapping)
817
 * Return:
818
 *      0 if a valid header, -1 otherwise
819
 */
820
821
int
822
bcpio_id(char *blk, int size)
823
{
824
	if (size < sizeof(HD_BCPIO))
825
		return(-1);
826
827
	/*
828
	 * check both normal and byte swapped magic cookies
829
	 */
830
	if (((u_short)SHRT_EXT(blk)) == MAGIC)
831
		return(0);
832
	if (((u_short)RSHRT_EXT(blk)) == MAGIC) {
833
		if (!swp_head)
834
			++swp_head;
835
		return(0);
836
	}
837
	return(-1);
838
}
839
840
/*
841
 * bcpio_rd()
842
 *	determine if a buffer is a old binary archive entry. (it may have byte
843
 *	swapped header) convert and store the values in the ARCHD parameter.
844
 *	This is a very old header format and should not really be used.
845
 * Return:
846
 *	0 if a valid header, -1 otherwise.
847
 */
848
849
int
850
bcpio_rd(ARCHD *arcn, char *buf)
851
{
852
	HD_BCPIO *hd;
853
	int nsz;
854
855
	/*
856
	 * check the header
857
	 */
858
	if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0)
859
		return(-1);
860
861
	arcn->pad = 0L;
862
	hd = (HD_BCPIO *)buf;
863
	if (swp_head) {
864
		/*
865
		 * header has swapped bytes on 16 bit boundaries
866
		 */
867
		arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev));
868
		arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino));
869
		arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode));
870
		arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid));
871
		arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid));
872
		arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink));
873
		arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev));
874
		arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1));
875
		arcn->sb.st_mtime =  (arcn->sb.st_mtime << 16) |
876
			((time_t)(RSHRT_EXT(hd->h_mtime_2)));
877
		arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1));
878
		arcn->sb.st_size = (arcn->sb.st_size << 16) |
879
			((off_t)(RSHRT_EXT(hd->h_filesize_2)));
880
		nsz = (int)(RSHRT_EXT(hd->h_namesize));
881
	} else {
882
		arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev));
883
		arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino));
884
		arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode));
885
		arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid));
886
		arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid));
887
		arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink));
888
		arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev));
889
		arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1));
890
		arcn->sb.st_mtime =  (arcn->sb.st_mtime << 16) |
891
			((time_t)(SHRT_EXT(hd->h_mtime_2)));
892
		arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1));
893
		arcn->sb.st_size = (arcn->sb.st_size << 16) |
894
			((off_t)(SHRT_EXT(hd->h_filesize_2)));
895
		nsz = (int)(SHRT_EXT(hd->h_namesize));
896
	}
897
	arcn->sb.st_mtim.tv_nsec = 0;
898
	arcn->sb.st_ctim = arcn->sb.st_atim = arcn->sb.st_mtim;
899
900
	/*
901
	 * check the file name size, if bogus give up. otherwise read the file
902
	 * name
903
	 */
904
	if (nsz < 2)
905
		return(-1);
906
	arcn->nlen = nsz - 1;
907
	if (rd_nm(arcn, nsz) < 0)
908
		return(-1);
909
910
	/*
911
	 * header + file name are aligned to 2 byte boundaries, skip if needed
912
	 */
913
	if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)
914
		return(-1);
915
916
	/*
917
	 * if not a link (or a file with no data), calculate pad size (for
918
	 * padding which follows the file data), clear the link name and return
919
	 */
920
	if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){
921
		/*
922
		 * we have a valid header (not a link)
923
		 */
924
		arcn->ln_nlen = 0;
925
		arcn->ln_name[0] = '\0';
926
		arcn->pad = BCPIO_PAD(arcn->sb.st_size);
927
		return(com_rd(arcn));
928
	}
929
930
	if ((rd_ln_nm(arcn) < 0) ||
931
	    (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0))
932
		return(-1);
933
934
	/*
935
	 * we have a valid header (with a link)
936
	 */
937
	return(com_rd(arcn));
938
}
939
940
/*
941
 * bcpio_endrd()
942
 *      no cleanup needed here, just return size of the trailer (for append)
943
 * Return:
944
 *      size of trailer header in this format
945
 */
946
947
off_t
948
bcpio_endrd(void)
949
{
950
	return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) +
951
		(BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER)))));
952
}
953
954
/*
955
 * bcpio_wr()
956
 *	copy the data in the ARCHD to buffer in old binary cpio format
957
 *	There is a real chance of field overflow with this critter. So we
958
 *	always check the conversion is ok. nobody in their right mind
959
 *	should write an archive in this format...
960
 * Return
961
 *      0 if file has data to be written after the header, 1 if file has NO
962
 *	data to write after the header, -1 if archive write failed
963
 */
964
965
int
966
bcpio_wr(ARCHD *arcn)
967
{
968
	HD_BCPIO *hd;
969
	int nsz;
970
	char hdblk[sizeof(HD_BCPIO)];
971
	off_t t_offt;
972
	int t_int;
973
	time_t t_timet;
974
975
	/*
976
	 * check and repair truncated device and inode fields in the cpio
977
	 * header
978
	 */
979
	if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0)
980
		return(-1);
981
982
	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
983
		arcn->sb.st_rdev = 0;
984
	hd = (HD_BCPIO *)hdblk;
985
986
	switch (arcn->type) {
987
	case PAX_CTG:
988
	case PAX_REG:
989
	case PAX_HRG:
990
		/*
991
		 * caller will copy file data to the archive. tell him how
992
		 * much to pad.
993
		 */
994
		arcn->pad = BCPIO_PAD(arcn->sb.st_size);
995
		hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size);
996
		hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size);
997
		hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size);
998
		hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size);
999
		t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1));
1000
		t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2)));
1001
		if (arcn->sb.st_size != t_offt) {
1002
			paxwarn(1,"File is too large for bcpio format %s",
1003
			    arcn->org_name);
1004
			return(1);
1005
		}
1006
		break;
1007
	case PAX_SLK:
1008
		/*
1009
		 * no file data for the caller to process, the file data has
1010
		 * the size of the link
1011
		 */
1012
		arcn->pad = 0L;
1013
		hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen);
1014
		hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen);
1015
		hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen);
1016
		hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen);
1017
		t_int = (int)(SHRT_EXT(hd->h_filesize_1));
1018
		t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2)));
1019
		if (arcn->ln_nlen != t_int)
1020
			goto out;
1021
		break;
1022
	default:
1023
		/*
1024
		 * no file data for the caller to process
1025
		 */
1026
		arcn->pad = 0L;
1027
		hd->h_filesize_1[0] = (char)0;
1028
		hd->h_filesize_1[1] = (char)0;
1029
		hd->h_filesize_2[0] = (char)0;
1030
		hd->h_filesize_2[1] = (char)0;
1031
		break;
1032
	}
1033
1034
	/*
1035
	 * build up the rest of the fields
1036
	 */
1037
	hd->h_magic[0] = CHR_WR_2(MAGIC);
1038
	hd->h_magic[1] = CHR_WR_3(MAGIC);
1039
	hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev);
1040
	hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev);
1041
	if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev)))
1042
		goto out;
1043
	hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino);
1044
	hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino);
1045
	if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino)))
1046
		goto out;
1047
	hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode);
1048
	hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode);
1049
	if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode)))
1050
		goto out;
1051
	hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid);
1052
	hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid);
1053
	if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid)))
1054
		goto out;
1055
	hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid);
1056
	hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid);
1057
	if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid)))
1058
		goto out;
1059
	hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink);
1060
	hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink);
1061
	if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink)))
1062
		goto out;
1063
	hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev);
1064
	hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev);
1065
	if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev)))
1066
		goto out;
1067
	if (arcn->sb.st_mtime > 0) {
1068
		hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime);
1069
		hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime);
1070
		hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime);
1071
		hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime);
1072
		t_timet = (time_t)SHRT_EXT(hd->h_mtime_1);
1073
		t_timet =  t_timet << 16 | (time_t)SHRT_EXT(hd->h_mtime_2);
1074
		if (arcn->sb.st_mtime != t_timet)
1075
			goto out;
1076
	} else {
1077
		hd->h_mtime_1[0] = hd->h_mtime_1[1] = 0;
1078
		hd->h_mtime_2[0] = hd->h_mtime_2[1] = 0;
1079
	}
1080
	nsz = arcn->nlen + 1;
1081
	hd->h_namesize[0] = CHR_WR_2(nsz);
1082
	hd->h_namesize[1] = CHR_WR_3(nsz);
1083
	if (nsz != (int)(SHRT_EXT(hd->h_namesize)))
1084
		goto out;
1085
1086
	/*
1087
	 * write the header, the file name and padding as required.
1088
	 */
1089
	if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) ||
1090
	    (wr_rdbuf(arcn->name, nsz) < 0) ||
1091
	    (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) {
1092
		paxwarn(1, "Could not write bcpio header for %s", arcn->org_name);
1093
		return(-1);
1094
	}
1095
1096
	/*
1097
	 * if we have file data, tell the caller we are done
1098
	 */
1099
	if (PAX_IS_REG(arcn->type) || (arcn->type == PAX_HRG))
1100
		return(0);
1101
1102
	/*
1103
	 * if we are not a link, tell the caller we are done, go to next file
1104
	 */
1105
	if (arcn->type != PAX_SLK)
1106
		return(1);
1107
1108
	/*
1109
	 * write the link name, tell the caller we are done.
1110
	 */
1111
	if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
1112
	    (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) {
1113
		paxwarn(1,"Could not write bcpio link name for %s",arcn->org_name);
1114
		return(-1);
1115
	}
1116
	return(1);
1117
1118
    out:
1119
	/*
1120
	 * header field is out of range
1121
	 */
1122
	paxwarn(1,"Bcpio header field is too small for file %s", arcn->org_name);
1123
	return(1);
1124
}