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