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