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