1*57110Smuller /*- 2*57110Smuller * Copyright (c) 1992 Keith Muller. 3*57110Smuller * Copyright (c) 1992 The Regents of the University of California. 4*57110Smuller * All rights reserved. 5*57110Smuller * 6*57110Smuller * This code is derived from software contributed to Berkeley by 7*57110Smuller * Keith Muller of the University of California, San Diego. 8*57110Smuller * 9*57110Smuller * %sccs.include.redist.c% 10*57110Smuller */ 11*57110Smuller 12*57110Smuller #ifndef lint 13*57110Smuller static char sccsid[] = "@(#)file_subs.c 1.1 (Berkeley) 12/13/92"; 14*57110Smuller #endif /* not lint */ 15*57110Smuller 16*57110Smuller #include <sys/types.h> 17*57110Smuller #include <sys/time.h> 18*57110Smuller #include <sys/stat.h> 19*57110Smuller #include <unistd.h> 20*57110Smuller #include <sys/param.h> 21*57110Smuller #include <fcntl.h> 22*57110Smuller #include <string.h> 23*57110Smuller #include <stdio.h> 24*57110Smuller #include <ctype.h> 25*57110Smuller #include <errno.h> 26*57110Smuller #include <sys/uio.h> 27*57110Smuller #include <stdlib.h> 28*57110Smuller #include "pax.h" 29*57110Smuller #include "extern.h" 30*57110Smuller 31*57110Smuller static int 32*57110Smuller mk_link __P((register char *,register struct stat *,register char *, int)); 33*57110Smuller 34*57110Smuller /* 35*57110Smuller * routines that deal with file operations such as: creating, removing; 36*57110Smuller * and setting access modes, uid/gid and times of files 37*57110Smuller */ 38*57110Smuller 39*57110Smuller #define FILEBITS (S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) 40*57110Smuller #define SETBITS (S_ISUID | S_ISGID) 41*57110Smuller #define ABITS (FILEBITS | SETBITS) 42*57110Smuller 43*57110Smuller /* 44*57110Smuller * file_creat() 45*57110Smuller * Create and open a file. 46*57110Smuller * Return: 47*57110Smuller * file descriptor or -1 for failure 48*57110Smuller */ 49*57110Smuller 50*57110Smuller #if __STDC__ 51*57110Smuller int 52*57110Smuller file_creat(register ARCHD *arcn) 53*57110Smuller #else 54*57110Smuller int 55*57110Smuller file_creat(arcn) 56*57110Smuller register ARCHD *arcn; 57*57110Smuller #endif 58*57110Smuller { 59*57110Smuller int fd = -1; 60*57110Smuller mode_t file_mode; 61*57110Smuller int oerrno; 62*57110Smuller 63*57110Smuller /* 64*57110Smuller * assume file doesn't exist, so just try to create it, most times this 65*57110Smuller * works. We have to take special handling when the file does exist. To 66*57110Smuller * detect this, we use O_EXCL. For example when trying to create a 67*57110Smuller * file and a character device or fifo exists with the same name, we 68*57110Smuller * can accidently open the device by mistake (or block waiting to open) 69*57110Smuller * If we find that the open has failed, then figure spend the effore to 70*57110Smuller * figure out why. This strategy was found to have better average 71*57110Smuller * performance in common use than checking the file (and the path) 72*57110Smuller * first with lstat. 73*57110Smuller */ 74*57110Smuller file_mode = arcn->sb.st_mode & FILEBITS; 75*57110Smuller if ((fd = open(arcn->name, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 76*57110Smuller file_mode)) >= 0) 77*57110Smuller return(fd); 78*57110Smuller 79*57110Smuller /* 80*57110Smuller * the file seems to exist. First we try to get rid of it (found to be 81*57110Smuller * the second most common failure when traced). If this fails, only 82*57110Smuller * then we go to the expense to check and create the path to the file 83*57110Smuller */ 84*57110Smuller if (unlnk_exist(arcn->name, arcn->type) != 0) 85*57110Smuller return(-1); 86*57110Smuller 87*57110Smuller for (;;) { 88*57110Smuller /* 89*57110Smuller * try to open it again, if this fails, check all the nodes in 90*57110Smuller * the path and give it a final try. if chk_path() finds that 91*57110Smuller * it cannot fix anything, we will skip the last attempt 92*57110Smuller */ 93*57110Smuller if ((fd = open(arcn->name, O_WRONLY | O_CREAT | O_TRUNC, 94*57110Smuller file_mode)) >= 0) 95*57110Smuller break; 96*57110Smuller oerrno = errno; 97*57110Smuller if (chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) { 98*57110Smuller syswarn(1, oerrno, "Unable to create %s", arcn->name); 99*57110Smuller return(-1); 100*57110Smuller } 101*57110Smuller } 102*57110Smuller return(fd); 103*57110Smuller } 104*57110Smuller 105*57110Smuller /* 106*57110Smuller * file_close() 107*57110Smuller * Close file descriptor to a file just created by pax. Sets modes, 108*57110Smuller * ownership and times as required. 109*57110Smuller * Return: 110*57110Smuller * 0 for success, -1 for failure 111*57110Smuller */ 112*57110Smuller 113*57110Smuller #if __STDC__ 114*57110Smuller void 115*57110Smuller file_close(register ARCHD *arcn, int fd) 116*57110Smuller #else 117*57110Smuller void 118*57110Smuller file_close(arcn, fd) 119*57110Smuller register ARCHD *arcn; 120*57110Smuller int fd; 121*57110Smuller #endif 122*57110Smuller { 123*57110Smuller int res = 0; 124*57110Smuller 125*57110Smuller if (fd < 0) 126*57110Smuller return; 127*57110Smuller if (close(fd) < 0) 128*57110Smuller syswarn(0, errno, "Unable to close file descriptor on %s", 129*57110Smuller arcn->name); 130*57110Smuller 131*57110Smuller /* 132*57110Smuller * set owner/groups first as this may strip off mode bits we want 133*57110Smuller * then set file permission modes. Then set file access and 134*57110Smuller * modification times. 135*57110Smuller */ 136*57110Smuller if (pids) 137*57110Smuller res = set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid); 138*57110Smuller 139*57110Smuller /* 140*57110Smuller * IMPORTANT SECURITY NOTE: 141*57110Smuller * if not preserving mode or whe cannot set uid/gid, then PROHIBIT 142*57110Smuller * set uid/gid bits 143*57110Smuller */ 144*57110Smuller if (!pmode || res) 145*57110Smuller arcn->sb.st_mode &= ~(SETBITS); 146*57110Smuller if (pmode) 147*57110Smuller set_pmode(arcn->name, arcn->sb.st_mode); 148*57110Smuller if (patime || pmtime) 149*57110Smuller set_ftime(arcn->name, arcn->sb.st_mtime, arcn->sb.st_atime, 0); 150*57110Smuller } 151*57110Smuller 152*57110Smuller /* 153*57110Smuller * lnk_creat() 154*57110Smuller * Create a hard link to arcn->ln_name from arcn->name. arcn->ln_name 155*57110Smuller * must exist; 156*57110Smuller * Return: 157*57110Smuller * 0 if ok, -1 otherwise 158*57110Smuller */ 159*57110Smuller 160*57110Smuller #if __STDC__ 161*57110Smuller int 162*57110Smuller lnk_creat(register ARCHD *arcn) 163*57110Smuller #else 164*57110Smuller int 165*57110Smuller lnk_creat(arcn) 166*57110Smuller register ARCHD *arcn; 167*57110Smuller #endif 168*57110Smuller { 169*57110Smuller struct stat sb; 170*57110Smuller 171*57110Smuller /* 172*57110Smuller * we may be running as root, so we have to be sure that link target 173*57110Smuller * is not a directory, so we lstat and check 174*57110Smuller */ 175*57110Smuller if (lstat(arcn->ln_name, &sb) < 0) { 176*57110Smuller syswarn(1,errno,"Unable to link to %s from %s", arcn->ln_name, 177*57110Smuller arcn->name); 178*57110Smuller return(-1); 179*57110Smuller } 180*57110Smuller 181*57110Smuller if (S_ISDIR(sb.st_mode)) { 182*57110Smuller warn(1, "A hard links to the directory %s is not allowed", 183*57110Smuller arcn->ln_name); 184*57110Smuller return(-1); 185*57110Smuller } 186*57110Smuller 187*57110Smuller return(mk_link(arcn->ln_name, &sb, arcn->name, 0)); 188*57110Smuller } 189*57110Smuller 190*57110Smuller /* 191*57110Smuller * cross_lnk() 192*57110Smuller * Create a hard link to arcn->org_name from arcn->name. Only used in copy 193*57110Smuller * with the -l flag. No warning or error if this does not succeed (we will 194*57110Smuller * then just create the file) 195*57110Smuller * Return: 196*57110Smuller * 1 if copy() should try to create this file node 197*57110Smuller * 0 if cross_lnk() ok, -1 for fatal flaw (like linking to self). 198*57110Smuller */ 199*57110Smuller 200*57110Smuller #if __STDC__ 201*57110Smuller int 202*57110Smuller cross_lnk(register ARCHD *arcn) 203*57110Smuller #else 204*57110Smuller int 205*57110Smuller cross_lnk(arcn) 206*57110Smuller register ARCHD *arcn; 207*57110Smuller #endif 208*57110Smuller { 209*57110Smuller /* 210*57110Smuller * try to make a link to orginal file (-l flag in copy mode). make sure 211*57110Smuller * we do not try to link to directories in case we are running as root 212*57110Smuller * (and it might succeed). 213*57110Smuller */ 214*57110Smuller if (arcn->type == PAX_DIR) 215*57110Smuller return(1); 216*57110Smuller return(mk_link(arcn->org_name, &(arcn->sb), arcn->name, 1)); 217*57110Smuller } 218*57110Smuller 219*57110Smuller /* 220*57110Smuller * chk_same() 221*57110Smuller * In copy mode, if we are not trying to make hard links between the src 222*57110Smuller * and destinations, make sure we are not going to overwrite ourselves by 223*57110Smuller * accident. This slows things down a little, but we have to protect all 224*57110Smuller * those people who make typing errors. 225*57110Smuller * Return: 226*57110Smuller * 1 the target does not exist, go ahead and copy 227*57110Smuller * 0 skip it file exists (-k) or may be the same as source file 228*57110Smuller */ 229*57110Smuller 230*57110Smuller #if __STDC__ 231*57110Smuller int 232*57110Smuller chk_same(register ARCHD *arcn) 233*57110Smuller #else 234*57110Smuller int 235*57110Smuller chk_same(arcn) 236*57110Smuller register ARCHD *arcn; 237*57110Smuller #endif 238*57110Smuller { 239*57110Smuller struct stat sb; 240*57110Smuller 241*57110Smuller /* 242*57110Smuller * if file does not exist, return. if file exists and -k, skip it 243*57110Smuller * quietly 244*57110Smuller */ 245*57110Smuller if (lstat(arcn->name, &sb) < 0) 246*57110Smuller return(1); 247*57110Smuller if (kflag) 248*57110Smuller return(0); 249*57110Smuller 250*57110Smuller /* 251*57110Smuller * better make sure the user does not have src == dest by mistake 252*57110Smuller */ 253*57110Smuller if ((arcn->sb.st_dev == sb.st_dev) && (arcn->sb.st_ino == sb.st_ino)) { 254*57110Smuller warn(1, "Unable to copy %s, file would overwrite itself", 255*57110Smuller arcn->name); 256*57110Smuller return(0); 257*57110Smuller } 258*57110Smuller return(1); 259*57110Smuller } 260*57110Smuller 261*57110Smuller /* 262*57110Smuller * mk_link() 263*57110Smuller * try to make a hard link between two files. if ign set, we do not 264*57110Smuller * complain. 265*57110Smuller * Return: 266*57110Smuller * 0 if successful (or we are done with this file but no error, such as 267*57110Smuller * finding the from file exists and the user has set -k). 268*57110Smuller * 1 when ign set, indicates we couldn't make the link but try to 269*57110Smuller * copy/extract the file as that might work. 270*57110Smuller * -1 an error occurred. 271*57110Smuller */ 272*57110Smuller 273*57110Smuller #if __STDC__ 274*57110Smuller static int 275*57110Smuller mk_link(register char *to, register struct stat *to_sb, register char *from, 276*57110Smuller int ign) 277*57110Smuller #else 278*57110Smuller static int 279*57110Smuller mk_link(to, to_sb, from, ign) 280*57110Smuller register char *to; 281*57110Smuller register struct stat *to_sb; 282*57110Smuller register char *from; 283*57110Smuller int ign; 284*57110Smuller #endif 285*57110Smuller { 286*57110Smuller struct stat sb; 287*57110Smuller int oerrno; 288*57110Smuller 289*57110Smuller /* 290*57110Smuller * if from file exists, it has to be unlinked to make the link. If the 291*57110Smuller * file exists and -k is set, skip it quietly 292*57110Smuller */ 293*57110Smuller if (lstat(from, &sb) == 0) { 294*57110Smuller if (kflag) 295*57110Smuller return(0); 296*57110Smuller 297*57110Smuller /* 298*57110Smuller * make sure it is not the same file, protect the user 299*57110Smuller */ 300*57110Smuller if ((to_sb->st_dev==sb.st_dev)&&(to_sb->st_ino == sb.st_ino)) { 301*57110Smuller warn(1, "Unable to link file %s to itself", to); 302*57110Smuller return(-1);; 303*57110Smuller } 304*57110Smuller 305*57110Smuller /* 306*57110Smuller * try to get rid of the file, based on the type 307*57110Smuller */ 308*57110Smuller if (S_ISDIR(sb.st_mode)) { 309*57110Smuller if (rmdir(from) < 0) { 310*57110Smuller syswarn(1, errno, "Unable to remove %s", from); 311*57110Smuller return(-1); 312*57110Smuller } 313*57110Smuller } else if (unlink(from) < 0) { 314*57110Smuller if (!ign) { 315*57110Smuller syswarn(1, errno, "Unable to remove %s", from); 316*57110Smuller return(-1); 317*57110Smuller } 318*57110Smuller return(1); 319*57110Smuller } 320*57110Smuller } 321*57110Smuller 322*57110Smuller /* 323*57110Smuller * from file is gone (or did not exist), try to make the hard link. 324*57110Smuller * if it fails, check the path and try it again (if chk_path() says to 325*57110Smuller * try again) 326*57110Smuller */ 327*57110Smuller for (;;) { 328*57110Smuller if (link(to, from) == 0) 329*57110Smuller break; 330*57110Smuller oerrno = errno; 331*57110Smuller if (chk_path(from, to_sb->st_uid, to_sb->st_gid) == 0) 332*57110Smuller continue; 333*57110Smuller if (!ign) { 334*57110Smuller syswarn(1, oerrno, "Could not link to %s from %s", to, 335*57110Smuller from); 336*57110Smuller return(-1); 337*57110Smuller } 338*57110Smuller return(1); 339*57110Smuller } 340*57110Smuller 341*57110Smuller /* 342*57110Smuller * all right the link was made 343*57110Smuller */ 344*57110Smuller return(0); 345*57110Smuller } 346*57110Smuller 347*57110Smuller /* 348*57110Smuller * node_creat() 349*57110Smuller * create an entry in the file system (other than a file or hard link). 350*57110Smuller * If successful, sets uid/gid modes and times as required. 351*57110Smuller * Return: 352*57110Smuller * 0 if ok, -1 otherwise 353*57110Smuller */ 354*57110Smuller 355*57110Smuller #if __STDC__ 356*57110Smuller int 357*57110Smuller node_creat(register ARCHD *arcn) 358*57110Smuller #else 359*57110Smuller int 360*57110Smuller node_creat(arcn) 361*57110Smuller register ARCHD *arcn; 362*57110Smuller #endif 363*57110Smuller { 364*57110Smuller register int res; 365*57110Smuller register int ign = 0; 366*57110Smuller register int oerrno; 367*57110Smuller register int pass = 0; 368*57110Smuller mode_t file_mode; 369*57110Smuller struct stat sb; 370*57110Smuller 371*57110Smuller /* 372*57110Smuller * create node based on type, if that fails try to unlink the node and 373*57110Smuller * try again. finally check the path and try again. As noted in the 374*57110Smuller * file and link creation routines, this method seems to exhibit the 375*57110Smuller * best performance in general use workloads. 376*57110Smuller */ 377*57110Smuller file_mode = arcn->sb.st_mode & FILEBITS; 378*57110Smuller 379*57110Smuller for (;;) { 380*57110Smuller switch(arcn->type) { 381*57110Smuller case PAX_DIR: 382*57110Smuller res = mkdir(arcn->name, file_mode); 383*57110Smuller if (ign) 384*57110Smuller res = 0; 385*57110Smuller break; 386*57110Smuller case PAX_CHR: 387*57110Smuller file_mode |= S_IFCHR; 388*57110Smuller res = mknod(arcn->name, file_mode, arcn->sb.st_rdev); 389*57110Smuller break; 390*57110Smuller case PAX_BLK: 391*57110Smuller file_mode |= S_IFBLK; 392*57110Smuller res = mknod(arcn->name, file_mode, arcn->sb.st_rdev); 393*57110Smuller break; 394*57110Smuller case PAX_FIF: 395*57110Smuller res = mkfifo(arcn->name, file_mode); 396*57110Smuller break; 397*57110Smuller case PAX_SCK: 398*57110Smuller /* 399*57110Smuller * Skip sockets, operation has no meaning under BSD 400*57110Smuller */ 401*57110Smuller warn(0, "%s not created, sockets are not supported", 402*57110Smuller arcn->name); 403*57110Smuller return(-1); 404*57110Smuller case PAX_SLK: 405*57110Smuller if ((res = symlink(arcn->ln_name, arcn->name)) == 0) 406*57110Smuller return(0); 407*57110Smuller break; 408*57110Smuller case PAX_CTG: 409*57110Smuller case PAX_HLK: 410*57110Smuller case PAX_HRG: 411*57110Smuller case PAX_REG: 412*57110Smuller /* 413*57110Smuller * should never be called to create these 414*57110Smuller */ 415*57110Smuller default: 416*57110Smuller warn(1,"Unknown file system type skip: %s",arcn->name); 417*57110Smuller return(-1); 418*57110Smuller } 419*57110Smuller 420*57110Smuller /* 421*57110Smuller * if we were able to create the node break out of the loop, 422*57110Smuller * otherwise try to unlink the node and try again. if that 423*57110Smuller * fails check the full path and try a final time. 424*57110Smuller */ 425*57110Smuller if (res == 0) 426*57110Smuller break; 427*57110Smuller 428*57110Smuller /* 429*57110Smuller * we failed to make the node 430*57110Smuller */ 431*57110Smuller oerrno = errno; 432*57110Smuller if ((ign = unlnk_exist(arcn->name, arcn->type)) < 0) 433*57110Smuller return(-1); 434*57110Smuller 435*57110Smuller if (++pass <= 1) 436*57110Smuller continue; 437*57110Smuller 438*57110Smuller if (chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) { 439*57110Smuller syswarn(1, oerrno, "Could not create: %s", arcn->name); 440*57110Smuller return(-1); 441*57110Smuller } 442*57110Smuller } 443*57110Smuller 444*57110Smuller /* 445*57110Smuller * we were able to create the node. set uid/gid, modes and times 446*57110Smuller */ 447*57110Smuller if (pids) 448*57110Smuller res = set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid); 449*57110Smuller else 450*57110Smuller res = 0; 451*57110Smuller 452*57110Smuller /* 453*57110Smuller * IMPORTANT SECURITY NOTE: 454*57110Smuller * if not preserving mode or whe cannot set uid/gid, then PROHIBIT any 455*57110Smuller * set uid/gid bits 456*57110Smuller */ 457*57110Smuller if (!pmode || res) 458*57110Smuller arcn->sb.st_mode &= ~(SETBITS); 459*57110Smuller if (pmode) 460*57110Smuller set_pmode(arcn->name, arcn->sb.st_mode); 461*57110Smuller 462*57110Smuller if (arcn->type == PAX_DIR) { 463*57110Smuller /* 464*57110Smuller * Dirs must be processed again at end of extract to set times 465*57110Smuller * and modes to agree with those stored in the archive. However 466*57110Smuller * to allow extract to continue, we may have to also set owner 467*57110Smuller * rights. This allows nodes in the archive that are children 468*57110Smuller * of this directory to be extracted without failure. Both time 469*57110Smuller * and modes will be fixed after the entire archive is read and 470*57110Smuller * before pax exits. 471*57110Smuller */ 472*57110Smuller if (access(arcn->name, R_OK | W_OK | X_OK) < 0) { 473*57110Smuller if (lstat(arcn->name, &sb) < 0) { 474*57110Smuller syswarn(0, errno,"Could not access %s (stat)", 475*57110Smuller arcn->name); 476*57110Smuller set_pmode(arcn->name,file_mode | S_IRWXU); 477*57110Smuller } else { 478*57110Smuller /* 479*57110Smuller * We have to add rights to the dir, so we make 480*57110Smuller * sure to restore the mode. The mode must be 481*57110Smuller * restored AS CREATED and not as stored if 482*57110Smuller * pmode is not set. 483*57110Smuller */ 484*57110Smuller set_pmode(arcn->name, 485*57110Smuller ((sb.st_mode & FILEBITS) | S_IRWXU)); 486*57110Smuller if (!pmode) 487*57110Smuller arcn->sb.st_mode = sb.st_mode; 488*57110Smuller } 489*57110Smuller 490*57110Smuller /* 491*57110Smuller * we have to force the mode to what was set here, 492*57110Smuller * since we changed it from the default as created. 493*57110Smuller */ 494*57110Smuller add_dir(arcn->name, arcn->nlen, &(arcn->sb), 1); 495*57110Smuller } else if (pmode || patime || pmtime) 496*57110Smuller add_dir(arcn->name, arcn->nlen, &(arcn->sb), 0); 497*57110Smuller } 498*57110Smuller 499*57110Smuller if (patime || pmtime) 500*57110Smuller set_ftime(arcn->name, arcn->sb.st_mtime, arcn->sb.st_atime, 0); 501*57110Smuller return(0); 502*57110Smuller } 503*57110Smuller 504*57110Smuller /* 505*57110Smuller * unlnk_exist() 506*57110Smuller * Remove node from file system with the specified name. We pass the type 507*57110Smuller * of the node that is going to replace it. When we try to create a 508*57110Smuller * directory and find that it already exists, we allow processing to 509*57110Smuller * continue as proper modes etc will always be set for it later on. 510*57110Smuller * Return: 511*57110Smuller * 0 is ok to proceed, no file with the specified name exists 512*57110Smuller * -1 we were unable to remove the node, or we should not remove it (-k) 513*57110Smuller * 1 we found a directory and we were going to create a directory. 514*57110Smuller */ 515*57110Smuller 516*57110Smuller #if __STDC__ 517*57110Smuller int 518*57110Smuller unlnk_exist(register char *name, register int type) 519*57110Smuller #else 520*57110Smuller int 521*57110Smuller unlnk_exist(name, type) 522*57110Smuller register char *name; 523*57110Smuller register int type; 524*57110Smuller #endif 525*57110Smuller { 526*57110Smuller struct stat sb; 527*57110Smuller 528*57110Smuller /* 529*57110Smuller * the file does not exist, or -k we are done 530*57110Smuller */ 531*57110Smuller if (lstat(name, &sb) < 0) 532*57110Smuller return(0); 533*57110Smuller if (kflag) 534*57110Smuller return(-1); 535*57110Smuller 536*57110Smuller if (S_ISDIR(sb.st_mode)) { 537*57110Smuller /* 538*57110Smuller * try to remove a directory, if it fails and we were going to 539*57110Smuller * create a directory anyway, tell the caller (return a 1) 540*57110Smuller */ 541*57110Smuller if (rmdir(name) < 0) { 542*57110Smuller if (type == PAX_DIR) 543*57110Smuller return(1); 544*57110Smuller syswarn(1,errno,"Unable to remove directory %s", name); 545*57110Smuller return(-1); 546*57110Smuller } 547*57110Smuller return(0); 548*57110Smuller } 549*57110Smuller 550*57110Smuller /* 551*57110Smuller * try to get rid of all non-directory type nodes 552*57110Smuller */ 553*57110Smuller if (unlink(name) < 0) { 554*57110Smuller syswarn(1, errno, "Could not unlink %s", name); 555*57110Smuller return(-1); 556*57110Smuller } 557*57110Smuller return(0); 558*57110Smuller } 559*57110Smuller 560*57110Smuller /* 561*57110Smuller * chk_path() 562*57110Smuller * We were trying to create some kind of node in the file system and it 563*57110Smuller * failed. chk_path() makes sure the path up to the node exists and is 564*57110Smuller * writeable. When we have to create a directory that is missing along the 565*57110Smuller * path somewhere, the directory we create will be set to the same 566*57110Smuller * uid/gid as the file has (when uid and gid are being preserved). 567*57110Smuller * NOTE: this routine is a real performance loss. It is only used as a 568*57110Smuller * last resort when trying to create entries in the file system. 569*57110Smuller * Return: 570*57110Smuller * -1 when it could find nothing it is allowed to fix. 571*57110Smuller * 0 otherwise 572*57110Smuller */ 573*57110Smuller 574*57110Smuller #if __STDC__ 575*57110Smuller int 576*57110Smuller chk_path( register char *name, uid_t st_uid, gid_t st_gid) 577*57110Smuller #else 578*57110Smuller int 579*57110Smuller chk_path(name, st_uid, st_gid) 580*57110Smuller register char *name; 581*57110Smuller uid_t st_uid; 582*57110Smuller gid_t st_gid; 583*57110Smuller #endif 584*57110Smuller { 585*57110Smuller register char *spt = name; 586*57110Smuller struct stat sb; 587*57110Smuller int retval = -1; 588*57110Smuller 589*57110Smuller /* 590*57110Smuller * watch out for paths with nodes stored directly in / (e.g. /bozo) 591*57110Smuller */ 592*57110Smuller if (*spt == '/') 593*57110Smuller ++spt; 594*57110Smuller 595*57110Smuller for(;;) { 596*57110Smuller /* 597*57110Smuller * work foward from the first / and check each part of the path 598*57110Smuller */ 599*57110Smuller spt = strchr(spt, '/'); 600*57110Smuller if (spt == NULL) 601*57110Smuller break; 602*57110Smuller *spt = '\0'; 603*57110Smuller 604*57110Smuller /* 605*57110Smuller * if it exists we assume it is a directory, it is not within 606*57110Smuller * the spec (at least it seems to reads that way) to alter the 607*57110Smuller * file system for nodes NOT EXPLICITLY stored on the archive. 608*57110Smuller * If that assumption is changed, you would test the node here 609*57110Smuller * and figure out how to get rid of it (probably like some 610*57110Smuller * recursive unlink()) 611*57110Smuller */ 612*57110Smuller if (lstat(name, &sb) == 0) { 613*57110Smuller *(spt++) = '/'; 614*57110Smuller continue; 615*57110Smuller } 616*57110Smuller 617*57110Smuller /* 618*57110Smuller * the path fails at this point, see if we can create the 619*57110Smuller * needed directory and continue on 620*57110Smuller */ 621*57110Smuller if (mkdir(name, S_IRWXU | S_IRWXG | S_IRWXO) < 0) { 622*57110Smuller *spt = '/'; 623*57110Smuller retval = -1; 624*57110Smuller break; 625*57110Smuller } 626*57110Smuller 627*57110Smuller /* 628*57110Smuller * we were able to create the directory. We will tell the 629*57110Smuller * caller that we found something to fix, and it is ok to try 630*57110Smuller * and create the node again. 631*57110Smuller */ 632*57110Smuller retval = 0; 633*57110Smuller if (pids) 634*57110Smuller (void)set_ids(name, st_uid, st_gid); 635*57110Smuller 636*57110Smuller /* 637*57110Smuller * make sure the user doen't have some strange umask that 638*57110Smuller * causes this newly created directory to be unusable. We fix 639*57110Smuller * the modes and restore them back to the creation default at 640*57110Smuller * the end of pax 641*57110Smuller */ 642*57110Smuller if ((access(name, R_OK | W_OK | X_OK) < 0) && 643*57110Smuller (lstat(name, &sb) == 0)) { 644*57110Smuller set_pmode(name, ((sb.st_mode & FILEBITS) | S_IRWXU)); 645*57110Smuller add_dir(name, spt - name, &sb, 1); 646*57110Smuller } 647*57110Smuller *(spt++) = '/'; 648*57110Smuller continue; 649*57110Smuller } 650*57110Smuller return(retval); 651*57110Smuller } 652*57110Smuller 653*57110Smuller /* 654*57110Smuller * set_ftime() 655*57110Smuller * Set the access time and modification time for a named file. If frc is 656*57110Smuller * non-zero we force these times to be set even if the the user did not 657*57110Smuller * request access and/or modification time preservation (this is also 658*57110Smuller * used by -t to reset access times). 659*57110Smuller * When ign is zero, only those times the user has asked for are set, the 660*57110Smuller * other ones are left alone. We do not assume the un-documented feature 661*57110Smuller * of many utimes() implementations that consider a 0 time value as a do 662*57110Smuller * not set request. 663*57110Smuller */ 664*57110Smuller 665*57110Smuller #if __STDC__ 666*57110Smuller void 667*57110Smuller set_ftime(char *fnm, time_t mtime, time_t atime, int frc) 668*57110Smuller #else 669*57110Smuller void 670*57110Smuller set_ftime(fnm, mtime, atime, frc) 671*57110Smuller char *fnm; 672*57110Smuller time_t mtime; 673*57110Smuller time_t atime; 674*57110Smuller int frc; 675*57110Smuller #endif 676*57110Smuller { 677*57110Smuller static struct timeval tv[2] = {{0L, 0L}, {0L, 0L}}; 678*57110Smuller struct stat sb; 679*57110Smuller 680*57110Smuller tv[0].tv_sec = (long)atime; 681*57110Smuller tv[1].tv_sec = (long)mtime; 682*57110Smuller if (!frc && (!patime || !pmtime)) { 683*57110Smuller /* 684*57110Smuller * if we are not forcing, only set those times the user wants 685*57110Smuller * set. We get the current values of the times if we need them. 686*57110Smuller */ 687*57110Smuller if (lstat(fnm, &sb) == 0) { 688*57110Smuller if (!patime) 689*57110Smuller tv[0].tv_sec = (long)sb.st_atime; 690*57110Smuller if (!pmtime) 691*57110Smuller tv[1].tv_sec = (long)sb.st_mtime; 692*57110Smuller } else 693*57110Smuller syswarn(0,errno,"Unable to obtain file stats %s", fnm); 694*57110Smuller } 695*57110Smuller 696*57110Smuller /* 697*57110Smuller * set the times 698*57110Smuller */ 699*57110Smuller if (utimes(fnm, tv) < 0) 700*57110Smuller syswarn(1, errno, "Access/modification time set failed on: %s", 701*57110Smuller fnm); 702*57110Smuller return; 703*57110Smuller } 704*57110Smuller 705*57110Smuller /* 706*57110Smuller * set_ids() 707*57110Smuller * set the uid and gid of a file system node 708*57110Smuller * Return: 709*57110Smuller * 0 when set, -1 on failure 710*57110Smuller */ 711*57110Smuller 712*57110Smuller #if __STDC__ 713*57110Smuller int 714*57110Smuller set_ids(char *fnm, uid_t uid, gid_t gid) 715*57110Smuller #else 716*57110Smuller int 717*57110Smuller set_ids(fnm, uid, gid) 718*57110Smuller char *fnm; 719*57110Smuller uid_t uid; 720*57110Smuller gid_t gid; 721*57110Smuller #endif 722*57110Smuller { 723*57110Smuller if (chown(fnm, uid, gid) < 0) { 724*57110Smuller syswarn(1, errno, "Unable to set file uid/gid of %s", fnm); 725*57110Smuller return(-1); 726*57110Smuller } 727*57110Smuller return(0); 728*57110Smuller } 729*57110Smuller 730*57110Smuller /* 731*57110Smuller * set_pmode() 732*57110Smuller * Set file access mode 733*57110Smuller */ 734*57110Smuller 735*57110Smuller #if __STDC__ 736*57110Smuller void 737*57110Smuller set_pmode(char *fnm, mode_t mode) 738*57110Smuller #else 739*57110Smuller void 740*57110Smuller set_pmode(fnm, mode) 741*57110Smuller char *fnm; 742*57110Smuller mode_t mode; 743*57110Smuller #endif 744*57110Smuller { 745*57110Smuller mode &= ABITS; 746*57110Smuller if (chmod(fnm, mode) < 0) 747*57110Smuller syswarn(1, errno, "Could not set permissions on %s", fnm); 748*57110Smuller return; 749*57110Smuller } 750*57110Smuller 751*57110Smuller /* 752*57110Smuller * file_write() 753*57110Smuller * Write/copy a file (during copy or archive extract). This routine knows 754*57110Smuller * how to copy files with lseek holes in it. (Which are read as file 755*57110Smuller * blocks containing all 0's but do not have any file blocks associated 756*57110Smuller * with the data). Typical examples of these are files created by dbm 757*57110Smuller * variants (.pag files). While the file size of these files are huge, the 758*57110Smuller * actual storage is quite small (the files are sparse). The problem is 759*57110Smuller * the holes read as all zeros so are probably stored on the archive that 760*57110Smuller * way (there is no way to determine if the file block is really a hole, 761*57110Smuller * we only know that a file block of all zero's can be a hole). 762*57110Smuller * At this writing, no major archive format knows how to archive files 763*57110Smuller * with holes. However, on extraction (or during copy, -rw) we have to 764*57110Smuller * deal with these files. Without detecting the holes, the files can 765*57110Smuller * consume a lot of file space if just written to disk. This replacement 766*57110Smuller * for write when passed the basic allocation size of a file system block, 767*57110Smuller * uses lseek whenever it detects the input data is all 0 within that 768*57110Smuller * file block. In more detail, the strategy is as follows: 769*57110Smuller * While the input is all zero keep doing an lseek. Keep track of when we 770*57110Smuller * pass over file block boundries. Only write when we hit a non zero 771*57110Smuller * input. once we have written a file block, we continue to write it to 772*57110Smuller * the end (we stop looking at the input). When we reach the start of the 773*57110Smuller * next file block, start checking for zero blocks again. Working on file 774*57110Smuller * block boundries significantly reduces the overhead when copying files 775*57110Smuller * that are NOT very sparse. This overhead (when compared to a write) is 776*57110Smuller * almost below the measurement resolution on many systems. Without it, 777*57110Smuller * files with holes cannot be safely copied. It does has a side effect as 778*57110Smuller * it can put holes into files that did not have them before, but that is 779*57110Smuller * not a problem since the file contents are unchanged (in fact it saves 780*57110Smuller * file space). (Except on paging files for diskless clients. But since we 781*57110Smuller * cannot determine one of those file from here, we ignore them). If this 782*57110Smuller * ever ends up on a system where CTG files are supported and the holes 783*57110Smuller * are not desired, just do a conditional test in those routines that 784*57110Smuller * call file_write() and have it call write() instead. BEFORE CLOSING THE 785*57110Smuller * FILE, make sure to call file_flush() when the last write finishes with 786*57110Smuller * an empty block. A lot of file systems will not create an lseek hole at 787*57110Smuller * the end. In this case we drop a single 0 at the end to force the 788*57110Smuller * trailing 0's in the file. 789*57110Smuller * ---Parameters--- 790*57110Smuller * rem: how many bytes left in this file system block 791*57110Smuller * isempt: have we written to the file block yet (is it empty) 792*57110Smuller * sz: basic file block allocation size 793*57110Smuller * cnt: number of bytes on this write 794*57110Smuller * str: buffer to write 795*57110Smuller * Return: 796*57110Smuller * number of bytes written, -1 on write (or lseek) error. 797*57110Smuller */ 798*57110Smuller 799*57110Smuller #if __STDC__ 800*57110Smuller int 801*57110Smuller file_write(int fd, char *str, register int cnt, int *rem, int *isempt, int sz, 802*57110Smuller char *name) 803*57110Smuller #else 804*57110Smuller int 805*57110Smuller file_write(fd, str, cnt, rem, isempt, sz, name) 806*57110Smuller int fd; 807*57110Smuller char *str; 808*57110Smuller register int cnt; 809*57110Smuller int *rem; 810*57110Smuller int *isempt; 811*57110Smuller int sz; 812*57110Smuller char *name; 813*57110Smuller #endif 814*57110Smuller { 815*57110Smuller register char *pt; 816*57110Smuller register char *end; 817*57110Smuller register int wcnt; 818*57110Smuller register char *st = str; 819*57110Smuller 820*57110Smuller /* 821*57110Smuller * while we have data to process 822*57110Smuller */ 823*57110Smuller while (cnt) { 824*57110Smuller if (!*rem) { 825*57110Smuller /* 826*57110Smuller * We are now at the start of file system block again 827*57110Smuller * (or what we think one is...). start looking for 828*57110Smuller * empty blocks again 829*57110Smuller */ 830*57110Smuller *isempt = 1; 831*57110Smuller *rem = sz; 832*57110Smuller } 833*57110Smuller 834*57110Smuller /* 835*57110Smuller * only examine up to the end of the current file block or 836*57110Smuller * remaining characters to write, whatever is smaller 837*57110Smuller */ 838*57110Smuller wcnt = MIN(cnt, *rem); 839*57110Smuller cnt -= wcnt; 840*57110Smuller *rem -= wcnt; 841*57110Smuller if (*isempt) { 842*57110Smuller /* 843*57110Smuller * have not written to this block yet, so we keep 844*57110Smuller * looking for zero's 845*57110Smuller */ 846*57110Smuller pt = st; 847*57110Smuller end = st + wcnt; 848*57110Smuller 849*57110Smuller /* 850*57110Smuller * look for a zero filled buffer 851*57110Smuller */ 852*57110Smuller while ((pt < end) && (*pt == '\0')) 853*57110Smuller ++pt; 854*57110Smuller 855*57110Smuller if (pt == end) { 856*57110Smuller /* 857*57110Smuller * skip, buf is empty so far 858*57110Smuller */ 859*57110Smuller if (lseek(fd, (off_t)wcnt, SEEK_CUR) < 0) { 860*57110Smuller syswarn(1,errno,"File seek on %s", 861*57110Smuller name); 862*57110Smuller return(-1); 863*57110Smuller } 864*57110Smuller st = pt; 865*57110Smuller continue; 866*57110Smuller } 867*57110Smuller /* 868*57110Smuller * drat, the buf is not zero filled 869*57110Smuller */ 870*57110Smuller *isempt = 0; 871*57110Smuller } 872*57110Smuller 873*57110Smuller /* 874*57110Smuller * have non-zero data in this file system block, have to write 875*57110Smuller */ 876*57110Smuller if (write(fd, st, wcnt) != wcnt) { 877*57110Smuller syswarn(1, errno, "Failed write to file %s", name); 878*57110Smuller return(-1); 879*57110Smuller } 880*57110Smuller st += wcnt; 881*57110Smuller } 882*57110Smuller return(st - str); 883*57110Smuller } 884*57110Smuller 885*57110Smuller /* 886*57110Smuller * file_flush() 887*57110Smuller * when the last file block in a file is zero, many file systems will not 888*57110Smuller * let us create a hole at the end. To get the last block with zeros, we 889*57110Smuller * write the last BYTE with a zero (back up one byte and write a zero). 890*57110Smuller */ 891*57110Smuller 892*57110Smuller #if __STDC__ 893*57110Smuller void 894*57110Smuller file_flush(int fd, char *fname, int isempt) 895*57110Smuller #else 896*57110Smuller void 897*57110Smuller file_flush(fd, fname, isempt) 898*57110Smuller int fd; 899*57110Smuller char *fname; 900*57110Smuller int isempt; 901*57110Smuller #endif 902*57110Smuller { 903*57110Smuller static char blnk[] = "\0"; 904*57110Smuller 905*57110Smuller /* 906*57110Smuller * silly test, but make sure we are only called when the last block is 907*57110Smuller * filled with all zeros. 908*57110Smuller */ 909*57110Smuller if (!isempt) 910*57110Smuller return; 911*57110Smuller 912*57110Smuller /* 913*57110Smuller * move back one byte and write a zero 914*57110Smuller */ 915*57110Smuller if (lseek(fd, (off_t)-1, SEEK_CUR) < 0) { 916*57110Smuller syswarn(1, errno, "Failed seek on file %s", fname); 917*57110Smuller return; 918*57110Smuller } 919*57110Smuller 920*57110Smuller if (write(fd, blnk, 1) < 0) 921*57110Smuller syswarn(1, errno, "Failed write to file %s", fname); 922*57110Smuller return; 923*57110Smuller } 924*57110Smuller 925*57110Smuller /* 926*57110Smuller * rdfile_close() 927*57110Smuller * close a file we have beed reading (to copy or archive). If we have to 928*57110Smuller * reset access time (tflag) do so (the times are stored in arcn). 929*57110Smuller */ 930*57110Smuller 931*57110Smuller #if __STDC__ 932*57110Smuller void 933*57110Smuller rdfile_close(register ARCHD *arcn, register int *fd) 934*57110Smuller #else 935*57110Smuller void 936*57110Smuller rdfile_close(arcn, fd) 937*57110Smuller register ARCHD *arcn; 938*57110Smuller register int *fd; 939*57110Smuller #endif 940*57110Smuller { 941*57110Smuller /* 942*57110Smuller * make sure the file is open 943*57110Smuller */ 944*57110Smuller if (*fd < 0) 945*57110Smuller return; 946*57110Smuller 947*57110Smuller (void)close(*fd); 948*57110Smuller *fd = -1; 949*57110Smuller if (!tflag) 950*57110Smuller return; 951*57110Smuller 952*57110Smuller /* 953*57110Smuller * user wants last access time reset 954*57110Smuller */ 955*57110Smuller set_ftime(arcn->org_name, arcn->sb.st_mtime, arcn->sb.st_atime, 1); 956*57110Smuller return; 957*57110Smuller } 958*57110Smuller 959*57110Smuller /* 960*57110Smuller * set_crc() 961*57110Smuller * read a file to calculate its crc. This is a real drag. Archive formats 962*57110Smuller * that have this, end up reading the file twice (we have to write the 963*57110Smuller * header WITH the crc before writing the file contents. Oh well... 964*57110Smuller * Return: 965*57110Smuller * 0 if was able to calculate the crc, -1 otherwise 966*57110Smuller */ 967*57110Smuller 968*57110Smuller #if __STDC__ 969*57110Smuller int 970*57110Smuller set_crc(register ARCHD *arcn, register int fd) 971*57110Smuller #else 972*57110Smuller int 973*57110Smuller set_crc(arcn, fd) 974*57110Smuller register ARCHD *arcn; 975*57110Smuller register int fd; 976*57110Smuller #endif 977*57110Smuller { 978*57110Smuller register int i; 979*57110Smuller register int res; 980*57110Smuller off_t cpcnt = 0L; 981*57110Smuller u_long size; 982*57110Smuller unsigned long crc = 0L; 983*57110Smuller char tbuf[FILEBLK]; 984*57110Smuller struct stat sb; 985*57110Smuller 986*57110Smuller if (fd < 0) { 987*57110Smuller /* 988*57110Smuller * hmm, no fd, should never happen. well no crc then. 989*57110Smuller */ 990*57110Smuller arcn->crc = 0L; 991*57110Smuller return(0); 992*57110Smuller } 993*57110Smuller 994*57110Smuller if ((size = (u_long)arcn->sb.st_blksize) > (u_long)sizeof(tbuf)) 995*57110Smuller size = (u_long)sizeof(tbuf); 996*57110Smuller 997*57110Smuller /* 998*57110Smuller * read all the bytes we think that there are in the file. If the user 999*57110Smuller * is trying to archive an active file, forget this file. 1000*57110Smuller */ 1001*57110Smuller for(;;) { 1002*57110Smuller if ((res = read(fd, tbuf, size)) <= 0) 1003*57110Smuller break; 1004*57110Smuller cpcnt += res; 1005*57110Smuller for (i = 0; i < res; ++i) 1006*57110Smuller crc += (tbuf[i] & 0xff); 1007*57110Smuller } 1008*57110Smuller 1009*57110Smuller /* 1010*57110Smuller * safety check. we want to avoid archiving files that are active as 1011*57110Smuller * they can create inconsistant archive copies. 1012*57110Smuller */ 1013*57110Smuller if (cpcnt != arcn->sb.st_size) 1014*57110Smuller warn(1, "File changed size %s", arcn->org_name); 1015*57110Smuller else if (fstat(fd, &sb) < 0) 1016*57110Smuller syswarn(1, errno, "Failed stat on %s", arcn->org_name); 1017*57110Smuller else if (arcn->sb.st_mtime != sb.st_mtime) 1018*57110Smuller warn(1, "File %s was modified during read", arcn->org_name); 1019*57110Smuller else if (lseek(fd, (off_t)0L, SEEK_SET) < 0) 1020*57110Smuller syswarn(1, errno, "File rewind failed on: %s", arcn->org_name); 1021*57110Smuller else { 1022*57110Smuller arcn->crc = crc; 1023*57110Smuller return(0); 1024*57110Smuller } 1025*57110Smuller return(-1); 1026*57110Smuller } 1027