GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: bin/pax/cpio.c Lines: 0 382 0.0 %
Date: 2017-11-07 Branches: 0 276 0.0 %

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