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