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