1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1992 Keith Muller.
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Keith Muller of the University of California, San Diego.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94";
39 #endif
40 #endif /* not lint */
41 #include <sys/cdefs.h>
42 #include <sys/types.h>
43 #include <sys/time.h>
44 #include <sys/stat.h>
45 #include <string.h>
46 #include <stdio.h>
47 #include "pax.h"
48 #include "extern.h"
49 #include "tar.h"
50
51 /*
52 * Routines for reading, writing and header identify of various versions of tar
53 */
54
55 static u_long tar_chksm(char *, int);
56 static char *name_split(char *, int);
57 static int ul_oct(u_long, char *, int, int);
58 static int uqd_oct(u_quad_t, char *, int, int);
59
60 /*
61 * Routines common to all versions of tar
62 */
63
64 static int tar_nodir; /* do not write dirs under old tar */
65
66 /*
67 * tar_endwr()
68 * add the tar trailer of two null blocks
69 * Return:
70 * 0 if ok, -1 otherwise (what wr_skip returns)
71 */
72
73 int
tar_endwr(void)74 tar_endwr(void)
75 {
76 return(wr_skip((off_t)(NULLCNT*BLKMULT)));
77 }
78
79 /*
80 * tar_endrd()
81 * no cleanup needed here, just return size of trailer (for append)
82 * Return:
83 * size of trailer (2 * BLKMULT)
84 */
85
86 off_t
tar_endrd(void)87 tar_endrd(void)
88 {
89 return((off_t)(NULLCNT*BLKMULT));
90 }
91
92 /*
93 * tar_trail()
94 * Called to determine if a header block is a valid trailer. We are passed
95 * the block, the in_sync flag (which tells us we are in resync mode;
96 * looking for a valid header), and cnt (which starts at zero) which is
97 * used to count the number of empty blocks we have seen so far.
98 * Return:
99 * 0 if a valid trailer, -1 if not a valid trailer, or 1 if the block
100 * could never contain a header.
101 */
102
103 int
tar_trail(char * buf,int in_resync,int * cnt)104 tar_trail(char *buf, int in_resync, int *cnt)
105 {
106 int i;
107
108 /*
109 * look for all zero, trailer is two consecutive blocks of zero
110 */
111 for (i = 0; i < BLKMULT; ++i) {
112 if (buf[i] != '\0')
113 break;
114 }
115
116 /*
117 * if not all zero it is not a trailer, but MIGHT be a header.
118 */
119 if (i != BLKMULT)
120 return(-1);
121
122 /*
123 * When given a zero block, we must be careful!
124 * If we are not in resync mode, check for the trailer. Have to watch
125 * out that we do not mis-identify file data as the trailer, so we do
126 * NOT try to id a trailer during resync mode. During resync mode we
127 * might as well throw this block out since a valid header can NEVER be
128 * a block of all 0 (we must have a valid file name).
129 */
130 if (!in_resync && (++*cnt >= NULLCNT))
131 return(0);
132 return(1);
133 }
134
135 /*
136 * ul_oct()
137 * convert an unsigned long to an octal string. many oddball field
138 * termination characters are used by the various versions of tar in the
139 * different fields. term selects which kind to use. str is '0' padded
140 * at the front to len. we are unable to use only one format as many old
141 * tar readers are very cranky about this.
142 * Return:
143 * 0 if the number fit into the string, -1 otherwise
144 */
145
146 static int
ul_oct(u_long val,char * str,int len,int term)147 ul_oct(u_long val, char *str, int len, int term)
148 {
149 char *pt;
150
151 /*
152 * term selects the appropriate character(s) for the end of the string
153 */
154 pt = str + len - 1;
155 switch(term) {
156 case 3:
157 *pt-- = '\0';
158 break;
159 case 2:
160 *pt-- = ' ';
161 *pt-- = '\0';
162 break;
163 case 1:
164 *pt-- = ' ';
165 break;
166 case 0:
167 default:
168 *pt-- = '\0';
169 *pt-- = ' ';
170 break;
171 }
172
173 /*
174 * convert and blank pad if there is space
175 */
176 while (pt >= str) {
177 *pt-- = '0' + (char)(val & 0x7);
178 if ((val = val >> 3) == (u_long)0)
179 break;
180 }
181
182 while (pt >= str)
183 *pt-- = '0';
184 if (val != (u_long)0)
185 return(-1);
186 return(0);
187 }
188
189 /*
190 * uqd_oct()
191 * convert an u_quad_t to an octal string. one of many oddball field
192 * termination characters are used by the various versions of tar in the
193 * different fields. term selects which kind to use. str is '0' padded
194 * at the front to len. we are unable to use only one format as many old
195 * tar readers are very cranky about this.
196 * Return:
197 * 0 if the number fit into the string, -1 otherwise
198 */
199
200 static int
uqd_oct(u_quad_t val,char * str,int len,int term)201 uqd_oct(u_quad_t val, char *str, int len, int term)
202 {
203 char *pt;
204
205 /*
206 * term selects the appropriate character(s) for the end of the string
207 */
208 pt = str + len - 1;
209 switch(term) {
210 case 3:
211 *pt-- = '\0';
212 break;
213 case 2:
214 *pt-- = ' ';
215 *pt-- = '\0';
216 break;
217 case 1:
218 *pt-- = ' ';
219 break;
220 case 0:
221 default:
222 *pt-- = '\0';
223 *pt-- = ' ';
224 break;
225 }
226
227 /*
228 * convert and blank pad if there is space
229 */
230 while (pt >= str) {
231 *pt-- = '0' + (char)(val & 0x7);
232 if ((val = val >> 3) == 0)
233 break;
234 }
235
236 while (pt >= str)
237 *pt-- = '0';
238 if (val != (u_quad_t)0)
239 return(-1);
240 return(0);
241 }
242
243 /*
244 * tar_chksm()
245 * calculate the checksum for a tar block counting the checksum field as
246 * all blanks (BLNKSUM is that value pre-calculated, the sum of 8 blanks).
247 * NOTE: we use len to short circuit summing 0's on write since we ALWAYS
248 * pad headers with 0.
249 * Return:
250 * unsigned long checksum
251 */
252
253 static u_long
tar_chksm(char * blk,int len)254 tar_chksm(char *blk, int len)
255 {
256 char *stop;
257 char *pt;
258 u_long chksm = BLNKSUM; /* initial value is checksum field sum */
259
260 /*
261 * add the part of the block before the checksum field
262 */
263 pt = blk;
264 stop = blk + CHK_OFFSET;
265 while (pt < stop)
266 chksm += (u_long)(*pt++ & 0xff);
267 /*
268 * move past the checksum field and keep going, spec counts the
269 * checksum field as the sum of 8 blanks (which is pre-computed as
270 * BLNKSUM).
271 * ASSUMED: len is greater than CHK_OFFSET. (len is where our 0 padding
272 * starts, no point in summing zero's)
273 */
274 pt += CHK_LEN;
275 stop = blk + len;
276 while (pt < stop)
277 chksm += (u_long)(*pt++ & 0xff);
278 return(chksm);
279 }
280
281 /*
282 * Routines for old BSD style tar (also made portable to sysV tar)
283 */
284
285 /*
286 * tar_id()
287 * determine if a block given to us is a valid tar header (and not a USTAR
288 * header). We have to be on the lookout for those pesky blocks of all
289 * zero's.
290 * Return:
291 * 0 if a tar header, -1 otherwise
292 */
293
294 int
tar_id(char * blk,int size)295 tar_id(char *blk, int size)
296 {
297 HD_TAR *hd;
298 HD_USTAR *uhd;
299
300 if (size < BLKMULT)
301 return(-1);
302 hd = (HD_TAR *)blk;
303 uhd = (HD_USTAR *)blk;
304
305 /*
306 * check for block of zero's first, a simple and fast test, then make
307 * sure this is not a ustar header by looking for the ustar magic
308 * cookie. We should use TMAGLEN, but some USTAR archive programs are
309 * wrong and create archives missing the \0. Last we check the
310 * checksum. If this is ok we have to assume it is a valid header.
311 */
312 if (hd->name[0] == '\0')
313 return(-1);
314 if (strncmp(uhd->magic, TMAGIC, TMAGLEN - 1) == 0)
315 return(-1);
316 if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT))
317 return(-1);
318 return(0);
319 }
320
321 /*
322 * tar_opt()
323 * handle tar format specific -o options
324 * Return:
325 * 0 if ok -1 otherwise
326 */
327
328 int
tar_opt(void)329 tar_opt(void)
330 {
331 OPLIST *opt;
332
333 while ((opt = opt_next()) != NULL) {
334 if (strcmp(opt->name, TAR_OPTION) ||
335 strcmp(opt->value, TAR_NODIR)) {
336 paxwarn(1, "Unknown tar format -o option/value pair %s=%s",
337 opt->name, opt->value);
338 paxwarn(1,"%s=%s is the only supported tar format option",
339 TAR_OPTION, TAR_NODIR);
340 return(-1);
341 }
342
343 /*
344 * we only support one option, and only when writing
345 */
346 if ((act != APPND) && (act != ARCHIVE)) {
347 paxwarn(1, "%s=%s is only supported when writing.",
348 opt->name, opt->value);
349 return(-1);
350 }
351 tar_nodir = 1;
352 }
353 return(0);
354 }
355
356
357 /*
358 * tar_rd()
359 * extract the values out of block already determined to be a tar header.
360 * store the values in the ARCHD parameter.
361 * Return:
362 * 0
363 */
364
365 int
tar_rd(ARCHD * arcn,char * buf)366 tar_rd(ARCHD *arcn, char *buf)
367 {
368 HD_TAR *hd;
369 char *pt;
370
371 /*
372 * we only get proper sized buffers passed to us
373 */
374 if (tar_id(buf, BLKMULT) < 0)
375 return(-1);
376 memset(arcn, 0, sizeof *arcn);
377 arcn->org_name = arcn->name;
378 arcn->sb.st_nlink = 1;
379
380 /*
381 * copy out the name and values in the stat buffer
382 */
383 hd = (HD_TAR *)buf;
384 /*
385 * old tar format specifies the name always be null-terminated,
386 * but let's be robust to broken archives.
387 * the same applies to handling links below.
388 */
389 arcn->nlen = l_strncpy(arcn->name, hd->name,
390 MIN(sizeof(hd->name), sizeof(arcn->name)) - 1);
391 arcn->name[arcn->nlen] = '\0';
392 arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode,sizeof(hd->mode),OCT) &
393 0xfff);
394 arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT);
395 arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT);
396 arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT);
397 arcn->sb.st_mtime = (time_t)asc_uqd(hd->mtime, sizeof(hd->mtime), OCT);
398 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
399
400 /*
401 * have to look at the last character, it may be a '/' and that is used
402 * to encode this as a directory
403 */
404 pt = &(arcn->name[arcn->nlen - 1]);
405 switch(hd->linkflag) {
406 case SYMTYPE:
407 /*
408 * symbolic link, need to get the link name and set the type in
409 * the st_mode so -v printing will look correct.
410 */
411 arcn->type = PAX_SLK;
412 arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
413 MIN(sizeof(hd->linkname), sizeof(arcn->ln_name)) - 1);
414 arcn->ln_name[arcn->ln_nlen] = '\0';
415 arcn->sb.st_mode |= S_IFLNK;
416 break;
417 case LNKTYPE:
418 /*
419 * hard link, need to get the link name, set the type in the
420 * st_mode and st_nlink so -v printing will look better.
421 */
422 arcn->type = PAX_HLK;
423 arcn->sb.st_nlink = 2;
424 arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
425 MIN(sizeof(hd->linkname), sizeof(arcn->ln_name)) - 1);
426 arcn->ln_name[arcn->ln_nlen] = '\0';
427
428 /*
429 * no idea of what type this thing really points at, but
430 * we set something for printing only.
431 */
432 arcn->sb.st_mode |= S_IFREG;
433 break;
434 case DIRTYPE:
435 /*
436 * It is a directory, set the mode for -v printing
437 */
438 arcn->type = PAX_DIR;
439 arcn->sb.st_mode |= S_IFDIR;
440 arcn->sb.st_nlink = 2;
441 break;
442 case AREGTYPE:
443 case REGTYPE:
444 default:
445 /*
446 * If we have a trailing / this is a directory and NOT a file.
447 */
448 if (*pt == '/') {
449 /*
450 * it is a directory, set the mode for -v printing
451 */
452 arcn->type = PAX_DIR;
453 arcn->sb.st_mode |= S_IFDIR;
454 arcn->sb.st_nlink = 2;
455 } else {
456 /*
457 * have a file that will be followed by data. Set the
458 * skip value to the size field and calculate the size
459 * of the padding.
460 */
461 arcn->type = PAX_REG;
462 arcn->sb.st_mode |= S_IFREG;
463 arcn->pad = TAR_PAD(arcn->sb.st_size);
464 arcn->skip = arcn->sb.st_size;
465 }
466 break;
467 }
468
469 /*
470 * strip off any trailing slash.
471 */
472 if (*pt == '/') {
473 *pt = '\0';
474 --arcn->nlen;
475 }
476 return(0);
477 }
478
479 /*
480 * tar_wr()
481 * write a tar header for the file specified in the ARCHD to the archive.
482 * Have to check for file types that cannot be stored and file names that
483 * are too long. Be careful of the term (last arg) to ul_oct, each field
484 * of tar has it own spec for the termination character(s).
485 * ASSUMED: space after header in header block is zero filled
486 * Return:
487 * 0 if file has data to be written after the header, 1 if file has NO
488 * data to write after the header, -1 if archive write failed
489 */
490
491 int
tar_wr(ARCHD * arcn)492 tar_wr(ARCHD *arcn)
493 {
494 HD_TAR *hd;
495 int len;
496 HD_TAR hdblk;
497
498 /*
499 * check for those file system types which tar cannot store
500 */
501 switch(arcn->type) {
502 case PAX_DIR:
503 /*
504 * user asked that dirs not be written to the archive
505 */
506 if (tar_nodir)
507 return(1);
508 break;
509 case PAX_CHR:
510 paxwarn(1, "Tar cannot archive a character device %s",
511 arcn->org_name);
512 return(1);
513 case PAX_BLK:
514 paxwarn(1, "Tar cannot archive a block device %s", arcn->org_name);
515 return(1);
516 case PAX_SCK:
517 paxwarn(1, "Tar cannot archive a socket %s", arcn->org_name);
518 return(1);
519 case PAX_FIF:
520 paxwarn(1, "Tar cannot archive a fifo %s", arcn->org_name);
521 return(1);
522 case PAX_SLK:
523 case PAX_HLK:
524 case PAX_HRG:
525 if (arcn->ln_nlen >= (int)sizeof(hd->linkname)) {
526 paxwarn(1,"Link name too long for tar %s", arcn->ln_name);
527 return(1);
528 }
529 break;
530 case PAX_REG:
531 case PAX_CTG:
532 default:
533 break;
534 }
535
536 /*
537 * check file name len, remember extra char for dirs (the / at the end)
538 */
539 len = arcn->nlen;
540 if (arcn->type == PAX_DIR)
541 ++len;
542 if (len >= (int)sizeof(hd->name)) {
543 paxwarn(1, "File name too long for tar %s", arcn->name);
544 return(1);
545 }
546
547 /*
548 * Copy the data out of the ARCHD into the tar header based on the type
549 * of the file. Remember, many tar readers want all fields to be
550 * padded with zero so we zero the header first. We then set the
551 * linkflag field (type), the linkname, the size, and set the padding
552 * (if any) to be added after the file data (0 for all other types,
553 * as they only have a header).
554 */
555 hd = &hdblk;
556 l_strncpy(hd->name, arcn->name, sizeof(hd->name) - 1);
557 hd->name[sizeof(hd->name) - 1] = '\0';
558 arcn->pad = 0;
559
560 if (arcn->type == PAX_DIR) {
561 /*
562 * directories are the same as files, except have a filename
563 * that ends with a /, we add the slash here. No data follows,
564 * dirs, so no pad.
565 */
566 hd->linkflag = AREGTYPE;
567 memset(hd->linkname, 0, sizeof(hd->linkname));
568 hd->name[len-1] = '/';
569 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
570 goto out;
571 } else if (arcn->type == PAX_SLK) {
572 /*
573 * no data follows this file, so no pad
574 */
575 hd->linkflag = SYMTYPE;
576 l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1);
577 hd->linkname[sizeof(hd->linkname) - 1] = '\0';
578 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
579 goto out;
580 } else if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) {
581 /*
582 * no data follows this file, so no pad
583 */
584 hd->linkflag = LNKTYPE;
585 l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1);
586 hd->linkname[sizeof(hd->linkname) - 1] = '\0';
587 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
588 goto out;
589 } else {
590 /*
591 * data follows this file, so set the pad
592 */
593 hd->linkflag = AREGTYPE;
594 memset(hd->linkname, 0, sizeof(hd->linkname));
595 if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size,
596 sizeof(hd->size), 1)) {
597 paxwarn(1,"File is too large for tar %s", arcn->org_name);
598 return(1);
599 }
600 arcn->pad = TAR_PAD(arcn->sb.st_size);
601 }
602
603 /*
604 * copy those fields that are independent of the type
605 */
606 if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) ||
607 ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 0) ||
608 ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 0) ||
609 ul_oct((u_long)arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1))
610 goto out;
611
612 /*
613 * calculate and add the checksum, then write the header. A return of
614 * 0 tells the caller to now write the file data, 1 says no data needs
615 * to be written
616 */
617 if (ul_oct(tar_chksm((char *)&hdblk, sizeof(HD_TAR)), hd->chksum,
618 sizeof(hd->chksum), 3))
619 goto out;
620 if (wr_rdbuf((char *)&hdblk, sizeof(HD_TAR)) < 0)
621 return(-1);
622 if (wr_skip((off_t)(BLKMULT - sizeof(HD_TAR))) < 0)
623 return(-1);
624 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG))
625 return(0);
626 return(1);
627
628 out:
629 /*
630 * header field is out of range
631 */
632 paxwarn(1, "Tar header field is too small for %s", arcn->org_name);
633 return(1);
634 }
635
636 /*
637 * Routines for POSIX ustar
638 */
639
640 /*
641 * ustar_strd()
642 * initialization for ustar read
643 * Return:
644 * 0 if ok, -1 otherwise
645 */
646
647 int
ustar_strd(void)648 ustar_strd(void)
649 {
650 if ((usrtb_start() < 0) || (grptb_start() < 0))
651 return(-1);
652 return(0);
653 }
654
655 /*
656 * ustar_stwr()
657 * initialization for ustar write
658 * Return:
659 * 0 if ok, -1 otherwise
660 */
661
662 int
ustar_stwr(void)663 ustar_stwr(void)
664 {
665 if ((uidtb_start() < 0) || (gidtb_start() < 0))
666 return(-1);
667 return(0);
668 }
669
670 /*
671 * ustar_id()
672 * determine if a block given to us is a valid ustar header. We have to
673 * be on the lookout for those pesky blocks of all zero's
674 * Return:
675 * 0 if a ustar header, -1 otherwise
676 */
677
678 int
ustar_id(char * blk,int size)679 ustar_id(char *blk, int size)
680 {
681 HD_USTAR *hd;
682
683 if (size < BLKMULT)
684 return(-1);
685 hd = (HD_USTAR *)blk;
686
687 /*
688 * check for block of zero's first, a simple and fast test then check
689 * ustar magic cookie. We should use TMAGLEN, but some USTAR archive
690 * programs are fouled up and create archives missing the \0. Last we
691 * check the checksum. If ok we have to assume it is a valid header.
692 */
693 if (hd->name[0] == '\0')
694 return(-1);
695 if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0)
696 return(-1);
697 if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT))
698 return(-1);
699 return(0);
700 }
701
702 /*
703 * ustar_rd()
704 * extract the values out of block already determined to be a ustar header.
705 * store the values in the ARCHD parameter.
706 * Return:
707 * 0
708 */
709
710 int
ustar_rd(ARCHD * arcn,char * buf)711 ustar_rd(ARCHD *arcn, char *buf)
712 {
713 HD_USTAR *hd;
714 char *dest;
715 int cnt = 0;
716 dev_t devmajor;
717 dev_t devminor;
718
719 /*
720 * we only get proper sized buffers
721 */
722 if (ustar_id(buf, BLKMULT) < 0)
723 return(-1);
724 memset(arcn, 0, sizeof *arcn);
725 arcn->org_name = arcn->name;
726 arcn->sb.st_nlink = 1;
727 hd = (HD_USTAR *)buf;
728
729 /*
730 * see if the filename is split into two parts. if, so joint the parts.
731 * we copy the prefix first and add a / between the prefix and name.
732 */
733 dest = arcn->name;
734 if (*(hd->prefix) != '\0') {
735 cnt = l_strncpy(dest, hd->prefix,
736 MIN(sizeof(hd->prefix), sizeof(arcn->name) - 2));
737 dest += cnt;
738 *dest++ = '/';
739 cnt++;
740 }
741 /*
742 * ustar format specifies the name may be unterminated
743 * if it fills the entire field. this also applies to
744 * the prefix and the linkname.
745 */
746 arcn->nlen = cnt + l_strncpy(dest, hd->name,
747 MIN(sizeof(hd->name), sizeof(arcn->name) - cnt - 1));
748 arcn->name[arcn->nlen] = '\0';
749
750 /*
751 * follow the spec to the letter. we should only have mode bits, strip
752 * off all other crud we may be passed.
753 */
754 arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode, sizeof(hd->mode), OCT) &
755 0xfff);
756 arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT);
757 arcn->sb.st_mtime = (time_t)asc_uqd(hd->mtime, sizeof(hd->mtime), OCT);
758 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
759
760 /*
761 * If we can find the ascii names for gname and uname in the password
762 * and group files we will use the uid's and gid they bind. Otherwise
763 * we use the uid and gid values stored in the header. (This is what
764 * the POSIX spec wants).
765 */
766 hd->gname[sizeof(hd->gname) - 1] = '\0';
767 if (gid_name(hd->gname, &(arcn->sb.st_gid)) < 0)
768 arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT);
769 hd->uname[sizeof(hd->uname) - 1] = '\0';
770 if (uid_name(hd->uname, &(arcn->sb.st_uid)) < 0)
771 arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT);
772
773 /*
774 * set the mode and PAX type according to the typeflag in the header
775 */
776 switch(hd->typeflag) {
777 case FIFOTYPE:
778 arcn->type = PAX_FIF;
779 arcn->sb.st_mode |= S_IFIFO;
780 break;
781 case DIRTYPE:
782 arcn->type = PAX_DIR;
783 arcn->sb.st_mode |= S_IFDIR;
784 arcn->sb.st_nlink = 2;
785
786 /*
787 * Some programs that create ustar archives append a '/'
788 * to the pathname for directories. This clearly violates
789 * ustar specs, but we will silently strip it off anyway.
790 */
791 if (arcn->name[arcn->nlen - 1] == '/')
792 arcn->name[--arcn->nlen] = '\0';
793 break;
794 case BLKTYPE:
795 case CHRTYPE:
796 /*
797 * this type requires the rdev field to be set.
798 */
799 if (hd->typeflag == BLKTYPE) {
800 arcn->type = PAX_BLK;
801 arcn->sb.st_mode |= S_IFBLK;
802 } else {
803 arcn->type = PAX_CHR;
804 arcn->sb.st_mode |= S_IFCHR;
805 }
806 devmajor = (dev_t)asc_ul(hd->devmajor,sizeof(hd->devmajor),OCT);
807 devminor = (dev_t)asc_ul(hd->devminor,sizeof(hd->devminor),OCT);
808 arcn->sb.st_rdev = TODEV(devmajor, devminor);
809 break;
810 case SYMTYPE:
811 case LNKTYPE:
812 if (hd->typeflag == SYMTYPE) {
813 arcn->type = PAX_SLK;
814 arcn->sb.st_mode |= S_IFLNK;
815 } else {
816 arcn->type = PAX_HLK;
817 /*
818 * so printing looks better
819 */
820 arcn->sb.st_mode |= S_IFREG;
821 arcn->sb.st_nlink = 2;
822 }
823 /*
824 * copy the link name
825 */
826 arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
827 MIN(sizeof(hd->linkname), sizeof(arcn->ln_name) - 1));
828 arcn->ln_name[arcn->ln_nlen] = '\0';
829 break;
830 case CONTTYPE:
831 case AREGTYPE:
832 case REGTYPE:
833 default:
834 /*
835 * these types have file data that follows. Set the skip and
836 * pad fields.
837 */
838 arcn->type = PAX_REG;
839 arcn->pad = TAR_PAD(arcn->sb.st_size);
840 arcn->skip = arcn->sb.st_size;
841 arcn->sb.st_mode |= S_IFREG;
842 break;
843 }
844 return(0);
845 }
846
847 /*
848 * ustar_wr()
849 * write a ustar header for the file specified in the ARCHD to the archive
850 * Have to check for file types that cannot be stored and file names that
851 * are too long. Be careful of the term (last arg) to ul_oct, we only use
852 * '\0' for the termination character (this is different than picky tar)
853 * ASSUMED: space after header in header block is zero filled
854 * Return:
855 * 0 if file has data to be written after the header, 1 if file has NO
856 * data to write after the header, -1 if archive write failed
857 */
858
859 int
ustar_wr(ARCHD * arcn)860 ustar_wr(ARCHD *arcn)
861 {
862 HD_USTAR *hd;
863 char *pt;
864 HD_USTAR hdblk;
865
866 /*
867 * check for those file system types ustar cannot store
868 */
869 if (arcn->type == PAX_SCK) {
870 paxwarn(1, "Ustar cannot archive a socket %s", arcn->org_name);
871 return(1);
872 }
873
874 /*
875 * check the length of the linkname
876 */
877 if (((arcn->type == PAX_SLK) || (arcn->type == PAX_HLK) ||
878 (arcn->type == PAX_HRG)) &&
879 (arcn->ln_nlen > (int)sizeof(hd->linkname))) {
880 paxwarn(1, "Link name too long for ustar %s", arcn->ln_name);
881 return(1);
882 }
883
884 /*
885 * split the path name into prefix and name fields (if needed). if
886 * pt != arcn->name, the name has to be split
887 */
888 if ((pt = name_split(arcn->name, arcn->nlen)) == NULL) {
889 paxwarn(1, "File name too long for ustar %s", arcn->name);
890 return(1);
891 }
892 hd = &hdblk;
893 arcn->pad = 0L;
894
895 /*
896 * split the name, or zero out the prefix
897 */
898 if (pt != arcn->name) {
899 /*
900 * name was split, pt points at the / where the split is to
901 * occur, we remove the / and copy the first part to the prefix
902 */
903 *pt = '\0';
904 l_strncpy(hd->prefix, arcn->name, sizeof(hd->prefix));
905 *pt++ = '/';
906 } else
907 memset(hd->prefix, 0, sizeof(hd->prefix));
908
909 /*
910 * copy the name part. this may be the whole path or the part after
911 * the prefix. both the name and prefix may fill the entire field.
912 */
913 l_strncpy(hd->name, pt, sizeof(hd->name));
914
915 /*
916 * set the fields in the header that are type dependent
917 */
918 switch(arcn->type) {
919 case PAX_DIR:
920 hd->typeflag = DIRTYPE;
921 memset(hd->linkname, 0, sizeof(hd->linkname));
922 memset(hd->devmajor, 0, sizeof(hd->devmajor));
923 memset(hd->devminor, 0, sizeof(hd->devminor));
924 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
925 goto out;
926 break;
927 case PAX_CHR:
928 case PAX_BLK:
929 if (arcn->type == PAX_CHR)
930 hd->typeflag = CHRTYPE;
931 else
932 hd->typeflag = BLKTYPE;
933 memset(hd->linkname, 0, sizeof(hd->linkname));
934 if (ul_oct((u_long)MAJOR(arcn->sb.st_rdev), hd->devmajor,
935 sizeof(hd->devmajor), 3) ||
936 ul_oct((u_long)MINOR(arcn->sb.st_rdev), hd->devminor,
937 sizeof(hd->devminor), 3) ||
938 ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
939 goto out;
940 break;
941 case PAX_FIF:
942 hd->typeflag = FIFOTYPE;
943 memset(hd->linkname, 0, sizeof(hd->linkname));
944 memset(hd->devmajor, 0, sizeof(hd->devmajor));
945 memset(hd->devminor, 0, sizeof(hd->devminor));
946 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
947 goto out;
948 break;
949 case PAX_SLK:
950 case PAX_HLK:
951 case PAX_HRG:
952 if (arcn->type == PAX_SLK)
953 hd->typeflag = SYMTYPE;
954 else
955 hd->typeflag = LNKTYPE;
956 /* the link name may occupy the entire field in ustar */
957 l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname));
958 memset(hd->devmajor, 0, sizeof(hd->devmajor));
959 memset(hd->devminor, 0, sizeof(hd->devminor));
960 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
961 goto out;
962 break;
963 case PAX_REG:
964 case PAX_CTG:
965 default:
966 /*
967 * file data with this type, set the padding
968 */
969 if (arcn->type == PAX_CTG)
970 hd->typeflag = CONTTYPE;
971 else
972 hd->typeflag = REGTYPE;
973 memset(hd->linkname, 0, sizeof(hd->linkname));
974 memset(hd->devmajor, 0, sizeof(hd->devmajor));
975 memset(hd->devminor, 0, sizeof(hd->devminor));
976 arcn->pad = TAR_PAD(arcn->sb.st_size);
977 if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size,
978 sizeof(hd->size), 3)) {
979 paxwarn(1,"File is too long for ustar %s",arcn->org_name);
980 return(1);
981 }
982 break;
983 }
984
985 l_strncpy(hd->magic, TMAGIC, TMAGLEN);
986 l_strncpy(hd->version, TVERSION, TVERSLEN);
987
988 /*
989 * set the remaining fields. Some versions want all 16 bits of mode
990 * we better humor them (they really do not meet spec though)....
991 */
992 if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3) ||
993 ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3) ||
994 ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3) ||
995 ul_oct((u_long)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3))
996 goto out;
997 l_strncpy(hd->uname,name_uid(arcn->sb.st_uid, 0),sizeof(hd->uname));
998 l_strncpy(hd->gname,name_gid(arcn->sb.st_gid, 0),sizeof(hd->gname));
999
1000 /*
1001 * calculate and store the checksum write the header to the archive
1002 * return 0 tells the caller to now write the file data, 1 says no data
1003 * needs to be written
1004 */
1005 if (ul_oct(tar_chksm((char *)&hdblk, sizeof(HD_USTAR)), hd->chksum,
1006 sizeof(hd->chksum), 3))
1007 goto out;
1008 if (wr_rdbuf((char *)&hdblk, sizeof(HD_USTAR)) < 0)
1009 return(-1);
1010 if (wr_skip((off_t)(BLKMULT - sizeof(HD_USTAR))) < 0)
1011 return(-1);
1012 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG))
1013 return(0);
1014 return(1);
1015
1016 out:
1017 /*
1018 * header field is out of range
1019 */
1020 paxwarn(1, "Ustar header field is too small for %s", arcn->org_name);
1021 return(1);
1022 }
1023
1024 /*
1025 * name_split()
1026 * see if the name has to be split for storage in a ustar header. We try
1027 * to fit the entire name in the name field without splitting if we can.
1028 * The split point is always at a /
1029 * Return
1030 * character pointer to split point (always the / that is to be removed
1031 * if the split is not needed, the points is set to the start of the file
1032 * name (it would violate the spec to split there). A NULL is returned if
1033 * the file name is too long
1034 */
1035
1036 static char *
name_split(char * name,int len)1037 name_split(char *name, int len)
1038 {
1039 char *start;
1040
1041 /*
1042 * check to see if the file name is small enough to fit in the name
1043 * field. if so just return a pointer to the name.
1044 */
1045 if (len <= TNMSZ)
1046 return(name);
1047 if (len > TPFSZ + TNMSZ)
1048 return(NULL);
1049
1050 /*
1051 * we start looking at the biggest sized piece that fits in the name
1052 * field. We walk forward looking for a slash to split at. The idea is
1053 * to find the biggest piece to fit in the name field (or the smallest
1054 * prefix we can find)
1055 */
1056 start = name + len - TNMSZ;
1057 while ((*start != '\0') && (*start != '/'))
1058 ++start;
1059
1060 /*
1061 * if we hit the end of the string, this name cannot be split, so we
1062 * cannot store this file.
1063 */
1064 if (*start == '\0')
1065 return(NULL);
1066 len = start - name;
1067
1068 /*
1069 * NOTE: /str where the length of str == TNMSZ can not be stored under
1070 * the p1003.1-1990 spec for ustar. We could force a prefix of / and
1071 * the file would then expand on extract to //str. The len == 0 below
1072 * makes this special case follow the spec to the letter.
1073 */
1074 if ((len > TPFSZ) || (len == 0))
1075 return(NULL);
1076
1077 /*
1078 * ok have a split point, return it to the caller
1079 */
1080 return(start);
1081 }
1082