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