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