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