tar.c revision 1.8
1/* $NetBSD: tar.c,v 1.8 1997/06/25 22:44:00 kleink 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#ifndef lint 41#if 0 42static char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94"; 43#else 44static char rcsid[] = "$NetBSD: tar.c,v 1.8 1997/06/25 22:44:00 kleink Exp $"; 45#endif 46#endif /* not lint */ 47 48#include <sys/types.h> 49#include <sys/time.h> 50#include <sys/stat.h> 51#include <sys/param.h> 52#include <string.h> 53#include <stdio.h> 54#include <ctype.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 65static u_long tar_chksm __P((char *, int)); 66static char *name_split __P((char *, int)); 67static int ul_oct __P((u_long, char *, int, int)); 68#ifndef NET2_STAT 69static int uqd_oct __P((u_quad_t, char *, int, int)); 70#endif 71 72/* 73 * Routines common to all versions of tar 74 */ 75 76static 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#if __STDC__ 86int 87tar_endwr(void) 88#else 89int 90tar_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#if __STDC__ 104off_t 105tar_endrd(void) 106#else 107off_t 108tar_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#if __STDC__ 126int 127tar_trail(char *buf, int in_resync, int *cnt) 128#else 129int 130tar_trail(buf, in_resync, cnt) 131 char *buf; 132 int in_resync; 133 int *cnt; 134#endif 135{ 136 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#if __STDC__ 177static int 178ul_oct(u_long val, char *str, int len, int term) 179#else 180static int 181ul_oct(val, str, len, term) 182 u_long val; 183 char *str; 184 int len; 185 int term; 186#endif 187{ 188 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#if __STDC__ 241static int 242uqd_oct(u_quad_t val, char *str, int len, int term) 243#else 244static int 245uqd_oct(val, str, len, term) 246 u_quad_t val; 247 char *str; 248 int len; 249 int term; 250#endif 251{ 252 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#if __STDC__ 304static u_long 305tar_chksm(char *blk, int len) 306#else 307static u_long 308tar_chksm(blk, len) 309 char *blk; 310 int len; 311#endif 312{ 313 char *stop; 314 char *pt; 315 u_long chksm = BLNKSUM; /* inital 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#if __STDC__ 352int 353tar_id(char *blk, int size) 354#else 355int 356tar_id(blk, size) 357 char *blk; 358 int size; 359#endif 360{ 361 HD_TAR *hd; 362 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#if __STDC__ 393int 394tar_opt(void) 395#else 396int 397tar_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 warn(1, "Unknown tar format -o option/value pair %s=%s", 406 opt->name, opt->value); 407 warn(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 warn(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#if __STDC__ 435int 436tar_rd(ARCHD *arcn, char *buf) 437#else 438int 439tar_rd(arcn, buf) 440 ARCHD *arcn; 441 char *buf; 442#endif 443{ 444 HD_TAR *hd; 445 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(hd->name)); 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 arcn->sb.st_size = (size_t)asc_ul(hd->size, sizeof(hd->size), OCT); 467 arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT); 468 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 469 470 /* 471 * have to look at the last character, it may be a '/' and that is used 472 * to encode this as a directory 473 */ 474 pt = &(arcn->name[arcn->nlen - 1]); 475 arcn->pad = 0; 476 arcn->skip = 0; 477 switch(hd->linkflag) { 478 case SYMTYPE: 479 /* 480 * symbolic link, need to get the link name and set the type in 481 * the st_mode so -v printing will look correct. 482 */ 483 arcn->type = PAX_SLK; 484 arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname, 485 sizeof(hd->linkname)); 486 arcn->ln_name[arcn->ln_nlen] = '\0'; 487 arcn->sb.st_mode |= S_IFLNK; 488 break; 489 case LNKTYPE: 490 /* 491 * hard link, need to get the link name, set the type in the 492 * st_mode and st_nlink so -v printing will look better. 493 */ 494 arcn->type = PAX_HLK; 495 arcn->sb.st_nlink = 2; 496 arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname, 497 sizeof(hd->linkname)); 498 arcn->ln_name[arcn->ln_nlen] = '\0'; 499 500 /* 501 * no idea of what type this thing really points at, but 502 * we set something for printing only. 503 */ 504 arcn->sb.st_mode |= S_IFREG; 505 break; 506 case AREGTYPE: 507 case REGTYPE: 508 default: 509 /* 510 * If we have a trailing / this is a directory and NOT a file. 511 */ 512 arcn->ln_name[0] = '\0'; 513 arcn->ln_nlen = 0; 514 if (*pt == '/') { 515 /* 516 * it is a directory, set the mode for -v printing 517 */ 518 arcn->type = PAX_DIR; 519 arcn->sb.st_mode |= S_IFDIR; 520 arcn->sb.st_nlink = 2; 521 } else { 522 /* 523 * have a file that will be followed by data. Set the 524 * skip value to the size field and caluculate the size 525 * of the padding. 526 */ 527 arcn->type = PAX_REG; 528 arcn->sb.st_mode |= S_IFREG; 529 arcn->pad = TAR_PAD(arcn->sb.st_size); 530 arcn->skip = arcn->sb.st_size; 531 } 532 break; 533 } 534 535 /* 536 * strip off any trailing slash. 537 */ 538 if (*pt == '/') { 539 *pt = '\0'; 540 --arcn->nlen; 541 } 542 return(0); 543} 544 545/* 546 * tar_wr() 547 * write a tar header for the file specified in the ARCHD to the archive. 548 * Have to check for file types that cannot be stored and file names that 549 * are too long. Be careful of the term (last arg) to ul_oct, each field 550 * of tar has it own spec for the termination character(s). 551 * ASSUMED: space after header in header block is zero filled 552 * Return: 553 * 0 if file has data to be written after the header, 1 if file has NO 554 * data to write after the header, -1 if archive write failed 555 */ 556 557#if __STDC__ 558int 559tar_wr(ARCHD *arcn) 560#else 561int 562tar_wr(arcn) 563 ARCHD *arcn; 564#endif 565{ 566 HD_TAR *hd; 567 int len; 568 char hdblk[sizeof(HD_TAR)]; 569 570 /* 571 * check for those file system types which tar cannot store 572 */ 573 switch(arcn->type) { 574 case PAX_DIR: 575 /* 576 * user asked that dirs not be written to the archive 577 */ 578 if (tar_nodir) 579 return(1); 580 break; 581 case PAX_CHR: 582 warn(1, "Tar cannot archive a character device %s", 583 arcn->org_name); 584 return(1); 585 case PAX_BLK: 586 warn(1, "Tar cannot archive a block device %s", arcn->org_name); 587 return(1); 588 case PAX_SCK: 589 warn(1, "Tar cannot archive a socket %s", arcn->org_name); 590 return(1); 591 case PAX_FIF: 592 warn(1, "Tar cannot archive a fifo %s", arcn->org_name); 593 return(1); 594 case PAX_SLK: 595 case PAX_HLK: 596 case PAX_HRG: 597 if (arcn->ln_nlen > sizeof(hd->linkname)) { 598 warn(1,"Link name too long for tar %s", arcn->ln_name); 599 return(1); 600 } 601 break; 602 case PAX_REG: 603 case PAX_CTG: 604 default: 605 break; 606 } 607 608 /* 609 * check file name len, remember extra char for dirs (the / at the end) 610 */ 611 len = arcn->nlen; 612 if (arcn->type == PAX_DIR) 613 ++len; 614 if (len > sizeof(hd->name)) { 615 warn(1, "File name too long for tar %s", arcn->name); 616 return(1); 617 } 618 619 /* 620 * copy the data out of the ARCHD into the tar header based on the type 621 * of the file. Remember many tar readers want the unused fields to be 622 * padded with zero. We set the linkflag field (type), the linkname 623 * (or zero if not used),the size, and set the padding (if any) to be 624 * added after the file data (0 for all other types, as they only have 625 * a header) 626 */ 627 hd = (HD_TAR *)hdblk; 628 zf_strncpy(hd->name, arcn->name, sizeof(hd->name)); 629 arcn->pad = 0; 630 631 if (arcn->type == PAX_DIR) { 632 /* 633 * directories are the same as files, except have a filename 634 * that ends with a /, we add the slash here. No data follows, 635 * dirs, so no pad. 636 */ 637 hd->linkflag = AREGTYPE; 638 memset(hd->linkname, 0, sizeof(hd->linkname)); 639 hd->name[len-1] = '/'; 640 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) 641 goto out; 642 } else if (arcn->type == PAX_SLK) { 643 /* 644 * no data follows this file, so no pad 645 */ 646 hd->linkflag = SYMTYPE; 647 zf_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname)); 648 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) 649 goto out; 650 } else if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) { 651 /* 652 * no data follows this file, so no pad 653 */ 654 hd->linkflag = LNKTYPE; 655 zf_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname)); 656 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) 657 goto out; 658 } else { 659 /* 660 * data follows this file, so set the pad 661 */ 662 hd->linkflag = AREGTYPE; 663 memset(hd->linkname, 0, sizeof(hd->linkname)); 664# ifdef NET2_STAT 665 if (ul_oct((u_long)arcn->sb.st_size, hd->size, 666 sizeof(hd->size), 1)) { 667# else 668 if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size, 669 sizeof(hd->size), 1)) { 670# endif 671 warn(1,"File is too large for tar %s", arcn->org_name); 672 return(1); 673 } 674 arcn->pad = TAR_PAD(arcn->sb.st_size); 675 } 676 677 /* 678 * copy those fields that are independent of the type 679 */ 680 if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) || 681 ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 0) || 682 ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 0) || 683 ul_oct((u_long)arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1)) 684 goto out; 685 686 /* 687 * calculate and add the checksum, then write the header. A return of 688 * 0 tells the caller to now write the file data, 1 says no data needs 689 * to be written 690 */ 691 if (ul_oct(tar_chksm(hdblk, sizeof(HD_TAR)), hd->chksum, 692 sizeof(hd->chksum), 2)) 693 goto out; 694 if (wr_rdbuf(hdblk, sizeof(HD_TAR)) < 0) 695 return(-1); 696 if (wr_skip((off_t)(BLKMULT - sizeof(HD_TAR))) < 0) 697 return(-1); 698 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG)) 699 return(0); 700 return(1); 701 702 out: 703 /* 704 * header field is out of range 705 */ 706 warn(1, "Tar header field is too small for %s", arcn->org_name); 707 return(1); 708} 709 710/* 711 * Routines for POSIX ustar 712 */ 713 714/* 715 * ustar_strd() 716 * initialization for ustar read 717 * Return: 718 * 0 if ok, -1 otherwise 719 */ 720 721#if __STDC__ 722int 723ustar_strd(void) 724#else 725int 726ustar_strd() 727#endif 728{ 729 if ((usrtb_start() < 0) || (grptb_start() < 0)) 730 return(-1); 731 return(0); 732} 733 734/* 735 * ustar_stwr() 736 * initialization for ustar write 737 * Return: 738 * 0 if ok, -1 otherwise 739 */ 740 741#if __STDC__ 742int 743ustar_stwr(void) 744#else 745int 746ustar_stwr() 747#endif 748{ 749 if ((uidtb_start() < 0) || (gidtb_start() < 0)) 750 return(-1); 751 return(0); 752} 753 754/* 755 * ustar_id() 756 * determine if a block given to us is a valid ustar header. We have to 757 * be on the lookout for those pesky blocks of all zero's 758 * Return: 759 * 0 if a ustar header, -1 otherwise 760 */ 761 762#if __STDC__ 763int 764ustar_id(char *blk, int size) 765#else 766int 767ustar_id(blk, size) 768 char *blk; 769 int size; 770#endif 771{ 772 HD_USTAR *hd; 773 774 if (size < BLKMULT) 775 return(-1); 776 hd = (HD_USTAR *)blk; 777 778 /* 779 * check for block of zero's first, a simple and fast test then check 780 * ustar magic cookie. We should use TMAGLEN, but some USTAR archive 781 * programs are fouled up and create archives missing the \0. Last we 782 * check the checksum. If ok we have to assume it is a valid header. 783 */ 784 if (hd->name[0] == '\0') 785 return(-1); 786 if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0) 787 return(-1); 788 if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT)) 789 return(-1); 790 return(0); 791} 792 793/* 794 * ustar_rd() 795 * extract the values out of block already determined to be a ustar header. 796 * store the values in the ARCHD parameter. 797 * Return: 798 * 0 799 */ 800 801#if __STDC__ 802int 803ustar_rd(ARCHD *arcn, char *buf) 804#else 805int 806ustar_rd(arcn, buf) 807 ARCHD *arcn; 808 char *buf; 809#endif 810{ 811 HD_USTAR *hd; 812 char *dest; 813 int cnt = 0; 814 dev_t devmajor; 815 dev_t devminor; 816 817 /* 818 * we only get proper sized buffers 819 */ 820 if (ustar_id(buf, BLKMULT) < 0) 821 return(-1); 822 arcn->org_name = arcn->name; 823 arcn->sb.st_nlink = 1; 824 arcn->pat = NULL; 825 hd = (HD_USTAR *)buf; 826 827 /* 828 * see if the filename is split into two parts. if, so joint the parts. 829 * we copy the prefix first and add a / between the prefix and name. 830 */ 831 dest = arcn->name; 832 if (*(hd->prefix) != '\0') { 833 cnt = l_strncpy(arcn->name, hd->prefix, sizeof(hd->prefix)); 834 dest = arcn->name + arcn->nlen; 835 *dest++ = '/'; 836 cnt++; 837 } 838 arcn->nlen = l_strncpy(dest, hd->name, sizeof(hd->name)); 839 arcn->nlen += cnt; 840 arcn->name[arcn->nlen] = '\0'; 841 842 /* 843 * follow the spec to the letter. we should only have mode bits, strip 844 * off all other crud we may be passed. 845 */ 846 arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode, sizeof(hd->mode), OCT) & 847 0xfff); 848 arcn->sb.st_size = (size_t)asc_ul(hd->size, sizeof(hd->size), OCT); 849 arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT); 850 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 851 852 /* 853 * If we can find the ascii names for gname and uname in the password 854 * and group files we will use the uid's and gid they bind. Otherwise 855 * we use the uid and gid values stored in the header. (This is what 856 * the posix spec wants). 857 */ 858 hd->gname[sizeof(hd->gname) - 1] = '\0'; 859 if (gid_name(hd->gname, &(arcn->sb.st_gid)) < 0) 860 arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT); 861 hd->uname[sizeof(hd->uname) - 1] = '\0'; 862 if (uid_name(hd->uname, &(arcn->sb.st_uid)) < 0) 863 arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT); 864 865 /* 866 * set the defaults, these may be changed depending on the file type 867 */ 868 arcn->ln_name[0] = '\0'; 869 arcn->ln_nlen = 0; 870 arcn->pad = 0; 871 arcn->skip = 0; 872 arcn->sb.st_rdev = (dev_t)0; 873 874 /* 875 * set the mode and PAX type according to the typeflag in the header 876 */ 877 switch(hd->typeflag) { 878 case FIFOTYPE: 879 arcn->type = PAX_FIF; 880 arcn->sb.st_mode |= S_IFIFO; 881 break; 882 case DIRTYPE: 883 arcn->type = PAX_DIR; 884 arcn->sb.st_mode |= S_IFDIR; 885 arcn->sb.st_nlink = 2; 886 887 /* 888 * Some programs that create ustar archives append a '/' 889 * to the pathname for directories. This clearly violates 890 * ustar specs, but we will silently strip it off anyway. 891 */ 892 if (arcn->name[arcn->nlen - 1] == '/') 893 arcn->name[--arcn->nlen] = '\0'; 894 break; 895 case BLKTYPE: 896 case CHRTYPE: 897 /* 898 * this type requires the rdev field to be set. 899 */ 900 if (hd->typeflag == BLKTYPE) { 901 arcn->type = PAX_BLK; 902 arcn->sb.st_mode |= S_IFBLK; 903 } else { 904 arcn->type = PAX_CHR; 905 arcn->sb.st_mode |= S_IFCHR; 906 } 907 devmajor = (dev_t)asc_ul(hd->devmajor,sizeof(hd->devmajor),OCT); 908 devminor = (dev_t)asc_ul(hd->devminor,sizeof(hd->devminor),OCT); 909 arcn->sb.st_rdev = TODEV(devmajor, devminor); 910 break; 911 case SYMTYPE: 912 case LNKTYPE: 913 if (hd->typeflag == SYMTYPE) { 914 arcn->type = PAX_SLK; 915 arcn->sb.st_mode |= S_IFLNK; 916 } else { 917 arcn->type = PAX_HLK; 918 /* 919 * so printing looks better 920 */ 921 arcn->sb.st_mode |= S_IFREG; 922 arcn->sb.st_nlink = 2; 923 } 924 /* 925 * copy the link name 926 */ 927 arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname, 928 sizeof(hd->linkname)); 929 arcn->ln_name[arcn->ln_nlen] = '\0'; 930 break; 931 case CONTTYPE: 932 case AREGTYPE: 933 case REGTYPE: 934 default: 935 /* 936 * these types have file data that follows. Set the skip and 937 * pad fields. 938 */ 939 arcn->type = PAX_REG; 940 arcn->pad = TAR_PAD(arcn->sb.st_size); 941 arcn->skip = arcn->sb.st_size; 942 arcn->sb.st_mode |= S_IFREG; 943 break; 944 } 945 return(0); 946} 947 948/* 949 * ustar_wr() 950 * write a ustar header for the file specified in the ARCHD to the archive 951 * Have to check for file types that cannot be stored and file names that 952 * are too long. Be careful of the term (last arg) to ul_oct, we only use 953 * '\0' for the termination character (this is different than picky tar) 954 * ASSUMED: space after header in header block is zero filled 955 * Return: 956 * 0 if file has data to be written after the header, 1 if file has NO 957 * data to write after the header, -1 if archive write failed 958 */ 959 960#if __STDC__ 961int 962ustar_wr(ARCHD *arcn) 963#else 964int 965ustar_wr(arcn) 966 ARCHD *arcn; 967#endif 968{ 969 HD_USTAR *hd; 970 char *pt; 971 char hdblk[sizeof(HD_USTAR)]; 972 973 /* 974 * check for those file system types ustar cannot store 975 */ 976 if (arcn->type == PAX_SCK) { 977 warn(1, "Ustar cannot archive a socket %s", arcn->org_name); 978 return(1); 979 } 980 981 /* 982 * check the length of the linkname 983 */ 984 if (((arcn->type == PAX_SLK) || (arcn->type == PAX_HLK) || 985 (arcn->type == PAX_HRG)) && (arcn->ln_nlen > sizeof(hd->linkname))){ 986 warn(1, "Link name too long for ustar %s", arcn->ln_name); 987 return(1); 988 } 989 990 /* 991 * split the path name into prefix and name fields (if needed). if 992 * pt != arcn->name, the name has to be split 993 */ 994 if ((pt = name_split(arcn->name, arcn->nlen)) == NULL) { 995 warn(1, "File name too long for ustar %s", arcn->name); 996 return(1); 997 } 998 hd = (HD_USTAR *)hdblk; 999 arcn->pad = 0L; 1000 1001 /* 1002 * split the name, or zero out the prefix 1003 */ 1004 if (pt != arcn->name) { 1005 /* 1006 * name was split, pt points at the / where the split is to 1007 * occur, we remove the / and copy the first part to the prefix 1008 */ 1009 *pt = '\0'; 1010 zf_strncpy(hd->prefix, arcn->name, sizeof(hd->prefix)); 1011 *pt++ = '/'; 1012 } else 1013 memset(hd->prefix, 0, sizeof(hd->prefix)); 1014 1015 /* 1016 * copy the name part. this may be the whole path or the part after 1017 * the prefix 1018 */ 1019 zf_strncpy(hd->name, pt, sizeof(hd->name)); 1020 1021 /* 1022 * set the fields in the header that are type dependent 1023 */ 1024 switch(arcn->type) { 1025 case PAX_DIR: 1026 hd->typeflag = DIRTYPE; 1027 memset(hd->linkname, 0, sizeof(hd->linkname)); 1028 memset(hd->devmajor, 0, sizeof(hd->devmajor)); 1029 memset(hd->devminor, 0, sizeof(hd->devminor)); 1030 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) 1031 goto out; 1032 break; 1033 case PAX_CHR: 1034 case PAX_BLK: 1035 if (arcn->type == PAX_CHR) 1036 hd->typeflag = CHRTYPE; 1037 else 1038 hd->typeflag = BLKTYPE; 1039 memset(hd->linkname, 0, sizeof(hd->linkname)); 1040 if (ul_oct((u_long)MAJOR(arcn->sb.st_rdev), hd->devmajor, 1041 sizeof(hd->devmajor), 3) || 1042 ul_oct((u_long)MINOR(arcn->sb.st_rdev), hd->devminor, 1043 sizeof(hd->devminor), 3) || 1044 ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) 1045 goto out; 1046 break; 1047 case PAX_FIF: 1048 hd->typeflag = FIFOTYPE; 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_SLK: 1056 case PAX_HLK: 1057 case PAX_HRG: 1058 if (arcn->type == PAX_SLK) 1059 hd->typeflag = SYMTYPE; 1060 else 1061 hd->typeflag = LNKTYPE; 1062 zf_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname)); 1063 memset(hd->devmajor, 0, sizeof(hd->devmajor)); 1064 memset(hd->devminor, 0, sizeof(hd->devminor)); 1065 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) 1066 goto out; 1067 break; 1068 case PAX_REG: 1069 case PAX_CTG: 1070 default: 1071 /* 1072 * file data with this type, set the padding 1073 */ 1074 if (arcn->type == PAX_CTG) 1075 hd->typeflag = CONTTYPE; 1076 else 1077 hd->typeflag = REGTYPE; 1078 memset(hd->linkname, 0, sizeof(hd->linkname)); 1079 memset(hd->devmajor, 0, sizeof(hd->devmajor)); 1080 memset(hd->devminor, 0, sizeof(hd->devminor)); 1081 arcn->pad = TAR_PAD(arcn->sb.st_size); 1082# ifdef NET2_STAT 1083 if (ul_oct((u_long)arcn->sb.st_size, hd->size, 1084 sizeof(hd->size), 3)) { 1085# else 1086 if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size, 1087 sizeof(hd->size), 3)) { 1088# endif 1089 warn(1,"File is too long for ustar %s",arcn->org_name); 1090 return(1); 1091 } 1092 break; 1093 } 1094 1095 zf_strncpy(hd->magic, TMAGIC, TMAGLEN); 1096 zf_strncpy(hd->version, TVERSION, TVERSLEN); 1097 1098 /* 1099 * set the remaining fields. Some versions want all 16 bits of mode 1100 * we better humor them (they really do not meet spec though).... 1101 */ 1102 if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3) || 1103 ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3) || 1104 ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3) || 1105 ul_oct((u_long)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3)) 1106 goto out; 1107 zf_strncpy(hd->uname,name_uid(arcn->sb.st_uid, 0),sizeof(hd->uname)); 1108 zf_strncpy(hd->gname,name_gid(arcn->sb.st_gid, 0),sizeof(hd->gname)); 1109 1110 /* 1111 * calculate and store the checksum write the header to the archive 1112 * return 0 tells the caller to now write the file data, 1 says no data 1113 * needs to be written 1114 */ 1115 if (ul_oct(tar_chksm(hdblk, sizeof(HD_USTAR)), hd->chksum, 1116 sizeof(hd->chksum), 3)) 1117 goto out; 1118 if (wr_rdbuf(hdblk, sizeof(HD_USTAR)) < 0) 1119 return(-1); 1120 if (wr_skip((off_t)(BLKMULT - sizeof(HD_USTAR))) < 0) 1121 return(-1); 1122 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG)) 1123 return(0); 1124 return(1); 1125 1126 out: 1127 /* 1128 * header field is out of range 1129 */ 1130 warn(1, "Ustar header field is too small for %s", arcn->org_name); 1131 return(1); 1132} 1133 1134/* 1135 * name_split() 1136 * see if the name has to be split for storage in a ustar header. We try 1137 * to fit the entire name in the name field without splitting if we can. 1138 * The split point is always at a / 1139 * Return 1140 * character pointer to split point (always the / that is to be removed 1141 * if the split is not needed, the points is set to the start of the file 1142 * name (it would violate the spec to split there). A NULL is returned if 1143 * the file name is too long 1144 */ 1145 1146#if __STDC__ 1147static char * 1148name_split(char *name, int len) 1149#else 1150static char * 1151name_split(name, len) 1152 char *name; 1153 int len; 1154#endif 1155{ 1156 char *start; 1157 1158 /* 1159 * check to see if the file name is small enough to fit in the name 1160 * field. if so just return a pointer to the name. 1161 */ 1162 if (len <= TNMSZ) 1163 return(name); 1164 if (len > (TPFSZ + TNMSZ + 1)) 1165 return(NULL); 1166 1167 /* 1168 * we start looking at the biggest sized piece that fits in the name 1169 * field. We walk foward looking for a slash to split at. The idea is 1170 * to find the biggest piece to fit in the name field (or the smallest 1171 * prefix we can find) (the -1 is correct the biggest piece would 1172 * include the slash between the two parts that gets thrown away) 1173 */ 1174 start = name + len - TNMSZ - 1; 1175 while ((*start != '\0') && (*start != '/')) 1176 ++start; 1177 1178 /* 1179 * if we hit the end of the string, this name cannot be split, so we 1180 * cannot store this file. 1181 */ 1182 if (*start == '\0') 1183 return(NULL); 1184 len = start - name; 1185 1186 /* 1187 * NOTE: /str where the length of str == TNMSZ can not be stored under 1188 * the p1003.1-1990 spec for ustar. We could force a prefix of / and 1189 * the file would then expand on extract to //str. The len == 0 below 1190 * makes this special case follow the spec to the letter. 1191 */ 1192 if ((len > TPFSZ) || (len == 0)) 1193 return(NULL); 1194 1195 /* 1196 * ok have a split point, return it to the caller 1197 */ 1198 return(start); 1199} 1200