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