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