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