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