]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - bin/pax/cpio.c
MFC r368207,368607:
[FreeBSD/stable/10.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  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #ifndef lint
35 #if 0
36 static char sccsid[] = "@(#)cpio.c      8.1 (Berkeley) 5/31/93";
37 #endif
38 #endif /* not lint */
39 #include <sys/cdefs.h>
40 __FBSDID("$FreeBSD$");
41
42 #include <sys/types.h>
43 #include <sys/time.h>
44 #include <sys/stat.h>
45 #include <string.h>
46 #include <stdint.h>
47 #include <stdio.h>
48 #include "pax.h"
49 #include "cpio.h"
50 #include "extern.h"
51
52 static int rd_nm(ARCHD *, int);
53 static int rd_ln_nm(ARCHD *);
54 static int com_rd(ARCHD *);
55
56 /*
57  * Routines which support the different cpio versions
58  */
59
60 static int swp_head;            /* binary cpio header byte swap */
61
62 /*
63  * Routines common to all versions of cpio
64  */
65
66 /*
67  * cpio_strd()
68  *      Fire up the hard link detection code
69  * Return:
70  *      0 if ok -1 otherwise (the return values of lnk_start())
71  */
72
73 int
74 cpio_strd(void)
75 {
76         return(lnk_start());
77 }
78
79 /*
80  * cpio_trail()
81  *      Called to determine if a header block is a valid trailer. We are
82  *      passed the block, the in_sync flag (which tells us we are in resync
83  *      mode; looking for a valid header), and cnt (which starts at zero)
84  *      which is used to count the number of empty blocks we have seen so far.
85  * Return:
86  *      0 if a valid trailer, -1 if not a valid trailer,
87  */
88
89 int
90 cpio_trail(ARCHD *arcn)
91 {
92         /*
93          * look for trailer id in file we are about to process
94          */
95         if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0))
96                 return(0);
97         return(-1);
98 }
99
100 /*
101  * com_rd()
102  *      operations common to all cpio read functions.
103  * Return:
104  *      0
105  */
106
107 static int
108 com_rd(ARCHD *arcn)
109 {
110         arcn->skip = 0;
111         arcn->pat = NULL;
112         arcn->org_name = arcn->name;
113         switch(arcn->sb.st_mode & C_IFMT) {
114         case C_ISFIFO:
115                 arcn->type = PAX_FIF;
116                 break;
117         case C_ISDIR:
118                 arcn->type = PAX_DIR;
119                 break;
120         case C_ISBLK:
121                 arcn->type = PAX_BLK;
122                 break;
123         case C_ISCHR:
124                 arcn->type = PAX_CHR;
125                 break;
126         case C_ISLNK:
127                 arcn->type = PAX_SLK;
128                 break;
129         case C_ISOCK:
130                 arcn->type = PAX_SCK;
131                 break;
132         case C_ISCTG:
133         case C_ISREG:
134         default:
135                 /*
136                  * we have file data, set up skip (pad is set in the format
137                  * specific sections)
138                  */
139                 arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG;
140                 arcn->type = PAX_REG;
141                 arcn->skip = arcn->sb.st_size;
142                 break;
143         }
144         if (chk_lnk(arcn) < 0)
145                 return(-1);
146         return(0);
147 }
148
149 /*
150  * cpio_end_wr()
151  *      write the special file with the name trailer in the proper format
152  * Return:
153  *      result of the write of the trailer from the cpio specific write func
154  */
155
156 int
157 cpio_endwr(void)
158 {
159         ARCHD last;
160
161         /*
162          * create a trailer request and call the proper format write function
163          */
164         memset(&last, 0, sizeof(last));
165         last.nlen = sizeof(TRAILER) - 1;
166         last.type = PAX_REG;
167         last.sb.st_nlink = 1;
168         (void)strcpy(last.name, TRAILER);
169         return((*frmt->wr)(&last));
170 }
171
172 /*
173  * rd_nam()
174  *      read in the file name which follows the cpio header
175  * Return:
176  *      0 if ok, -1 otherwise
177  */
178
179 static int
180 rd_nm(ARCHD *arcn, int nsz)
181 {
182         /*
183          * do not even try bogus values
184          */
185         if ((nsz == 0) || (nsz > (int)sizeof(arcn->name))) {
186                 paxwarn(1, "Cpio file name length %d is out of range", nsz);
187                 return(-1);
188         }
189
190         /*
191          * read the name and make sure it is not empty and is \0 terminated
192          */
193         if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') ||
194             (arcn->name[0] == '\0')) {
195                 paxwarn(1, "Cpio file name in header is corrupted");
196                 return(-1);
197         }
198         return(0);
199 }
200
201 /*
202  * rd_ln_nm()
203  *      read in the link name for a file with links. The link name is stored
204  *      like file data (and is NOT \0 terminated!)
205  * Return:
206  *      0 if ok, -1 otherwise
207  */
208
209 static int
210 rd_ln_nm(ARCHD *arcn)
211 {
212         /*
213          * check the length specified for bogus values
214          */
215         if ((arcn->sb.st_size == 0) ||
216             ((size_t)arcn->sb.st_size >= sizeof(arcn->ln_name))) {
217 #               ifdef NET2_STAT
218                 paxwarn(1, "Cpio link name length is invalid: %lu",
219                     arcn->sb.st_size);
220 #               else
221                 paxwarn(1, "Cpio link name length is invalid: %ju",
222                     (uintmax_t)arcn->sb.st_size);
223 #               endif
224                 return(-1);
225         }
226
227         /*
228          * read in the link name and \0 terminate it
229          */
230         if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) !=
231             (int)arcn->sb.st_size) {
232                 paxwarn(1, "Cpio link name read error");
233                 return(-1);
234         }
235         arcn->ln_nlen = arcn->sb.st_size;
236         arcn->ln_name[arcn->ln_nlen] = '\0';
237
238         /*
239          * watch out for those empty link names
240          */
241         if (arcn->ln_name[0] == '\0') {
242                 paxwarn(1, "Cpio link name is corrupt");
243                 return(-1);
244         }
245         return(0);
246 }
247
248 /*
249  * Routines common to the extended byte oriented cpio format
250  */
251
252 /*
253  * cpio_id()
254  *      determine if a block given to us is a valid extended byte oriented
255  *      cpio header
256  * Return:
257  *      0 if a valid header, -1 otherwise
258  */
259
260 int
261 cpio_id(char *blk, int size)
262 {
263         if ((size < (int)sizeof(HD_CPIO)) ||
264             (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0))
265                 return(-1);
266         return(0);
267 }
268
269 /*
270  * cpio_rd()
271  *      determine if a buffer is a byte oriented extended cpio archive entry.
272  *      convert and store the values in the ARCHD parameter.
273  * Return:
274  *      0 if a valid header, -1 otherwise.
275  */
276
277 int
278 cpio_rd(ARCHD *arcn, char *buf)
279 {
280         int nsz;
281         HD_CPIO *hd;
282
283         /*
284          * check that this is a valid header, if not return -1
285          */
286         if (cpio_id(buf, sizeof(HD_CPIO)) < 0)
287                 return(-1);
288         hd = (HD_CPIO *)buf;
289
290         /*
291          * byte oriented cpio (posix) does not have padding! extract the octal
292          * ascii fields from the header
293          */
294         arcn->pad = 0L;
295         arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT);
296         arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT);
297         arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT);
298         arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT);
299         arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT);
300         arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
301             OCT);
302         arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT);
303 #ifdef NET2_STAT
304         arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime),
305             OCT);
306 #else
307         arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime, sizeof(hd->c_mtime),
308             OCT);
309 #endif
310         arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
311 #ifdef NET2_STAT
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         HD_CPIO hdblk;
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 = &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 NET2_STAT
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((char *)&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 < (int)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 < (int)sizeof(HD_VCPIO)) ||
537             (strncmp(blk, AVCMAGIC, (int)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 #ifdef NET2_STAT
595         arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX);
596 #else
597         arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime,sizeof(hd->c_mtime),HEX);
598 #endif
599         arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
600 #ifdef NET2_STAT
601         arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,
602             sizeof(hd->c_filesize), HEX);
603 #else
604         arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,
605             sizeof(hd->c_filesize), HEX);
606 #endif
607         arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
608             HEX);
609         devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX);
610         devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX);
611         arcn->sb.st_dev = TODEV(devmajor, devminor);
612         devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX);
613         devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX);
614         arcn->sb.st_rdev = TODEV(devmajor, devminor);
615         arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX);
616
617         /*
618          * check the length of the file name, if ok read it in, return -1 if
619          * bogus
620          */
621         if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2)
622                 return(-1);
623         arcn->nlen = nsz - 1;
624         if (rd_nm(arcn, nsz) < 0)
625                 return(-1);
626
627         /*
628          * skip padding. header + filename is aligned to 4 byte boundaries
629          */
630         if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)
631                 return(-1);
632
633         /*
634          * if not a link (or a file with no data), calculate pad size (for
635          * padding which follows the file data), clear the link name and return
636          */
637         if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
638                 /*
639                  * we have a valid header (not a link)
640                  */
641                 arcn->ln_nlen = 0;
642                 arcn->ln_name[0] = '\0';
643                 arcn->pad = VCPIO_PAD(arcn->sb.st_size);
644                 return(com_rd(arcn));
645         }
646
647         /*
648          * read in the link name and skip over the padding
649          */
650         if ((rd_ln_nm(arcn) < 0) ||
651             (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0))
652                 return(-1);
653
654         /*
655          * we have a valid header (with a link)
656          */
657         return(com_rd(arcn));
658 }
659
660 /*
661  * vcpio_endrd()
662  *      no cleanup needed here, just return size of the trailer (for append)
663  * Return:
664  *      size of trailer header in this format
665  */
666
667 off_t
668 vcpio_endrd(void)
669 {
670         return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) +
671                 (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER)))));
672 }
673
674 /*
675  * crc_stwr()
676  *      start up the device mapping table, enable crc file calculation
677  * Return:
678  *      0 if ok, -1 otherwise (what dev_start() returns)
679  */
680
681 int
682 crc_stwr(void)
683 {
684         docrc = 1;
685         return(dev_start());
686 }
687
688 /*
689  * vcpio_wr()
690  *      copy the data in the ARCHD to buffer in system VR4 cpio
691  *      (with/without crc) format.
692  * Return
693  *      0 if file has data to be written after the header, 1 if file has
694  *      NO data to write after the header, -1 if archive write failed
695  */
696
697 int
698 vcpio_wr(ARCHD *arcn)
699 {
700         HD_VCPIO *hd;
701         unsigned int nsz;
702         HD_VCPIO hdblk;
703
704         /*
705          * check and repair truncated device and inode fields in the cpio
706          * header
707          */
708         if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0)
709                 return(-1);
710         nsz = arcn->nlen + 1;
711         hd = &hdblk;
712         if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
713                 arcn->sb.st_rdev = 0;
714
715         /*
716          * add the proper magic value depending whether we were asked for
717          * file data crc's, and the crc if needed.
718          */
719         if (docrc) {
720                 if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic),
721                         OCT) ||
722                     ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum),
723                         HEX))
724                         goto out;
725         } else {
726                 if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic),
727                         OCT) ||
728                     ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX))
729                         goto out;
730         }
731
732         switch(arcn->type) {
733         case PAX_CTG:
734         case PAX_REG:
735         case PAX_HRG:
736                 /*
737                  * caller will copy file data to the archive. tell him how
738                  * much to pad.
739                  */
740                 arcn->pad = VCPIO_PAD(arcn->sb.st_size);
741 #               ifdef NET2_STAT
742                 if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize,
743                     sizeof(hd->c_filesize), HEX)) {
744 #               else
745                 if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
746                     sizeof(hd->c_filesize), HEX)) {
747 #               endif
748                         paxwarn(1,"File is too large for sv4cpio format %s",
749                             arcn->org_name);
750                         return(1);
751                 }
752                 break;
753         case PAX_SLK:
754                 /*
755                  * no file data for the caller to process, the file data has
756                  * the size of the link
757                  */
758                 arcn->pad = 0L;
759                 if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
760                     sizeof(hd->c_filesize), HEX))
761                         goto out;
762                 break;
763         default:
764                 /*
765                  * no file data for the caller to process
766                  */
767                 arcn->pad = 0L;
768                 if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize),
769                     HEX))
770                         goto out;
771                 break;
772         }
773
774         /*
775          * set the other fields in the header
776          */
777         if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
778                 HEX) ||
779             ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
780                 HEX) ||
781             ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
782                 HEX) ||
783             ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
784                 HEX) ||
785             ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime),
786                 HEX) ||
787             ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
788                 HEX) ||
789             ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj),
790                 HEX) ||
791             ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min),
792                 HEX) ||
793             ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj),
794                 HEX) ||
795             ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min),
796                 HEX) ||
797             ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX))
798                 goto out;
799
800         /*
801          * write the header, the file name and padding as required.
802          */
803         if ((wr_rdbuf((char *)&hdblk, (int)sizeof(HD_VCPIO)) < 0) ||
804             (wr_rdbuf(arcn->name, (int)nsz) < 0)  ||
805             (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) {
806                 paxwarn(1,"Could not write sv4cpio header for %s",arcn->org_name);
807                 return(-1);
808         }
809
810         /*
811          * if we have file data, tell the caller we are done, copy the file
812          */
813         if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
814             (arcn->type == PAX_HRG))
815                 return(0);
816
817         /*
818          * if we are not a link, tell the caller we are done, go to next file
819          */
820         if (arcn->type != PAX_SLK)
821                 return(1);
822
823         /*
824          * write the link name, tell the caller we are done.
825          */
826         if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
827             (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) {
828                 paxwarn(1,"Could not write sv4cpio link name for %s",
829                     arcn->org_name);
830                 return(-1);
831         }
832         return(1);
833
834     out:
835         /*
836          * header field is out of range
837          */
838         paxwarn(1,"Sv4cpio header field is too small for file %s",arcn->org_name);
839         return(1);
840 }
841
842 /*
843  * Routines common to the old binary header cpio
844  */
845
846 /*
847  * bcpio_id()
848  *      determine if a block given to us is an old binary cpio header
849  *      (with/without header byte swapping)
850  * Return:
851  *      0 if a valid header, -1 otherwise
852  */
853
854 int
855 bcpio_id(char *blk, int size)
856 {
857         if (size < (int)sizeof(HD_BCPIO))
858                 return(-1);
859
860         /*
861          * check both normal and byte swapped magic cookies
862          */
863         if (((u_short)SHRT_EXT(blk)) == MAGIC)
864                 return(0);
865         if (((u_short)RSHRT_EXT(blk)) == MAGIC) {
866                 if (!swp_head)
867                         ++swp_head;
868                 return(0);
869         }
870         return(-1);
871 }
872
873 /*
874  * bcpio_rd()
875  *      determine if a buffer is an old binary archive entry. (It may have byte
876  *      swapped header) convert and store the values in the ARCHD parameter.
877  *      This is a very old header format and should not really be used.
878  * Return:
879  *      0 if a valid header, -1 otherwise.
880  */
881
882 int
883 bcpio_rd(ARCHD *arcn, char *buf)
884 {
885         HD_BCPIO *hd;
886         int nsz;
887
888         /*
889          * check the header
890          */
891         if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0)
892                 return(-1);
893
894         arcn->pad = 0L;
895         hd = (HD_BCPIO *)buf;
896         if (swp_head) {
897                 /*
898                  * header has swapped bytes on 16 bit boundaries
899                  */
900                 arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev));
901                 arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino));
902                 arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode));
903                 arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid));
904                 arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid));
905                 arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink));
906                 arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev));
907                 arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1));
908                 arcn->sb.st_mtime =  (arcn->sb.st_mtime << 16) |
909                         ((time_t)(RSHRT_EXT(hd->h_mtime_2)));
910                 arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1));
911                 arcn->sb.st_size = (arcn->sb.st_size << 16) |
912                         ((off_t)(RSHRT_EXT(hd->h_filesize_2)));
913                 nsz = (int)(RSHRT_EXT(hd->h_namesize));
914         } else {
915                 arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev));
916                 arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino));
917                 arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode));
918                 arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid));
919                 arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid));
920                 arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink));
921                 arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev));
922                 arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1));
923                 arcn->sb.st_mtime =  (arcn->sb.st_mtime << 16) |
924                         ((time_t)(SHRT_EXT(hd->h_mtime_2)));
925                 arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1));
926                 arcn->sb.st_size = (arcn->sb.st_size << 16) |
927                         ((off_t)(SHRT_EXT(hd->h_filesize_2)));
928                 nsz = (int)(SHRT_EXT(hd->h_namesize));
929         }
930         arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
931
932         /*
933          * check the file name size, if bogus give up. otherwise read the file
934          * name
935          */
936         if (nsz < 2)
937                 return(-1);
938         arcn->nlen = nsz - 1;
939         if (rd_nm(arcn, nsz) < 0)
940                 return(-1);
941
942         /*
943          * header + file name are aligned to 2 byte boundaries, skip if needed
944          */
945         if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)
946                 return(-1);
947
948         /*
949          * if not a link (or a file with no data), calculate pad size (for
950          * padding which follows the file data), clear the link name and return
951          */
952         if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){
953                 /*
954                  * we have a valid header (not a link)
955                  */
956                 arcn->ln_nlen = 0;
957                 arcn->ln_name[0] = '\0';
958                 arcn->pad = BCPIO_PAD(arcn->sb.st_size);
959                 return(com_rd(arcn));
960         }
961
962         if ((rd_ln_nm(arcn) < 0) ||
963             (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0))
964                 return(-1);
965
966         /*
967          * we have a valid header (with a link)
968          */
969         return(com_rd(arcn));
970 }
971
972 /*
973  * bcpio_endrd()
974  *      no cleanup needed here, just return size of the trailer (for append)
975  * Return:
976  *      size of trailer header in this format
977  */
978
979 off_t
980 bcpio_endrd(void)
981 {
982         return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) +
983                 (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER)))));
984 }
985
986 /*
987  * bcpio_wr()
988  *      copy the data in the ARCHD to buffer in old binary cpio format
989  *      There is a real chance of field overflow with this critter. So we
990  *      always check that the conversion is ok. nobody in their right mind
991  *      should write an archive in this format...
992  * Return
993  *      0 if file has data to be written after the header, 1 if file has NO
994  *      data to write after the header, -1 if archive write failed
995  */
996
997 int
998 bcpio_wr(ARCHD *arcn)
999 {
1000         HD_BCPIO *hd;
1001         int nsz;
1002         HD_BCPIO hdblk;
1003         off_t t_offt;
1004         int t_int;
1005         time_t t_timet;
1006
1007         /*
1008          * check and repair truncated device and inode fields in the cpio
1009          * header
1010          */
1011         if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0)
1012                 return(-1);
1013
1014         if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
1015                 arcn->sb.st_rdev = 0;
1016         hd = &hdblk;
1017
1018         switch(arcn->type) {
1019         case PAX_CTG:
1020         case PAX_REG:
1021         case PAX_HRG:
1022                 /*
1023                  * caller will copy file data to the archive. tell him how
1024                  * much to pad.
1025                  */
1026                 arcn->pad = BCPIO_PAD(arcn->sb.st_size);
1027                 hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size);
1028                 hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size);
1029                 hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size);
1030                 hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size);
1031                 t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1));
1032                 t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2)));
1033                 if (arcn->sb.st_size != t_offt) {
1034                         paxwarn(1,"File is too large for bcpio format %s",
1035                             arcn->org_name);
1036                         return(1);
1037                 }
1038                 break;
1039         case PAX_SLK:
1040                 /*
1041                  * no file data for the caller to process, the file data has
1042                  * the size of the link
1043                  */
1044                 arcn->pad = 0L;
1045                 hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen);
1046                 hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen);
1047                 hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen);
1048                 hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen);
1049                 t_int = (int)(SHRT_EXT(hd->h_filesize_1));
1050                 t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2)));
1051                 if (arcn->ln_nlen != t_int)
1052                         goto out;
1053                 break;
1054         default:
1055                 /*
1056                  * no file data for the caller to process
1057                  */
1058                 arcn->pad = 0L;
1059                 hd->h_filesize_1[0] = (char)0;
1060                 hd->h_filesize_1[1] = (char)0;
1061                 hd->h_filesize_2[0] = (char)0;
1062                 hd->h_filesize_2[1] = (char)0;
1063                 break;
1064         }
1065
1066         /*
1067          * build up the rest of the fields
1068          */
1069         hd->h_magic[0] = CHR_WR_2(MAGIC);
1070         hd->h_magic[1] = CHR_WR_3(MAGIC);
1071         hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev);
1072         hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev);
1073         if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev)))
1074                 goto out;
1075         hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino);
1076         hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino);
1077         if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino)))
1078                 goto out;
1079         hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode);
1080         hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode);
1081         if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode)))
1082                 goto out;
1083         hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid);
1084         hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid);
1085         if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid)))
1086                 goto out;
1087         hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid);
1088         hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid);
1089         if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid)))
1090                 goto out;
1091         hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink);
1092         hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink);
1093         if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink)))
1094                 goto out;
1095         hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev);
1096         hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev);
1097         if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev)))
1098                 goto out;
1099         hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime);
1100         hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime);
1101         hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime);
1102         hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime);
1103         t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1));
1104         t_timet =  (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2)));
1105         if (arcn->sb.st_mtime != t_timet)
1106                 goto out;
1107         nsz = arcn->nlen + 1;
1108         hd->h_namesize[0] = CHR_WR_2(nsz);
1109         hd->h_namesize[1] = CHR_WR_3(nsz);
1110         if (nsz != (int)(SHRT_EXT(hd->h_namesize)))
1111                 goto out;
1112
1113         /*
1114          * write the header, the file name and padding as required.
1115          */
1116         if ((wr_rdbuf((char *)&hdblk, (int)sizeof(HD_BCPIO)) < 0) ||
1117             (wr_rdbuf(arcn->name, nsz) < 0) ||
1118             (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) {
1119                 paxwarn(1, "Could not write bcpio header for %s", arcn->org_name);
1120                 return(-1);
1121         }
1122
1123         /*
1124          * if we have file data, tell the caller we are done
1125          */
1126         if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
1127             (arcn->type == PAX_HRG))
1128                 return(0);
1129
1130         /*
1131          * if we are not a link, tell the caller we are done, go to next file
1132          */
1133         if (arcn->type != PAX_SLK)
1134                 return(1);
1135
1136         /*
1137          * write the link name, tell the caller we are done.
1138          */
1139         if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
1140             (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) {
1141                 paxwarn(1,"Could not write bcpio link name for %s",arcn->org_name);
1142                 return(-1);
1143         }
1144         return(1);
1145
1146     out:
1147         /*
1148          * header field is out of range
1149          */
1150         paxwarn(1,"Bcpio header field is too small for file %s", arcn->org_name);
1151         return(1);
1152 }