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