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