Merge from vendor branch FILE:
[dragonfly.git] / bin / pax / cpio.c
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  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by the University of
20  *      California, Berkeley and its contributors.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  * @(#)cpio.c   8.1 (Berkeley) 5/31/93
38  * $FreeBSD: src/bin/pax/cpio.c,v 1.12.2.1 2001/08/01 05:03:11 obrien Exp $
39  * $DragonFly: src/bin/pax/cpio.c,v 1.8 2006/09/27 21:58:08 pavalos Exp $
40  */
41
42 #include <sys/types.h>
43 #include <sys/time.h>
44 #include <sys/stat.h>
45 #include <string.h>
46 #include <stdio.h>
47 #include <unistd.h>
48 #include <stdlib.h>
49 #include "pax.h"
50 #include "cpio.h"
51 #include "extern.h"
52
53 static int rd_nm (ARCHD *, int);
54 static int rd_ln_nm (ARCHD *);
55 static int com_rd (ARCHD *);
56
57 /*
58  * Routines which support the different cpio versions
59  */
60
61 static int swp_head;            /* binary cpio header byte swap */
62
63 /*
64  * Routines common to all versions of cpio
65  */
66
67 /*
68  * cpio_strd()
69  *      Fire up the hard link detection code
70  * Return:
71  *      0 if ok -1 otherwise (the return values of lnk_start())
72  */
73
74 int
75 cpio_strd(void)
76 {
77         return(lnk_start());
78 }
79
80 /*
81  * cpio_trail()
82  *      Called to determine if a header block is a valid trailer. We are
83  *      passed the block, the in_sync flag (which tells us we are in resync
84  *      mode; looking for a valid header), and cnt (which starts at zero)
85  *      which is used to count the number of empty blocks we have seen so far.
86  * Return:
87  *      0 if a valid trailer, -1 if not a valid trailer,
88  */
89
90 int
91 cpio_trail(ARCHD *arcn)
92 {
93         /*
94          * look for trailer id in file we are about to process
95          */
96         if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0))
97                 return(0);
98         return(-1);
99 }
100
101 /*
102  * com_rd()
103  *      operations common to all cpio read functions.
104  * Return:
105  *      0
106  */
107
108 static int
109 com_rd(ARCHD *arcn)
110 {
111         arcn->skip = 0;
112         arcn->pat = NULL;
113         arcn->org_name = arcn->name;
114         switch(arcn->sb.st_mode & C_IFMT) {
115         case C_ISFIFO:
116                 arcn->type = PAX_FIF;
117                 break;
118         case C_ISDIR:
119                 arcn->type = PAX_DIR;
120                 break;
121         case C_ISBLK:
122                 arcn->type = PAX_BLK;
123                 break;
124         case C_ISCHR:
125                 arcn->type = PAX_CHR;
126                 break;
127         case C_ISLNK:
128                 arcn->type = PAX_SLK;
129                 break;
130         case C_ISOCK:
131                 arcn->type = PAX_SCK;
132                 break;
133         case C_ISCTG:
134         case C_ISREG:
135         default:
136                 /*
137                  * we have file data, set up skip (pad is set in the format
138                  * specific sections)
139                  */
140                 arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG;
141                 arcn->type = PAX_REG;
142                 arcn->skip = arcn->sb.st_size;
143                 break;
144         }
145         if (chk_lnk(arcn) < 0)
146                 return(-1);
147         return(0);
148 }
149
150 /*
151  * cpio_end_wr()
152  *      write the special file with the name trailer in the proper format
153  * Return:
154  *      result of the write of the trailer from the cpio specific write func
155  */
156
157 int
158 cpio_endwr(void)
159 {
160         ARCHD last;
161
162         /*
163          * create a trailer request and call the proper format write function
164          */
165         memset(&last, 0, sizeof(last));
166         last.nlen = sizeof(TRAILER) - 1;
167         last.type = PAX_REG;
168         last.sb.st_nlink = 1;
169         strcpy(last.name, TRAILER);
170         return((*frmt->wr)(&last));
171 }
172
173 /*
174  * rd_nam()
175  *      read in the file name which follows the cpio header
176  * Return:
177  *      0 if ok, -1 otherwise
178  */
179
180 static int
181 rd_nm(ARCHD *arcn, int nsz)
182 {
183         /*
184          * do not even try bogus values
185          */
186         if ((nsz == 0) || (nsz > sizeof(arcn->name))) {
187                 paxwarn(1, "Cpio file name length %d is out of range", nsz);
188                 return(-1);
189         }
190
191         /*
192          * read the name and make sure it is not empty and is \0 terminated
193          */
194         if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') ||
195             (arcn->name[0] == '\0')) {
196                 paxwarn(1, "Cpio file name in header is corrupted");
197                 return(-1);
198         }
199         return(0);
200 }
201
202 /*
203  * rd_ln_nm()
204  *      read in the link name for a file with links. The link name is stored
205  *      like file data (and is NOT \0 terminated!)
206  * Return:
207  *      0 if ok, -1 otherwise
208  */
209
210 static int
211 rd_ln_nm(ARCHD *arcn)
212 {
213         /*
214          * check the length specified for bogus values
215          */
216         if ((arcn->sb.st_size == 0) ||
217             (arcn->sb.st_size >= sizeof(arcn->ln_name))) {
218                 paxwarn(1, "Cpio link name length is invalid: %qu",
219                     arcn->sb.st_size);
220                 return(-1);
221         }
222
223         /*
224          * read in the link name and \0 terminate it
225          */
226         if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) !=
227             (int)arcn->sb.st_size) {
228                 paxwarn(1, "Cpio link name read error");
229                 return(-1);
230         }
231         arcn->ln_nlen = arcn->sb.st_size;
232         arcn->ln_name[arcn->ln_nlen] = '\0';
233
234         /*
235          * watch out for those empty link names
236          */
237         if (arcn->ln_name[0] == '\0') {
238                 paxwarn(1, "Cpio link name is corrupt");
239                 return(-1);
240         }
241         return(0);
242 }
243
244 /*
245  * Routines common to the extended byte oriented cpio format
246  */
247
248 /*
249  * cpio_id()
250  *      determine if a block given to us is a valid extended byte oriented
251  *      cpio header
252  * Return:
253  *      0 if a valid header, -1 otherwise
254  */
255
256 int
257 cpio_id(char *blk, int size)
258 {
259         if ((size < sizeof(HD_CPIO)) ||
260             (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0))
261                 return(-1);
262         return(0);
263 }
264
265 /*
266  * cpio_rd()
267  *      determine if a buffer is a byte oriented extended cpio archive entry.
268  *      convert and store the values in the ARCHD parameter.
269  * Return:
270  *      0 if a valid header, -1 otherwise.
271  */
272
273 int
274 cpio_rd(ARCHD *arcn, char *buf)
275 {
276         int nsz;
277         HD_CPIO *hd;
278
279         /*
280          * check that this is a valid header, if not return -1
281          */
282         if (cpio_id(buf, sizeof(HD_CPIO)) < 0)
283                 return(-1);
284         hd = (HD_CPIO *)buf;
285
286         /*
287          * byte oriented cpio (posix) does not have padding! extract the octal
288          * ascii fields from the header
289          */
290         arcn->pad = 0L;
291         arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT);
292         arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT);
293         arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT);
294         arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT);
295         arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT);
296         arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
297             OCT);
298         arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT);
299         arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime),
300             OCT);
301         arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
302         arcn->sb.st_size = (off_t)asc_uqd(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((off_t)(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, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0)
383                 return(-1);
384
385         arcn->pad = 0L;
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 (uqd_asc((u_quad_t)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((u_long)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((u_long)0, hd->c_filesize, sizeof(hd->c_filesize),
418                      OCT))
419                         goto out;
420                 break;
421         }
422
423         /*
424          * copy the values to the header using octal ascii
425          */
426         if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) ||
427             ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev),
428                 OCT) ||
429             ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
430                 OCT) ||
431             ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
432                 OCT) ||
433             ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
434                 OCT) ||
435             ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
436                 OCT) ||
437             ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
438                  OCT) ||
439             ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev),
440                 OCT) ||
441             ul_asc((u_long)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime),
442                 OCT) ||
443             ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT))
444                 goto out;
445
446         /*
447          * write the file name to the archive
448          */
449         if ((wr_rdbuf(hdblk, (int)sizeof(HD_CPIO)) < 0) ||
450             (wr_rdbuf(arcn->name, nsz) < 0)) {
451                 paxwarn(1, "Unable to write cpio header for %s", arcn->org_name);
452                 return(-1);
453         }
454
455         /*
456          * if this file has data, we are done. The caller will write the file
457          * data, if we are link tell caller we are done, go to next file
458          */
459         if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
460             (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_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
577         arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,
578             sizeof(hd->c_filesize), HEX);
579         arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
580             HEX);
581         devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX);
582         devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX);
583         arcn->sb.st_dev = TODEV(devmajor, devminor);
584         devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX);
585         devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX);
586         arcn->sb.st_rdev = TODEV(devmajor, devminor);
587         arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX);
588
589         /*
590          * check the length of the file name, if ok read it in, return -1 if
591          * bogus
592          */
593         if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2)
594                 return(-1);
595         arcn->nlen = nsz - 1;
596         if (rd_nm(arcn, nsz) < 0)
597                 return(-1);
598
599         /*
600          * skip padding. header + filename is aligned to 4 byte boundaries
601          */
602         if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)
603                 return(-1);
604
605         /*
606          * if not a link (or a file with no data), calculate pad size (for
607          * padding which follows the file data), clear the link name and return
608          */
609         if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
610                 /*
611                  * we have a valid header (not a link)
612                  */
613                 arcn->ln_nlen = 0;
614                 arcn->ln_name[0] = '\0';
615                 arcn->pad = VCPIO_PAD(arcn->sb.st_size);
616                 return(com_rd(arcn));
617         }
618
619         /*
620          * read in the link name and skip over the padding
621          */
622         if ((rd_ln_nm(arcn) < 0) ||
623             (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0))
624                 return(-1);
625
626         /*
627          * we have a valid header (with a link)
628          */
629         return(com_rd(arcn));
630 }
631
632 /*
633  * vcpio_endrd()
634  *      no cleanup needed here, just return size of the trailer (for append)
635  * Return:
636  *      size of trailer header in this format
637  */
638
639 off_t
640 vcpio_endrd(void)
641 {
642         return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) +
643                 (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER)))));
644 }
645
646 /*
647  * crc_stwr()
648  *      start up the device mapping table, enable crc file calculation
649  * Return:
650  *      0 if ok, -1 otherwise (what dev_start() returns)
651  */
652
653 int
654 crc_stwr(void)
655 {
656         docrc = 1;
657         return(dev_start());
658 }
659
660 /*
661  * vcpio_wr()
662  *      copy the data in the ARCHD to buffer in system VR4 cpio
663  *      (with/without crc) format.
664  * Return
665  *      0 if file has data to be written after the header, 1 if file has
666  *      NO data to write after the header, -1 if archive write failed
667  */
668
669 int
670 vcpio_wr(ARCHD *arcn)
671 {
672         HD_VCPIO *hd;
673         unsigned int nsz;
674         char hdblk[sizeof(HD_VCPIO)];
675
676         /*
677          * check and repair truncated device and inode fields in the cpio
678          * header
679          */
680         if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0)
681                 return(-1);
682         nsz = arcn->nlen + 1;
683         hd = (HD_VCPIO *)hdblk;
684         if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
685                 arcn->sb.st_rdev = 0;
686
687         /*
688          * add the proper magic value depending whether we were asked for
689          * file data crc's, and the crc if needed.
690          */
691         if (docrc) {
692                 if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic),
693                         OCT) ||
694                     ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum),
695                         HEX))
696                         goto out;
697         } else {
698                 if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic),
699                         OCT) ||
700                     ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX))
701                         goto out;
702         }
703
704         switch(arcn->type) {
705         case PAX_CTG:
706         case PAX_REG:
707         case PAX_HRG:
708                 /*
709                  * caller will copy file data to the archive. tell him how
710                  * much to pad.
711                  */
712                 arcn->pad = VCPIO_PAD(arcn->sb.st_size);
713                 if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
714                     sizeof(hd->c_filesize), HEX)) {
715                         paxwarn(1,"File is too large for sv4cpio format %s",
716                             arcn->org_name);
717                         return(1);
718                 }
719                 break;
720         case PAX_SLK:
721                 /*
722                  * no file data for the caller to process, the file data has
723                  * the size of the link
724                  */
725                 arcn->pad = 0L;
726                 if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
727                     sizeof(hd->c_filesize), HEX))
728                         goto out;
729                 break;
730         default:
731                 /*
732                  * no file data for the caller to process
733                  */
734                 arcn->pad = 0L;
735                 if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize),
736                     HEX))
737                         goto out;
738                 break;
739         }
740
741         /*
742          * set the other fields in the header
743          */
744         if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
745                 HEX) ||
746             ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
747                 HEX) ||
748             ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
749                 HEX) ||
750             ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
751                 HEX) ||
752             ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime),
753                 HEX) ||
754             ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
755                 HEX) ||
756             ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj),
757                 HEX) ||
758             ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min),
759                 HEX) ||
760             ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj),
761                 HEX) ||
762             ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min),
763                 HEX) ||
764             ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX))
765                 goto out;
766
767         /*
768          * write the header, the file name and padding as required.
769          */
770         if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) ||
771             (wr_rdbuf(arcn->name, (int)nsz) < 0)  ||
772             (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) {
773                 paxwarn(1,"Could not write sv4cpio header for %s",arcn->org_name);
774                 return(-1);
775         }
776
777         /*
778          * if we have file data, tell the caller we are done, copy the file
779          */
780         if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
781             (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_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
898
899         /*
900          * check the file name size, if bogus give up. otherwise read the file
901          * name
902          */
903         if (nsz < 2)
904                 return(-1);
905         arcn->nlen = nsz - 1;
906         if (rd_nm(arcn, nsz) < 0)
907                 return(-1);
908
909         /*
910          * header + file name are aligned to 2 byte boundaries, skip if needed
911          */
912         if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)
913                 return(-1);
914
915         /*
916          * if not a link (or a file with no data), calculate pad size (for
917          * padding which follows the file data), clear the link name and return
918          */
919         if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){
920                 /*
921                  * we have a valid header (not a link)
922                  */
923                 arcn->ln_nlen = 0;
924                 arcn->ln_name[0] = '\0';
925                 arcn->pad = BCPIO_PAD(arcn->sb.st_size);
926                 return(com_rd(arcn));
927         }
928
929         if ((rd_ln_nm(arcn) < 0) ||
930             (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0))
931                 return(-1);
932
933         /*
934          * we have a valid header (with a link)
935          */
936         return(com_rd(arcn));
937 }
938
939 /*
940  * bcpio_endrd()
941  *      no cleanup needed here, just return size of the trailer (for append)
942  * Return:
943  *      size of trailer header in this format
944  */
945
946 off_t
947 bcpio_endrd(void)
948 {
949         return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) +
950                 (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER)))));
951 }
952
953 /*
954  * bcpio_wr()
955  *      copy the data in the ARCHD to buffer in old binary cpio format
956  *      There is a real chance of field overflow with this critter. So we
957  *      always check the conversion is ok. nobody in their right mind
958  *      should write an archive in this format...
959  * Return
960  *      0 if file has data to be written after the header, 1 if file has NO
961  *      data to write after the header, -1 if archive write failed
962  */
963
964 int
965 bcpio_wr(ARCHD *arcn)
966 {
967         HD_BCPIO *hd;
968         int nsz;
969         char hdblk[sizeof(HD_BCPIO)];
970         off_t t_offt;
971         int t_int;
972         time_t t_timet;
973
974         /*
975          * check and repair truncated device and inode fields in the cpio
976          * header
977          */
978         if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0)
979                 return(-1);
980
981         if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
982                 arcn->sb.st_rdev = 0;
983         hd = (HD_BCPIO *)hdblk;
984
985         switch(arcn->type) {
986         case PAX_CTG:
987         case PAX_REG:
988         case PAX_HRG:
989                 /*
990                  * caller will copy file data to the archive. tell him how
991                  * much to pad.
992                  */
993                 arcn->pad = BCPIO_PAD(arcn->sb.st_size);
994                 hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size);
995                 hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size);
996                 hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size);
997                 hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size);
998                 t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1));
999                 t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2)));
1000                 if (arcn->sb.st_size != t_offt) {
1001                         paxwarn(1,"File is too large for bcpio format %s",
1002                             arcn->org_name);
1003                         return(1);
1004                 }
1005                 break;
1006         case PAX_SLK:
1007                 /*
1008                  * no file data for the caller to process, the file data has
1009                  * the size of the link
1010                  */
1011                 arcn->pad = 0L;
1012                 hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen);
1013                 hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen);
1014                 hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen);
1015                 hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen);
1016                 t_int = (int)(SHRT_EXT(hd->h_filesize_1));
1017                 t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2)));
1018                 if (arcn->ln_nlen != t_int)
1019                         goto out;
1020                 break;
1021         default:
1022                 /*
1023                  * no file data for the caller to process
1024                  */
1025                 arcn->pad = 0L;
1026                 hd->h_filesize_1[0] = (char)0;
1027                 hd->h_filesize_1[1] = (char)0;
1028                 hd->h_filesize_2[0] = (char)0;
1029                 hd->h_filesize_2[1] = (char)0;
1030                 break;
1031         }
1032
1033         /*
1034          * build up the rest of the fields
1035          */
1036         hd->h_magic[0] = CHR_WR_2(MAGIC);
1037         hd->h_magic[1] = CHR_WR_3(MAGIC);
1038         hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev);
1039         hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev);
1040         if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev)))
1041                 goto out;
1042         hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino);
1043         hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino);
1044         if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino)))
1045                 goto out;
1046         hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode);
1047         hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode);
1048         if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode)))
1049                 goto out;
1050         hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid);
1051         hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid);
1052         if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid)))
1053                 goto out;
1054         hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid);
1055         hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid);
1056         if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid)))
1057                 goto out;
1058         hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink);
1059         hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink);
1060         if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink)))
1061                 goto out;
1062         hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev);
1063         hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev);
1064         if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev)))
1065                 goto out;
1066         hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime);
1067         hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime);
1068         hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime);
1069         hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime);
1070         t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1));
1071         t_timet =  (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2)));
1072         if (arcn->sb.st_mtime != t_timet)
1073                 goto out;
1074         nsz = arcn->nlen + 1;
1075         hd->h_namesize[0] = CHR_WR_2(nsz);
1076         hd->h_namesize[1] = CHR_WR_3(nsz);
1077         if (nsz != (int)(SHRT_EXT(hd->h_namesize)))
1078                 goto out;
1079
1080         /*
1081          * write the header, the file name and padding as required.
1082          */
1083         if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) ||
1084             (wr_rdbuf(arcn->name, nsz) < 0) ||
1085             (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) {
1086                 paxwarn(1, "Could not write bcpio header for %s", arcn->org_name);
1087                 return(-1);
1088         }
1089
1090         /*
1091          * if we have file data, tell the caller we are done
1092          */
1093         if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
1094             (arcn->type == PAX_HRG))
1095                 return(0);
1096
1097         /*
1098          * if we are not a link, tell the caller we are done, go to next file
1099          */
1100         if (arcn->type != PAX_SLK)
1101                 return(1);
1102
1103         /*
1104          * write the link name, tell the caller we are done.
1105          */
1106         if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
1107             (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) {
1108                 paxwarn(1,"Could not write bcpio link name for %s",arcn->org_name);
1109                 return(-1);
1110         }
1111         return(1);
1112
1113     out:
1114         /*
1115          * header field is out of range
1116          */
1117         paxwarn(1,"Bcpio header field is too small for file %s", arcn->org_name);
1118         return(1);
1119 }