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