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