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