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