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