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