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