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