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