tar.c revision 102230
1151912Sphk/*- 2151912Sphk * Copyright (c) 1992 Keith Muller. 3209440Smav * Copyright (c) 1992, 1993 4151912Sphk * The Regents of the University of California. All rights reserved. 5151912Sphk * 6151912Sphk * This code is derived from software contributed to Berkeley by 7151912Sphk * Keith Muller of the University of California, San Diego. 8151912Sphk * 9151912Sphk * Redistribution and use in source and binary forms, with or without 10151912Sphk * modification, are permitted provided that the following conditions 11151912Sphk * are met: 12151912Sphk * 1. Redistributions of source code must retain the above copyright 13151912Sphk * notice, this list of conditions and the following disclaimer. 14151912Sphk * 2. Redistributions in binary form must reproduce the above copyright 15151912Sphk * notice, this list of conditions and the following disclaimer in the 16151912Sphk * documentation and/or other materials provided with the distribution. 17151912Sphk * 3. All advertising materials mentioning features or use of this software 18151912Sphk * must display the following acknowledgement: 19151912Sphk * This product includes software developed by the University of 20151912Sphk * California, Berkeley and its contributors. 21151912Sphk * 4. Neither the name of the University nor the names of its contributors 22151912Sphk * may be used to endorse or promote products derived from this software 23151912Sphk * without specific prior written permission. 24151912Sphk * 25151912Sphk * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26151912Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27151912Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28151912Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29151912Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30151912Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31151912Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32268351Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33209371Smav * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34209371Smav * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35209371Smav * SUCH DAMAGE. 36209371Smav */ 37151912Sphk 38159217Snjl#ifndef lint 39151912Sphk#if 0 40151912Sphkstatic char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94"; 41209371Smav#endif 42151912Sphk#endif /* not lint */ 43151912Sphk#include <sys/cdefs.h> 44209371Smav__FBSDID("$FreeBSD: head/bin/pax/tar.c 102230 2002-08-21 17:32:44Z trhodes $"); 45209371Smav 46209371Smav#include <sys/types.h> 47151912Sphk#include <sys/time.h> 48159217Snjl#include <sys/stat.h> 49193530Sjkim#include <string.h> 50193530Sjkim#include <stdio.h> 51193530Sjkim#include <unistd.h> 52151912Sphk#include <stdlib.h> 53175385Sjhb#include "pax.h" 54151912Sphk#include "extern.h" 55209371Smav#include "tar.h" 56209371Smav 57209371Smav/* 58209371Smav * Routines for reading, writing and header identify of various versions of tar 59203062Savg */ 60240286Smav 61203062Savgstatic u_long tar_chksm(char *, int); 62213302Smavstatic char *name_split(char *, int); 63232797Smavstatic int ul_oct(u_long, char *, int, int); 64203062Savg#ifndef NET2_STAT 65151912Sphkstatic int uqd_oct(u_quad_t, char *, int, int); 66151912Sphk#endif 67209371Smav 68169574Stakawata/* 69151931Sscottl * Routines common to all versions of tar 70151935Sscottl */ 71151931Sscottl 72151931Sscottlstatic int tar_nodir; /* do not write dirs under old tar */ 73209371Smav 74151912Sphk/* 75209371Smav * tar_endwr() 76209371Smav * add the tar trailer of two null blocks 77209371Smav * Return: 78209371Smav * 0 if ok, -1 otherwise (what wr_skip returns) 79209440Smav */ 80212533Smav 81212238Smavint 82159217Snjltar_endwr(void) 83209371Smav{ 84209371Smav return(wr_skip((off_t)(NULLCNT*BLKMULT))); 85151912Sphk} 86209371Smav 87209440Smav/* 88209371Smav * tar_endrd() 89209371Smav * no cleanup needed here, just return size of trailer (for append) 90209371Smav * Return: 91209371Smav * size of trailer (2 * BLKMULT) 92209371Smav */ 93209371Smav 94209371Smavoff_t 95209371Smavtar_endrd(void) 96212323Smav{ 97212323Smav return((off_t)(NULLCNT*BLKMULT)); 98209371Smav} 99209371Smav 100209371Smav/* 101209371Smav * tar_trail() 102209371Smav * Called to determine if a header block is a valid trailer. We are passed 103209371Smav * the block, the in_sync flag (which tells us we are in resync mode; 104209371Smav * looking for a valid header), and cnt (which starts at zero) which is 105212491Smav * used to count the number of empty blocks we have seen so far. 106209371Smav * Return: 107209371Smav * 0 if a valid trailer, -1 if not a valid trailer, or 1 if the block 108209371Smav * could never contain a header. 109151912Sphk */ 110151912Sphk 111159217Snjlint 112209371Smavtar_trail(char *buf, int in_resync, int *cnt) 113151912Sphk{ 114159217Snjl int i; 115159217Snjl 116269515Sroyger /* 117269515Sroyger * look for all zero, trailer is two consecutive blocks of zero 118269515Sroyger */ 119159217Snjl for (i = 0; i < BLKMULT; ++i) { 120151912Sphk if (buf[i] != '\0') 121151912Sphk break; 122209371Smav } 123151912Sphk 124151912Sphk /* 125175385Sjhb * if not all zero it is not a trailer, but MIGHT be a header. 126151912Sphk */ 127151912Sphk if (i != BLKMULT) 128175361Sjhb return(-1); 129209371Smav 130175361Sjhb /* 131175361Sjhb * When given a zero block, we must be careful! 132175385Sjhb * If we are not in resync mode, check for the trailer. Have to watch 133175385Sjhb * out that we do not mis-identify file data as the trailer, so we do 134209440Smav * NOT try to id a trailer during resync mode. During resync mode we 135209440Smav * might as well throw this block out since a valid header can NEVER be 136209440Smav * a block of all 0 (we must have a valid file name). 137209440Smav */ 138185103Sjkim if (!in_resync && (++*cnt >= NULLCNT)) 139185103Sjkim return(0); 140175361Sjhb return(1); 141175361Sjhb} 142175361Sjhb 143209371Smav/* 144175361Sjhb * ul_oct() 145175361Sjhb * convert an unsigned long to an octal string. many oddball field 146175385Sjhb * termination characters are used by the various versions of tar in the 147175385Sjhb * different fields. term selects which kind to use. str is '0' padded 148185103Sjkim * at the front to len. we are unable to use only one format as many old 149185103Sjkim * tar readers are very cranky about this. 150175361Sjhb * Return: 151175361Sjhb * 0 if the number fit into the string, -1 otherwise 152209371Smav */ 153247463Smav 154209371Smavstatic int 155209371Smavul_oct(u_long val, char *str, int len, int term) 156209371Smav{ 157209371Smav char *pt; 158212491Smav 159209371Smav /* 160209371Smav * term selects the appropriate character(s) for the end of the string 161247463Smav */ 162209371Smav pt = str + len - 1; 163247463Smav switch(term) { 164209371Smav case 3: 165209371Smav *pt-- = '\0'; 166209371Smav break; 167209371Smav case 2: 168247463Smav *pt-- = ' '; 169247463Smav *pt-- = '\0'; 170247463Smav break; 171210290Smav case 1: 172212238Smav *pt-- = ' '; 173212238Smav break; 174212238Smav case 0: 175212491Smav default: 176212238Smav *pt-- = '\0'; 177212491Smav *pt-- = ' '; 178209371Smav break; 179209371Smav } 180209371Smav 181209371Smav /* 182212491Smav * convert and blank pad if there is space 183212491Smav */ 184212491Smav while (pt >= str) { 185212491Smav *pt-- = '0' + (char)(val & 0x7); 186209371Smav if ((val = val >> 3) == (u_long)0) 187212238Smav break; 188212491Smav } 189212491Smav 190212491Smav while (pt >= str) 191212491Smav *pt-- = '0'; 192209371Smav if (val != (u_long)0) 193224919Smav return(-1); 194224919Smav return(0); 195224919Smav} 196224919Smav 197212238Smav#ifndef NET2_STAT 198209371Smav/* 199209371Smav * uqd_oct() 200209371Smav * convert an u_quad_t to an octal string. one of many oddball field 201209371Smav * termination characters are used by the various versions of tar in the 202209371Smav * different fields. term selects which kind to use. str is '0' padded 203209371Smav * at the front to len. we are unable to use only one format as many old 204209371Smav * tar readers are very cranky about this. 205209371Smav * Return: 206209371Smav * 0 if the number fit into the string, -1 otherwise 207209371Smav */ 208209371Smav 209209371Smavstatic int 210209371Smavuqd_oct(u_quad_t val, char *str, int len, int term) 211209371Smav{ 212209371Smav char *pt; 213209371Smav 214209371Smav /* 215209371Smav * term selects the appropriate character(s) for the end of the string 216209371Smav */ 217209371Smav pt = str + len - 1; 218209371Smav switch(term) { 219209371Smav case 3: 220209371Smav *pt-- = '\0'; 221209371Smav break; 222209371Smav case 2: 223212491Smav *pt-- = ' '; 224212491Smav *pt-- = '\0'; 225212323Smav break; 226212323Smav case 1: 227212323Smav *pt-- = ' '; 228212323Smav break; 229212323Smav case 0: 230212323Smav default: 231212323Smav *pt-- = '\0'; 232212323Smav *pt-- = ' '; 233212323Smav break; 234212323Smav } 235212323Smav 236212323Smav /* 237212323Smav * convert and blank pad if there is space 238212323Smav */ 239212491Smav while (pt >= str) { 240212491Smav *pt-- = '0' + (char)(val & 0x7); 241212323Smav if ((val = val >> 3) == 0) 242212491Smav break; 243212323Smav } 244212323Smav 245212323Smav while (pt >= str) 246209371Smav *pt-- = '0'; 247209371Smav if (val != (u_quad_t)0) 248212491Smav return(-1); 249209371Smav return(0); 250212491Smav} 251212491Smav#endif 252209371Smav 253212491Smav/* 254209371Smav * tar_chksm() 255209371Smav * calculate the checksum for a tar block counting the checksum field as 256209371Smav * all blanks (BLNKSUM is that value pre-calculated, the sum of 8 blanks). 257209990Smav * NOTE: we use len to short circuit summing 0's on write since we ALWAYS 258209990Smav * pad headers with 0. 259209371Smav * Return: 260209371Smav * unsigned long checksum 261209371Smav */ 262209371Smav 263209371Smavstatic u_long 264209371Smavtar_chksm(char *blk, int len) 265209371Smav{ 266209371Smav char *stop; 267209371Smav char *pt; 268209371Smav u_long chksm = BLNKSUM; /* initial value is checksum field sum */ 269209371Smav 270209371Smav /* 271209371Smav * add the part of the block before the checksum field 272209371Smav */ 273209371Smav pt = blk; 274209371Smav stop = blk + CHK_OFFSET; 275209371Smav while (pt < stop) 276209371Smav chksm += (u_long)(*pt++ & 0xff); 277209371Smav /* 278209371Smav * move past the checksum field and keep going, spec counts the 279209371Smav * checksum field as the sum of 8 blanks (which is pre-computed as 280209371Smav * BLNKSUM). 281209371Smav * ASSUMED: len is greater than CHK_OFFSET. (len is where our 0 padding 282209371Smav * starts, no point in summing zero's) 283208436Smav */ 284209371Smav pt += CHK_LEN; 285208436Smav stop = blk + len; 286208436Smav while (pt < stop) 287208436Smav chksm += (u_long)(*pt++ & 0xff); 288208436Smav return(chksm); 289208438Smav} 290208436Smav 291208436Smav/* 292208436Smav * Routines for old BSD style tar (also made portable to sysV tar) 293208436Smav */ 294208436Smav 295208436Smav/* 296208436Smav * tar_id() 297209371Smav * determine if a block given to us is a valid tar header (and not a USTAR 298209371Smav * header). We have to be on the lookout for those pesky blocks of all 299258164Smav * zero's. 300208436Smav * Return: 301208436Smav * 0 if a tar header, -1 otherwise 302208436Smav */ 303216263Sjhb 304216263Sjhbint 305216263Sjhbtar_id(char *blk, int size) 306216263Sjhb{ 307216263Sjhb HD_TAR *hd; 308216263Sjhb HD_USTAR *uhd; 309216263Sjhb 310216263Sjhb if (size < BLKMULT) 311216263Sjhb return(-1); 312216263Sjhb hd = (HD_TAR *)blk; 313216263Sjhb uhd = (HD_USTAR *)blk; 314216263Sjhb 315216263Sjhb /* 316216263Sjhb * check for block of zero's first, a simple and fast test, then make 317216263Sjhb * sure this is not a ustar header by looking for the ustar magic 318216263Sjhb * cookie. We should use TMAGLEN, but some USTAR archive programs are 319216263Sjhb * wrong and create archives missing the \0. Last we check the 320169592Snjl * checksum. If this is ok we have to assume it is a valid header. 321172489Snjl */ 322209371Smav if (hd->name[0] == '\0') 323169574Stakawata return(-1); 324169574Stakawata if (strncmp(uhd->magic, TMAGIC, TMAGLEN - 1) == 0) 325169574Stakawata return(-1); 326169574Stakawata if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT)) 327258164Smav return(-1); 328169574Stakawata return(0); 329172489Snjl} 330209371Smav 331172489Snjl/* 332208436Smav * tar_opt() 333208436Smav * handle tar format specific -o options 334208436Smav * Return: 335208436Smav * 0 if ok -1 otherwise 336208436Smav */ 337208436Smav 338258164Smavint 339208436Smavtar_opt(void) 340258164Smav{ 341258164Smav OPLIST *opt; 342208436Smav 343258164Smav while ((opt = opt_next()) != NULL) { 344258164Smav if (strcmp(opt->name, TAR_OPTION) || 345258164Smav strcmp(opt->value, TAR_NODIR)) { 346258164Smav paxwarn(1, "Unknown tar format -o option/value pair %s=%s", 347258164Smav opt->name, opt->value); 348208436Smav paxwarn(1,"%s=%s is the only supported tar format option", 349258164Smav TAR_OPTION, TAR_NODIR); 350208436Smav return(-1); 351231161Sjkim } 352208436Smav 353208436Smav /* 354208436Smav * we only support one option, and only when writing 355208436Smav */ 356208436Smav if ((act != APPND) && (act != ARCHIVE)) { 357208436Smav paxwarn(1, "%s=%s is only supported when writing.", 358169574Stakawata opt->name, opt->value); 359169574Stakawata return(-1); 360169574Stakawata } 361151912Sphk tar_nodir = 1; 362209371Smav } 363151912Sphk return(0); 364159217Snjl} 365159217Snjl 366269515Sroyger 367151912Sphk/* 368199016Savg * tar_rd() 369208436Smav * extract the values out of block already determined to be a tar header. 370169592Snjl * store the values in the ARCHD parameter. 371151912Sphk * Return: 372159217Snjl * 0 373151912Sphk */ 374151912Sphk 375151912Sphkint 376151912Sphktar_rd(ARCHD *arcn, char *buf) 377209371Smav{ 378151912Sphk HD_TAR *hd; 379209371Smav char *pt; 380209371Smav 381209371Smav /* 382209371Smav * we only get proper sized buffers passed to us 383209371Smav */ 384212238Smav if (tar_id(buf, BLKMULT) < 0) 385209371Smav return(-1); 386151912Sphk arcn->org_name = arcn->name; 387151912Sphk arcn->sb.st_nlink = 1; 388151912Sphk arcn->pat = NULL; 389151912Sphk 390151912Sphk /* 391151912Sphk * copy out the name and values in the stat buffer 392151912Sphk */ 393209371Smav hd = (HD_TAR *)buf; 394209371Smav arcn->nlen = l_strncpy(arcn->name, hd->name, sizeof(arcn->name) - 1); 395159217Snjl arcn->name[arcn->nlen] = '\0'; 396159217Snjl arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode,sizeof(hd->mode),OCT) & 397159217Snjl 0xfff); 398151912Sphk arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT); 399159217Snjl arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT); 400159217Snjl#ifdef NET2_STAT 401159217Snjl arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT); 402159217Snjl arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT); 403159217Snjl#else 404159217Snjl arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT); 405159217Snjl arcn->sb.st_mtime = (time_t)asc_uqd(hd->mtime, sizeof(hd->mtime), OCT); 406151912Sphk#endif 407171547Snjl arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 408175361Sjhb 409171547Snjl /* 410159217Snjl * have to look at the last character, it may be a '/' and that is used 411175385Sjhb * to encode this as a directory 412175361Sjhb */ 413175361Sjhb pt = &(arcn->name[arcn->nlen - 1]); 414175361Sjhb arcn->pad = 0; 415175361Sjhb arcn->skip = 0; 416175361Sjhb switch(hd->linkflag) { 417175361Sjhb case SYMTYPE: 418175361Sjhb /* 419209371Smav * symbolic link, need to get the link name and set the type in 420209440Smav * the st_mode so -v printing will look correct. 421209440Smav */ 422209440Smav arcn->type = PAX_SLK; 423209440Smav arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname, 424209371Smav sizeof(arcn->ln_name) - 1); 425209371Smav arcn->ln_name[arcn->ln_nlen] = '\0'; 426209371Smav arcn->sb.st_mode |= S_IFLNK; 427209371Smav break; 428209371Smav case LNKTYPE: 429209371Smav /* 430209371Smav * hard link, need to get the link name, set the type in the 431209371Smav * st_mode and st_nlink so -v printing will look better. 432209371Smav */ 433159217Snjl arcn->type = PAX_HLK; 434159217Snjl arcn->sb.st_nlink = 2; 435209371Smav arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname, 436209440Smav sizeof(arcn->ln_name) - 1); 437209440Smav arcn->ln_name[arcn->ln_nlen] = '\0'; 438209440Smav 439209440Smav /* 440159217Snjl * no idea of what type this thing really points at, but 441209371Smav * we set something for printing only. 442209371Smav */ 443209371Smav arcn->sb.st_mode |= S_IFREG; 444209371Smav break; 445209371Smav case DIRTYPE: 446209371Smav /* 447209371Smav * It is a directory, set the mode for -v printing 448212323Smav */ 449212323Smav arcn->type = PAX_DIR; 450209371Smav arcn->sb.st_mode |= S_IFDIR; 451209371Smav arcn->sb.st_nlink = 2; 452209371Smav arcn->ln_name[0] = '\0'; 453209371Smav arcn->ln_nlen = 0; 454209371Smav break; 455209371Smav case AREGTYPE: 456209371Smav case REGTYPE: 457209371Smav default: 458209371Smav /* 459209371Smav * If we have a trailing / this is a directory and NOT a file. 460209371Smav */ 461209371Smav arcn->ln_name[0] = '\0'; 462159217Snjl arcn->ln_nlen = 0; 463209371Smav if (*pt == '/') { 464171547Snjl /* 465171547Snjl * it is a directory, set the mode for -v printing 466171547Snjl */ 467171547Snjl arcn->type = PAX_DIR; 468175385Sjhb arcn->sb.st_mode |= S_IFDIR; 469171547Snjl arcn->sb.st_nlink = 2; 470175385Sjhb } else { 471171547Snjl /* 472171547Snjl * have a file that will be followed by data. Set the 473175361Sjhb * skip value to the size field and calculate the size 474171547Snjl * of the padding. 475171547Snjl */ 476171547Snjl arcn->type = PAX_REG; 477208436Smav arcn->sb.st_mode |= S_IFREG; 478208436Smav arcn->pad = TAR_PAD(arcn->sb.st_size); 479209371Smav arcn->skip = arcn->sb.st_size; 480209371Smav } 481209371Smav break; 482222222Sjkim } 483209371Smav 484209371Smav /* 485209371Smav * strip off any trailing slash. 486208436Smav */ 487209371Smav if (*pt == '/') { 488209371Smav *pt = '\0'; 489209371Smav --arcn->nlen; 490209371Smav } 491209440Smav return(0); 492209440Smav} 493209440Smav 494209440Smav/* 495209440Smav * tar_wr() 496209440Smav * write a tar header for the file specified in the ARCHD to the archive. 497209440Smav * Have to check for file types that cannot be stored and file names that 498209440Smav * are too long. Be careful of the term (last arg) to ul_oct, each field 499209440Smav * of tar has it own spec for the termination character(s). 500209440Smav * ASSUMED: space after header in header block is zero filled 501209440Smav * Return: 502209440Smav * 0 if file has data to be written after the header, 1 if file has NO 503212238Smav * data to write after the header, -1 if archive write failed 504212238Smav */ 505212238Smav 506209371Smavint 507209371Smavtar_wr(ARCHD *arcn) 508209371Smav{ 509209371Smav HD_TAR *hd; 510209371Smav int len; 511209371Smav char hdblk[sizeof(HD_TAR)]; 512209371Smav 513240286Smav /* 514212238Smav * check for those file system types which tar cannot store 515212238Smav */ 516213302Smav switch(arcn->type) { 517213302Smav case PAX_DIR: 518213302Smav /* 519213302Smav * user asked that dirs not be written to the archive 520213302Smav */ 521213302Smav if (tar_nodir) 522232797Smav return(1); 523232797Smav break; 524232797Smav case PAX_CHR: 525232797Smav paxwarn(1, "Tar cannot archive a character device %s", 526232797Smav arcn->org_name); 527232797Smav return(1); 528232797Smav case PAX_BLK: 529212238Smav paxwarn(1, "Tar cannot archive a block device %s", arcn->org_name); 530212238Smav return(1); 531215473Sjhb case PAX_SCK: 532212238Smav paxwarn(1, "Tar cannot archive a socket %s", arcn->org_name); 533212238Smav return(1); 534212238Smav case PAX_FIF: 535212238Smav paxwarn(1, "Tar cannot archive a fifo %s", arcn->org_name); 536212238Smav return(1); 537212238Smav case PAX_SLK: 538212238Smav case PAX_HLK: 539212533Smav case PAX_HRG: 540212533Smav if (arcn->ln_nlen > sizeof(hd->linkname)) { 541212533Smav paxwarn(1,"Link name too long for tar %s", arcn->ln_name); 542212533Smav return(1); 543212533Smav } 544212238Smav break; 545212238Smav case PAX_REG: 546212238Smav case PAX_CTG: 547212238Smav default: 548212238Smav break; 549212238Smav } 550212238Smav 551209371Smav /* 552209371Smav * check file name len, remember extra char for dirs (the / at the end) 553209440Smav */ 554209440Smav len = arcn->nlen; 555209371Smav if (arcn->type == PAX_DIR) 556209440Smav ++len; 557209371Smav if (len >= sizeof(hd->name)) { 558209371Smav paxwarn(1, "File name too long for tar %s", arcn->name); 559209371Smav return(1); 560209371Smav } 561269897Sneel 562269897Sneel /* 563209440Smav * copy the data out of the ARCHD into the tar header based on the type 564209440Smav * of the file. Remember many tar readers want the unused fields to be 565209440Smav * padded with zero. We set the linkflag field (type), the linkname 566212238Smav * (or zero if not used),the size, and set the padding (if any) to be 567212238Smav * added after the file data (0 for all other types, as they only have 568212238Smav * a header) 569212238Smav */ 570209440Smav hd = (HD_TAR *)hdblk; 571216263Sjhb l_strncpy(hd->name, arcn->name, sizeof(hd->name) - 1); 572216490Sjhb hd->name[sizeof(hd->name) - 1] = '\0'; 573216490Sjhb arcn->pad = 0; 574216490Sjhb 575209440Smav if (arcn->type == PAX_DIR) { 576209440Smav /* 577209440Smav * directories are the same as files, except have a filename 578216490Sjhb * that ends with a /, we add the slash here. No data follows, 579216490Sjhb * dirs, so no pad. 580216490Sjhb */ 581209440Smav hd->linkflag = AREGTYPE; 582209440Smav memset(hd->linkname, 0, sizeof(hd->linkname)); 583209440Smav hd->name[len-1] = '/'; 584209371Smav if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) 585209371Smav goto out; 586209371Smav } else if (arcn->type == PAX_SLK) { 587209371Smav /* 588209371Smav * no data follows this file, so no pad 589209440Smav */ 590209440Smav hd->linkflag = SYMTYPE; 591209371Smav l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1); 592209371Smav hd->linkname[sizeof(hd->linkname) - 1] = '\0'; 593209371Smav if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) 594209371Smav goto out; 595209440Smav } else if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) { 596209440Smav /* 597209440Smav * no data follows this file, so no pad 598209440Smav */ 599209440Smav hd->linkflag = LNKTYPE; 600212533Smav l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1); 601209440Smav hd->linkname[sizeof(hd->linkname) - 1] = '\0'; 602209440Smav if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) 603209440Smav goto out; 604209440Smav } else { 605209440Smav /* 606209440Smav * data follows this file, so set the pad 607209440Smav */ 608209440Smav hd->linkflag = AREGTYPE; 609212323Smav memset(hd->linkname, 0, sizeof(hd->linkname)); 610209440Smav# ifdef NET2_STAT 611209440Smav if (ul_oct((u_long)arcn->sb.st_size, hd->size, 612209440Smav sizeof(hd->size), 1)) { 613209440Smav# else 614209440Smav if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size, 615209440Smav sizeof(hd->size), 1)) { 616212238Smav# endif 617212238Smav paxwarn(1,"File is too large for tar %s", arcn->org_name); 618209440Smav return(1); 619209371Smav } 620209371Smav arcn->pad = TAR_PAD(arcn->sb.st_size); 621215473Sjhb } 622209371Smav 623209371Smav /* 624209371Smav * copy those fields that are independent of the type 625209371Smav */ 626216263Sjhb if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) || 627216490Sjhb ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 0) || 628216490Sjhb ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 0) || 629216490Sjhb ul_oct((u_long)arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1)) 630216490Sjhb goto out; 631216490Sjhb 632216490Sjhb /* 633209371Smav * calculate and add the checksum, then write the header. A return of 634209371Smav * 0 tells the caller to now write the file data, 1 says no data needs 635209371Smav * to be written 636209371Smav */ 637209371Smav if (ul_oct(tar_chksm(hdblk, sizeof(HD_TAR)), hd->chksum, 638209371Smav sizeof(hd->chksum), 3)) 639209371Smav goto out; 640209371Smav if (wr_rdbuf(hdblk, sizeof(HD_TAR)) < 0) 641209371Smav return(-1); 642209371Smav if (wr_skip((off_t)(BLKMULT - sizeof(HD_TAR))) < 0) 643209371Smav return(-1); 644209371Smav if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG)) 645209440Smav return(0); 646209371Smav return(1); 647209440Smav 648209440Smav out: 649209440Smav /* 650209371Smav * header field is out of range 651212238Smav */ 652209371Smav paxwarn(1, "Tar header field is too small for %s", arcn->org_name); 653209371Smav return(1); 654209371Smav} 655209371Smav 656209371Smav/* 657209371Smav * Routines for POSIX ustar 658209371Smav */ 659209371Smav 660209371Smav/* 661209371Smav * ustar_strd() 662209371Smav * initialization for ustar read 663209371Smav * Return: 664209371Smav * 0 if ok, -1 otherwise 665209371Smav */ 666209371Smav 667212238Smavint 668212238Smavustar_strd(void) 669212238Smav{ 670209371Smav if ((usrtb_start() < 0) || (grptb_start() < 0)) 671209371Smav return(-1); 672209371Smav return(0); 673209371Smav} 674209371Smav 675209371Smav/* 676209371Smav * ustar_stwr() 677209371Smav * initialization for ustar write 678209371Smav * Return: 679209371Smav * 0 if ok, -1 otherwise 680209371Smav */ 681209371Smav 682209371Smavint 683209371Smavustar_stwr(void) 684209371Smav{ 685209371Smav if ((uidtb_start() < 0) || (gidtb_start() < 0)) 686209371Smav return(-1); 687209371Smav return(0); 688248170Smav} 689248154Smav 690209371Smav/* 691209371Smav * ustar_id() 692209371Smav * determine if a block given to us is a valid ustar header. We have to 693247463Smav * be on the lookout for those pesky blocks of all zero's 694247463Smav * Return: 695247463Smav * 0 if a ustar header, -1 otherwise 696209371Smav */ 697209371Smav 698209371Smavint 699209371Smavustar_id(char *blk, int size) 700209371Smav{ 701209371Smav HD_USTAR *hd; 702209371Smav 703209371Smav if (size < BLKMULT) 704159217Snjl return(-1); 705159217Snjl hd = (HD_USTAR *)blk; 706159217Snjl 707159217Snjl /* 708209371Smav * check for block of zero's first, a simple and fast test then check 709159217Snjl * ustar magic cookie. We should use TMAGLEN, but some USTAR archive 710159217Snjl * programs are fouled up and create archives missing the \0. Last we 711159217Snjl * check the checksum. If ok we have to assume it is a valid header. 712159217Snjl */ 713159217Snjl if (hd->name[0] == '\0') 714159217Snjl return(-1); 715159217Snjl if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0) 716168010Snjl return(-1); 717209371Smav if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT)) 718175361Sjhb return(-1); 719212541Smav return(0); 720175361Sjhb} 721175361Sjhb 722175361Sjhb/* 723175361Sjhb * ustar_rd() 724175361Sjhb * extract the values out of block already determined to be a ustar header. 725175361Sjhb * store the values in the ARCHD parameter. 726212541Smav * Return: 727212541Smav * 0 728175361Sjhb */ 729175361Sjhb 730175361Sjhbint 731175361Sjhbustar_rd(ARCHD *arcn, char *buf) 732175361Sjhb{ 733209371Smav HD_USTAR *hd; 734168010Snjl char *dest; 735209371Smav int cnt = 0; 736209371Smav dev_t devmajor; 737209371Smav dev_t devminor; 738168010Snjl 739168010Snjl /* 740168010Snjl * we only get proper sized buffers 741175361Sjhb */ 742209371Smav if (ustar_id(buf, BLKMULT) < 0) 743209371Smav return(-1); 744209371Smav arcn->org_name = arcn->name; 745209371Smav arcn->sb.st_nlink = 1; 746209440Smav arcn->pat = NULL; 747209371Smav arcn->nlen = 0; 748209371Smav hd = (HD_USTAR *)buf; 749209371Smav 750209371Smav /* 751209371Smav * see if the filename is split into two parts. if, so joint the parts. 752209371Smav * we copy the prefix first and add a / between the prefix and name. 753209371Smav */ 754209371Smav dest = arcn->name; 755209371Smav if (*(hd->prefix) != '\0') { 756209371Smav cnt = l_strncpy(dest, hd->prefix, sizeof(arcn->name) - 2); 757209371Smav dest += cnt; 758209371Smav *dest++ = '/'; 759209371Smav cnt++; 760209371Smav } 761209371Smav arcn->nlen = cnt + l_strncpy(dest, hd->name, sizeof(arcn->name) - cnt); 762212491Smav arcn->name[arcn->nlen] = '\0'; 763209371Smav 764209371Smav /* 765212491Smav * follow the spec to the letter. we should only have mode bits, strip 766209371Smav * off all other crud we may be passed. 767209371Smav */ 768209371Smav arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode, sizeof(hd->mode), OCT) & 769212491Smav 0xfff); 770209371Smav#ifdef NET2_STAT 771209371Smav arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT); 772209371Smav arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT); 773209371Smav#else 774212491Smav arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT); 775209371Smav arcn->sb.st_mtime = (time_t)asc_uqd(hd->mtime, sizeof(hd->mtime), OCT); 776212491Smav#endif 777209371Smav arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 778209371Smav 779209371Smav /* 780209371Smav * If we can find the ascii names for gname and uname in the password 781168010Snjl * and group files we will use the uid's and gid they bind. Otherwise 782168010Snjl * we use the uid and gid values stored in the header. (This is what 783168010Snjl * the POSIX spec wants). 784159217Snjl */ 785159217Snjl hd->gname[sizeof(hd->gname) - 1] = '\0'; 786209371Smav if (gid_name(hd->gname, &(arcn->sb.st_gid)) < 0) 787159217Snjl arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT); 788151912Sphk hd->uname[sizeof(hd->uname) - 1] = '\0'; 789151912Sphk if (uid_name(hd->uname, &(arcn->sb.st_uid)) < 0) 790151912Sphk arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT); 791151912Sphk 792151912Sphk /* 793151912Sphk * set the defaults, these may be changed depending on the file type 794151912Sphk */ 795151912Sphk arcn->ln_name[0] = '\0'; 796175385Sjhb arcn->ln_nlen = 0; 797151912Sphk arcn->pad = 0; 798175385Sjhb arcn->skip = 0; 799151912Sphk arcn->sb.st_rdev = (dev_t)0; 800175385Sjhb 801151912Sphk /* 802151912Sphk * set the mode and PAX type according to the typeflag in the header 803151912Sphk */ 804151912Sphk switch(hd->typeflag) { 805151912Sphk case FIFOTYPE: 806151912Sphk arcn->type = PAX_FIF; 807159217Snjl arcn->sb.st_mode |= S_IFIFO; 808151912Sphk break; 809151912Sphk case DIRTYPE: 810159217Snjl arcn->type = PAX_DIR; 811151912Sphk arcn->sb.st_mode |= S_IFDIR; 812151912Sphk arcn->sb.st_nlink = 2; 813209371Smav 814209371Smav /* 815209371Smav * Some programs that create ustar archives append a '/' 816209371Smav * to the pathname for directories. This clearly violates 817209371Smav * ustar specs, but we will silently strip it off anyway. 818209371Smav */ 819209371Smav if (arcn->name[arcn->nlen - 1] == '/') 820209371Smav arcn->name[--arcn->nlen] = '\0'; 821209371Smav break; 822209371Smav case BLKTYPE: 823209371Smav case CHRTYPE: 824209371Smav /* 825209371Smav * this type requires the rdev field to be set. 826209371Smav */ 827209371Smav if (hd->typeflag == BLKTYPE) { 828209371Smav arcn->type = PAX_BLK; 829209371Smav arcn->sb.st_mode |= S_IFBLK; 830209371Smav } else { 831209371Smav arcn->type = PAX_CHR; 832209371Smav arcn->sb.st_mode |= S_IFCHR; 833209371Smav } 834209371Smav devmajor = (dev_t)asc_ul(hd->devmajor,sizeof(hd->devmajor),OCT); 835209371Smav devminor = (dev_t)asc_ul(hd->devminor,sizeof(hd->devminor),OCT); 836209371Smav arcn->sb.st_rdev = TODEV(devmajor, devminor); 837209371Smav break; 838209371Smav case SYMTYPE: 839209371Smav case LNKTYPE: 840209371Smav if (hd->typeflag == SYMTYPE) { 841209371Smav arcn->type = PAX_SLK; 842209371Smav arcn->sb.st_mode |= S_IFLNK; 843151912Sphk } else { 844209371Smav arcn->type = PAX_HLK; 845209371Smav /* 846209371Smav * so printing looks better 847209371Smav */ 848209371Smav arcn->sb.st_mode |= S_IFREG; 849209371Smav arcn->sb.st_nlink = 2; 850151912Sphk } 851209371Smav /* 852209371Smav * copy the link name 853209371Smav */ 854209371Smav arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname, 855246128Ssbz sizeof(arcn->ln_name) - 1); 856151912Sphk arcn->ln_name[arcn->ln_nlen] = '\0'; 857151912Sphk break; 858209371Smav case CONTTYPE: 859209371Smav case AREGTYPE: 860209371Smav case REGTYPE: 861209371Smav default: 862151912Sphk /* 863151912Sphk * these types have file data that follows. Set the skip and 864209371Smav * pad fields. 865209371Smav */ 866 arcn->type = PAX_REG; 867 arcn->pad = TAR_PAD(arcn->sb.st_size); 868 arcn->skip = arcn->sb.st_size; 869 arcn->sb.st_mode |= S_IFREG; 870 break; 871 } 872 return(0); 873} 874 875/* 876 * ustar_wr() 877 * write a ustar header for the file specified in the ARCHD to the archive 878 * Have to check for file types that cannot be stored and file names that 879 * are too long. Be careful of the term (last arg) to ul_oct, we only use 880 * '\0' for the termination character (this is different than picky tar) 881 * ASSUMED: space after header in header block is zero filled 882 * Return: 883 * 0 if file has data to be written after the header, 1 if file has NO 884 * data to write after the header, -1 if archive write failed 885 */ 886 887int 888ustar_wr(ARCHD *arcn) 889{ 890 HD_USTAR *hd; 891 char *pt; 892 char hdblk[sizeof(HD_USTAR)]; 893 894 /* 895 * check for those file system types ustar cannot store 896 */ 897 if (arcn->type == PAX_SCK) { 898 paxwarn(1, "Ustar cannot archive a socket %s", arcn->org_name); 899 return(1); 900 } 901 902 /* 903 * check the length of the linkname 904 */ 905 if (((arcn->type == PAX_SLK) || (arcn->type == PAX_HLK) || 906 (arcn->type == PAX_HRG)) && (arcn->ln_nlen >= sizeof(hd->linkname))){ 907 paxwarn(1, "Link name too long for ustar %s", arcn->ln_name); 908 return(1); 909 } 910 911 /* 912 * split the path name into prefix and name fields (if needed). if 913 * pt != arcn->name, the name has to be split 914 */ 915 if ((pt = name_split(arcn->name, arcn->nlen)) == NULL) { 916 paxwarn(1, "File name too long for ustar %s", arcn->name); 917 return(1); 918 } 919 hd = (HD_USTAR *)hdblk; 920 arcn->pad = 0L; 921 922 /* 923 * split the name, or zero out the prefix 924 */ 925 if (pt != arcn->name) { 926 /* 927 * name was split, pt points at the / where the split is to 928 * occur, we remove the / and copy the first part to the prefix 929 */ 930 *pt = '\0'; 931 l_strncpy(hd->prefix, arcn->name, sizeof(hd->prefix) - 1); 932 *pt++ = '/'; 933 } else 934 memset(hd->prefix, 0, sizeof(hd->prefix)); 935 936 /* 937 * copy the name part. this may be the whole path or the part after 938 * the prefix 939 */ 940 l_strncpy(hd->name, pt, sizeof(hd->name) - 1); 941 hd->name[sizeof(hd->name) - 1] = '\0'; 942 943 /* 944 * set the fields in the header that are type dependent 945 */ 946 switch(arcn->type) { 947 case PAX_DIR: 948 hd->typeflag = DIRTYPE; 949 memset(hd->linkname, 0, sizeof(hd->linkname)); 950 memset(hd->devmajor, 0, sizeof(hd->devmajor)); 951 memset(hd->devminor, 0, sizeof(hd->devminor)); 952 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) 953 goto out; 954 break; 955 case PAX_CHR: 956 case PAX_BLK: 957 if (arcn->type == PAX_CHR) 958 hd->typeflag = CHRTYPE; 959 else 960 hd->typeflag = BLKTYPE; 961 memset(hd->linkname, 0, sizeof(hd->linkname)); 962 if (ul_oct((u_long)MAJOR(arcn->sb.st_rdev), hd->devmajor, 963 sizeof(hd->devmajor), 3) || 964 ul_oct((u_long)MINOR(arcn->sb.st_rdev), hd->devminor, 965 sizeof(hd->devminor), 3) || 966 ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) 967 goto out; 968 break; 969 case PAX_FIF: 970 hd->typeflag = FIFOTYPE; 971 memset(hd->linkname, 0, sizeof(hd->linkname)); 972 memset(hd->devmajor, 0, sizeof(hd->devmajor)); 973 memset(hd->devminor, 0, sizeof(hd->devminor)); 974 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) 975 goto out; 976 break; 977 case PAX_SLK: 978 case PAX_HLK: 979 case PAX_HRG: 980 if (arcn->type == PAX_SLK) 981 hd->typeflag = SYMTYPE; 982 else 983 hd->typeflag = LNKTYPE; 984 l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1); 985 hd->linkname[sizeof(hd->linkname) - 1] = '\0'; 986 memset(hd->devmajor, 0, sizeof(hd->devmajor)); 987 memset(hd->devminor, 0, sizeof(hd->devminor)); 988 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) 989 goto out; 990 break; 991 case PAX_REG: 992 case PAX_CTG: 993 default: 994 /* 995 * file data with this type, set the padding 996 */ 997 if (arcn->type == PAX_CTG) 998 hd->typeflag = CONTTYPE; 999 else 1000 hd->typeflag = REGTYPE; 1001 memset(hd->linkname, 0, sizeof(hd->linkname)); 1002 memset(hd->devmajor, 0, sizeof(hd->devmajor)); 1003 memset(hd->devminor, 0, sizeof(hd->devminor)); 1004 arcn->pad = TAR_PAD(arcn->sb.st_size); 1005# ifdef NET2_STAT 1006 if (ul_oct((u_long)arcn->sb.st_size, hd->size, 1007 sizeof(hd->size), 3)) { 1008# else 1009 if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size, 1010 sizeof(hd->size), 3)) { 1011# endif 1012 paxwarn(1,"File is too long for ustar %s",arcn->org_name); 1013 return(1); 1014 } 1015 break; 1016 } 1017 1018 l_strncpy(hd->magic, TMAGIC, TMAGLEN); 1019 l_strncpy(hd->version, TVERSION, TVERSLEN); 1020 1021 /* 1022 * set the remaining fields. Some versions want all 16 bits of mode 1023 * we better humor them (they really do not meet spec though).... 1024 */ 1025 if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3) || 1026 ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3) || 1027 ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3) || 1028 ul_oct((u_long)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3)) 1029 goto out; 1030 l_strncpy(hd->uname,name_uid(arcn->sb.st_uid, 0),sizeof(hd->uname)); 1031 l_strncpy(hd->gname,name_gid(arcn->sb.st_gid, 0),sizeof(hd->gname)); 1032 1033 /* 1034 * calculate and store the checksum write the header to the archive 1035 * return 0 tells the caller to now write the file data, 1 says no data 1036 * needs to be written 1037 */ 1038 if (ul_oct(tar_chksm(hdblk, sizeof(HD_USTAR)), hd->chksum, 1039 sizeof(hd->chksum), 3)) 1040 goto out; 1041 if (wr_rdbuf(hdblk, sizeof(HD_USTAR)) < 0) 1042 return(-1); 1043 if (wr_skip((off_t)(BLKMULT - sizeof(HD_USTAR))) < 0) 1044 return(-1); 1045 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG)) 1046 return(0); 1047 return(1); 1048 1049 out: 1050 /* 1051 * header field is out of range 1052 */ 1053 paxwarn(1, "Ustar header field is too small for %s", arcn->org_name); 1054 return(1); 1055} 1056 1057/* 1058 * name_split() 1059 * see if the name has to be split for storage in a ustar header. We try 1060 * to fit the entire name in the name field without splitting if we can. 1061 * The split point is always at a / 1062 * Return 1063 * character pointer to split point (always the / that is to be removed 1064 * if the split is not needed, the points is set to the start of the file 1065 * name (it would violate the spec to split there). A NULL is returned if 1066 * the file name is too long 1067 */ 1068 1069static char * 1070name_split(char *name, int len) 1071{ 1072 char *start; 1073 1074 /* 1075 * check to see if the file name is small enough to fit in the name 1076 * field. if so just return a pointer to the name. 1077 */ 1078 if (len < TNMSZ) 1079 return(name); 1080 if (len > (TPFSZ + TNMSZ)) 1081 return(NULL); 1082 1083 /* 1084 * we start looking at the biggest sized piece that fits in the name 1085 * field. We walk forward looking for a slash to split at. The idea is 1086 * to find the biggest piece to fit in the name field (or the smallest 1087 * prefix we can find) 1088 */ 1089 start = name + len - TNMSZ; 1090 while ((*start != '\0') && (*start != '/')) 1091 ++start; 1092 1093 /* 1094 * if we hit the end of the string, this name cannot be split, so we 1095 * cannot store this file. 1096 */ 1097 if (*start == '\0') 1098 return(NULL); 1099 len = start - name; 1100 1101 /* 1102 * NOTE: /str where the length of str == TNMSZ can not be stored under 1103 * the p1003.1-1990 spec for ustar. We could force a prefix of / and 1104 * the file would then expand on extract to //str. The len == 0 below 1105 * makes this special case follow the spec to the letter. 1106 */ 1107 if ((len >= TPFSZ) || (len == 0)) 1108 return(NULL); 1109 1110 /* 1111 * ok have a split point, return it to the caller 1112 */ 1113 return(start); 1114} 1115