1 /*- 2 * Copyright (c) 1992 Keith Muller. 3 * Copyright (c) 1992 The Regents of the University of California. 4 * 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 1.1 (Berkeley) 12/13/92"; 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 whe 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 links 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 set, indicates we couldn't make the link but try to 269 * copy/extract the file as that might work. 270 * -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, "%s not created, sockets are not supported", 402 arcn->name); 403 return(-1); 404 case PAX_SLK: 405 if ((res = symlink(arcn->ln_name, arcn->name)) == 0) 406 return(0); 407 break; 408 case PAX_CTG: 409 case PAX_HLK: 410 case PAX_HRG: 411 case PAX_REG: 412 /* 413 * should never be called to create these 414 */ 415 default: 416 warn(1,"Unknown file system type skip: %s",arcn->name); 417 return(-1); 418 } 419 420 /* 421 * if we were able to create the node break out of the loop, 422 * otherwise try to unlink the node and try again. if that 423 * fails check the full path and try a final time. 424 */ 425 if (res == 0) 426 break; 427 428 /* 429 * we failed to make the node 430 */ 431 oerrno = errno; 432 if ((ign = unlnk_exist(arcn->name, arcn->type)) < 0) 433 return(-1); 434 435 if (++pass <= 1) 436 continue; 437 438 if (chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) { 439 syswarn(1, oerrno, "Could not create: %s", arcn->name); 440 return(-1); 441 } 442 } 443 444 /* 445 * we were able to create the node. set uid/gid, modes and times 446 */ 447 if (pids) 448 res = set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid); 449 else 450 res = 0; 451 452 /* 453 * IMPORTANT SECURITY NOTE: 454 * if not preserving mode or whe cannot set uid/gid, then PROHIBIT any 455 * set uid/gid bits 456 */ 457 if (!pmode || res) 458 arcn->sb.st_mode &= ~(SETBITS); 459 if (pmode) 460 set_pmode(arcn->name, arcn->sb.st_mode); 461 462 if (arcn->type == PAX_DIR) { 463 /* 464 * Dirs must be processed again at end of extract to set times 465 * and modes to agree with those stored in the archive. However 466 * to allow extract to continue, we may have to also set owner 467 * rights. This allows nodes in the archive that are children 468 * of this directory to be extracted without failure. Both time 469 * and modes will be fixed after the entire archive is read and 470 * before pax exits. 471 */ 472 if (access(arcn->name, R_OK | W_OK | X_OK) < 0) { 473 if (lstat(arcn->name, &sb) < 0) { 474 syswarn(0, errno,"Could not access %s (stat)", 475 arcn->name); 476 set_pmode(arcn->name,file_mode | S_IRWXU); 477 } else { 478 /* 479 * We have to add rights to the dir, so we make 480 * sure to restore the mode. The mode must be 481 * restored AS CREATED and not as stored if 482 * pmode is not set. 483 */ 484 set_pmode(arcn->name, 485 ((sb.st_mode & FILEBITS) | S_IRWXU)); 486 if (!pmode) 487 arcn->sb.st_mode = sb.st_mode; 488 } 489 490 /* 491 * we have to force the mode to what was set here, 492 * since we changed it from the default as created. 493 */ 494 add_dir(arcn->name, arcn->nlen, &(arcn->sb), 1); 495 } else if (pmode || patime || pmtime) 496 add_dir(arcn->name, arcn->nlen, &(arcn->sb), 0); 497 } 498 499 if (patime || pmtime) 500 set_ftime(arcn->name, arcn->sb.st_mtime, arcn->sb.st_atime, 0); 501 return(0); 502 } 503 504 /* 505 * unlnk_exist() 506 * Remove node from file system with the specified name. We pass the type 507 * of the node that is going to replace it. When we try to create a 508 * directory and find that it already exists, we allow processing to 509 * continue as proper modes etc will always be set for it later on. 510 * Return: 511 * 0 is ok to proceed, no file with the specified name exists 512 * -1 we were unable to remove the node, or we should not remove it (-k) 513 * 1 we found a directory and we were going to create a directory. 514 */ 515 516 #if __STDC__ 517 int 518 unlnk_exist(register char *name, register int type) 519 #else 520 int 521 unlnk_exist(name, type) 522 register char *name; 523 register int type; 524 #endif 525 { 526 struct stat sb; 527 528 /* 529 * the file does not exist, or -k we are done 530 */ 531 if (lstat(name, &sb) < 0) 532 return(0); 533 if (kflag) 534 return(-1); 535 536 if (S_ISDIR(sb.st_mode)) { 537 /* 538 * try to remove a directory, if it fails and we were going to 539 * create a directory anyway, tell the caller (return a 1) 540 */ 541 if (rmdir(name) < 0) { 542 if (type == PAX_DIR) 543 return(1); 544 syswarn(1,errno,"Unable to remove directory %s", name); 545 return(-1); 546 } 547 return(0); 548 } 549 550 /* 551 * try to get rid of all non-directory type nodes 552 */ 553 if (unlink(name) < 0) { 554 syswarn(1, errno, "Could not unlink %s", name); 555 return(-1); 556 } 557 return(0); 558 } 559 560 /* 561 * chk_path() 562 * We were trying to create some kind of node in the file system and it 563 * failed. chk_path() makes sure the path up to the node exists and is 564 * writeable. When we have to create a directory that is missing along the 565 * path somewhere, the directory we create will be set to the same 566 * uid/gid as the file has (when uid and gid are being preserved). 567 * NOTE: this routine is a real performance loss. It is only used as a 568 * last resort when trying to create entries in the file system. 569 * Return: 570 * -1 when it could find nothing it is allowed to fix. 571 * 0 otherwise 572 */ 573 574 #if __STDC__ 575 int 576 chk_path( register char *name, uid_t st_uid, gid_t st_gid) 577 #else 578 int 579 chk_path(name, st_uid, st_gid) 580 register char *name; 581 uid_t st_uid; 582 gid_t st_gid; 583 #endif 584 { 585 register char *spt = name; 586 struct stat sb; 587 int retval = -1; 588 589 /* 590 * watch out for paths with nodes stored directly in / (e.g. /bozo) 591 */ 592 if (*spt == '/') 593 ++spt; 594 595 for(;;) { 596 /* 597 * work foward from the first / and check each part of the path 598 */ 599 spt = strchr(spt, '/'); 600 if (spt == NULL) 601 break; 602 *spt = '\0'; 603 604 /* 605 * if it exists we assume it is a directory, it is not within 606 * the spec (at least it seems to reads that way) to alter the 607 * file system for nodes NOT EXPLICITLY stored on the archive. 608 * If that assumption is changed, you would test the node here 609 * and figure out how to get rid of it (probably like some 610 * recursive unlink()) 611 */ 612 if (lstat(name, &sb) == 0) { 613 *(spt++) = '/'; 614 continue; 615 } 616 617 /* 618 * the path fails at this point, see if we can create the 619 * needed directory and continue on 620 */ 621 if (mkdir(name, S_IRWXU | S_IRWXG | S_IRWXO) < 0) { 622 *spt = '/'; 623 retval = -1; 624 break; 625 } 626 627 /* 628 * we were able to create the directory. We will tell the 629 * caller that we found something to fix, and it is ok to try 630 * and create the node again. 631 */ 632 retval = 0; 633 if (pids) 634 (void)set_ids(name, st_uid, st_gid); 635 636 /* 637 * make sure the user doen't have some strange umask that 638 * causes this newly created directory to be unusable. We fix 639 * the modes and restore them back to the creation default at 640 * the end of pax 641 */ 642 if ((access(name, R_OK | W_OK | X_OK) < 0) && 643 (lstat(name, &sb) == 0)) { 644 set_pmode(name, ((sb.st_mode & FILEBITS) | S_IRWXU)); 645 add_dir(name, spt - name, &sb, 1); 646 } 647 *(spt++) = '/'; 648 continue; 649 } 650 return(retval); 651 } 652 653 /* 654 * set_ftime() 655 * Set the access time and modification time for a named file. If frc is 656 * non-zero we force these times to be set even if the the user did not 657 * request access and/or modification time preservation (this is also 658 * used by -t to reset access times). 659 * When ign is zero, only those times the user has asked for are set, the 660 * other ones are left alone. We do not assume the un-documented feature 661 * of many utimes() implementations that consider a 0 time value as a do 662 * not set request. 663 */ 664 665 #if __STDC__ 666 void 667 set_ftime(char *fnm, time_t mtime, time_t atime, int frc) 668 #else 669 void 670 set_ftime(fnm, mtime, atime, frc) 671 char *fnm; 672 time_t mtime; 673 time_t atime; 674 int frc; 675 #endif 676 { 677 static struct timeval tv[2] = {{0L, 0L}, {0L, 0L}}; 678 struct stat sb; 679 680 tv[0].tv_sec = (long)atime; 681 tv[1].tv_sec = (long)mtime; 682 if (!frc && (!patime || !pmtime)) { 683 /* 684 * if we are not forcing, only set those times the user wants 685 * set. We get the current values of the times if we need them. 686 */ 687 if (lstat(fnm, &sb) == 0) { 688 if (!patime) 689 tv[0].tv_sec = (long)sb.st_atime; 690 if (!pmtime) 691 tv[1].tv_sec = (long)sb.st_mtime; 692 } else 693 syswarn(0,errno,"Unable to obtain file stats %s", fnm); 694 } 695 696 /* 697 * set the times 698 */ 699 if (utimes(fnm, tv) < 0) 700 syswarn(1, errno, "Access/modification time set failed on: %s", 701 fnm); 702 return; 703 } 704 705 /* 706 * set_ids() 707 * set the uid and gid of a file system node 708 * Return: 709 * 0 when set, -1 on failure 710 */ 711 712 #if __STDC__ 713 int 714 set_ids(char *fnm, uid_t uid, gid_t gid) 715 #else 716 int 717 set_ids(fnm, uid, gid) 718 char *fnm; 719 uid_t uid; 720 gid_t gid; 721 #endif 722 { 723 if (chown(fnm, uid, gid) < 0) { 724 syswarn(1, errno, "Unable to set file uid/gid of %s", fnm); 725 return(-1); 726 } 727 return(0); 728 } 729 730 /* 731 * set_pmode() 732 * Set file access mode 733 */ 734 735 #if __STDC__ 736 void 737 set_pmode(char *fnm, mode_t mode) 738 #else 739 void 740 set_pmode(fnm, mode) 741 char *fnm; 742 mode_t mode; 743 #endif 744 { 745 mode &= ABITS; 746 if (chmod(fnm, mode) < 0) 747 syswarn(1, errno, "Could not set permissions on %s", fnm); 748 return; 749 } 750 751 /* 752 * file_write() 753 * Write/copy a file (during copy or archive extract). This routine knows 754 * how to copy files with lseek holes in it. (Which are read as file 755 * blocks containing all 0's but do not have any file blocks associated 756 * with the data). Typical examples of these are files created by dbm 757 * variants (.pag files). While the file size of these files are huge, the 758 * actual storage is quite small (the files are sparse). The problem is 759 * the holes read as all zeros so are probably stored on the archive that 760 * way (there is no way to determine if the file block is really a hole, 761 * we only know that a file block of all zero's can be a hole). 762 * At this writing, no major archive format knows how to archive files 763 * with holes. However, on extraction (or during copy, -rw) we have to 764 * deal with these files. Without detecting the holes, the files can 765 * consume a lot of file space if just written to disk. This replacement 766 * for write when passed the basic allocation size of a file system block, 767 * uses lseek whenever it detects the input data is all 0 within that 768 * file block. In more detail, the strategy is as follows: 769 * While the input is all zero keep doing an lseek. Keep track of when we 770 * pass over file block boundries. Only write when we hit a non zero 771 * input. once we have written a file block, we continue to write it to 772 * the end (we stop looking at the input). When we reach the start of the 773 * next file block, start checking for zero blocks again. Working on file 774 * block boundries significantly reduces the overhead when copying files 775 * that are NOT very sparse. This overhead (when compared to a write) is 776 * almost below the measurement resolution on many systems. Without it, 777 * files with holes cannot be safely copied. It does has a side effect as 778 * it can put holes into files that did not have them before, but that is 779 * not a problem since the file contents are unchanged (in fact it saves 780 * file space). (Except on paging files for diskless clients. But since we 781 * cannot determine one of those file from here, we ignore them). If this 782 * ever ends up on a system where CTG files are supported and the holes 783 * are not desired, just do a conditional test in those routines that 784 * call file_write() and have it call write() instead. BEFORE CLOSING THE 785 * FILE, make sure to call file_flush() when the last write finishes with 786 * an empty block. A lot of file systems will not create an lseek hole at 787 * the end. In this case we drop a single 0 at the end to force the 788 * trailing 0's in the file. 789 * ---Parameters--- 790 * rem: how many bytes left in this file system block 791 * isempt: have we written to the file block yet (is it empty) 792 * sz: basic file block allocation size 793 * cnt: number of bytes on this write 794 * str: buffer to write 795 * Return: 796 * number of bytes written, -1 on write (or lseek) error. 797 */ 798 799 #if __STDC__ 800 int 801 file_write(int fd, char *str, register int cnt, int *rem, int *isempt, int sz, 802 char *name) 803 #else 804 int 805 file_write(fd, str, cnt, rem, isempt, sz, name) 806 int fd; 807 char *str; 808 register int cnt; 809 int *rem; 810 int *isempt; 811 int sz; 812 char *name; 813 #endif 814 { 815 register char *pt; 816 register char *end; 817 register int wcnt; 818 register char *st = str; 819 820 /* 821 * while we have data to process 822 */ 823 while (cnt) { 824 if (!*rem) { 825 /* 826 * We are now at the start of file system block again 827 * (or what we think one is...). start looking for 828 * empty blocks again 829 */ 830 *isempt = 1; 831 *rem = sz; 832 } 833 834 /* 835 * only examine up to the end of the current file block or 836 * remaining characters to write, whatever is smaller 837 */ 838 wcnt = MIN(cnt, *rem); 839 cnt -= wcnt; 840 *rem -= wcnt; 841 if (*isempt) { 842 /* 843 * have not written to this block yet, so we keep 844 * looking for zero's 845 */ 846 pt = st; 847 end = st + wcnt; 848 849 /* 850 * look for a zero filled buffer 851 */ 852 while ((pt < end) && (*pt == '\0')) 853 ++pt; 854 855 if (pt == end) { 856 /* 857 * skip, buf is empty so far 858 */ 859 if (lseek(fd, (off_t)wcnt, SEEK_CUR) < 0) { 860 syswarn(1,errno,"File seek on %s", 861 name); 862 return(-1); 863 } 864 st = pt; 865 continue; 866 } 867 /* 868 * drat, the buf is not zero filled 869 */ 870 *isempt = 0; 871 } 872 873 /* 874 * have non-zero data in this file system block, have to write 875 */ 876 if (write(fd, st, wcnt) != wcnt) { 877 syswarn(1, errno, "Failed write to file %s", name); 878 return(-1); 879 } 880 st += wcnt; 881 } 882 return(st - str); 883 } 884 885 /* 886 * file_flush() 887 * when the last file block in a file is zero, many file systems will not 888 * let us create a hole at the end. To get the last block with zeros, we 889 * write the last BYTE with a zero (back up one byte and write a zero). 890 */ 891 892 #if __STDC__ 893 void 894 file_flush(int fd, char *fname, int isempt) 895 #else 896 void 897 file_flush(fd, fname, isempt) 898 int fd; 899 char *fname; 900 int isempt; 901 #endif 902 { 903 static char blnk[] = "\0"; 904 905 /* 906 * silly test, but make sure we are only called when the last block is 907 * filled with all zeros. 908 */ 909 if (!isempt) 910 return; 911 912 /* 913 * move back one byte and write a zero 914 */ 915 if (lseek(fd, (off_t)-1, SEEK_CUR) < 0) { 916 syswarn(1, errno, "Failed seek on file %s", fname); 917 return; 918 } 919 920 if (write(fd, blnk, 1) < 0) 921 syswarn(1, errno, "Failed write to file %s", fname); 922 return; 923 } 924 925 /* 926 * rdfile_close() 927 * close a file we have beed reading (to copy or archive). If we have to 928 * reset access time (tflag) do so (the times are stored in arcn). 929 */ 930 931 #if __STDC__ 932 void 933 rdfile_close(register ARCHD *arcn, register int *fd) 934 #else 935 void 936 rdfile_close(arcn, fd) 937 register ARCHD *arcn; 938 register int *fd; 939 #endif 940 { 941 /* 942 * make sure the file is open 943 */ 944 if (*fd < 0) 945 return; 946 947 (void)close(*fd); 948 *fd = -1; 949 if (!tflag) 950 return; 951 952 /* 953 * user wants last access time reset 954 */ 955 set_ftime(arcn->org_name, arcn->sb.st_mtime, arcn->sb.st_atime, 1); 956 return; 957 } 958 959 /* 960 * set_crc() 961 * read a file to calculate its crc. This is a real drag. Archive formats 962 * that have this, end up reading the file twice (we have to write the 963 * header WITH the crc before writing the file contents. Oh well... 964 * Return: 965 * 0 if was able to calculate the crc, -1 otherwise 966 */ 967 968 #if __STDC__ 969 int 970 set_crc(register ARCHD *arcn, register int fd) 971 #else 972 int 973 set_crc(arcn, fd) 974 register ARCHD *arcn; 975 register int fd; 976 #endif 977 { 978 register int i; 979 register int res; 980 off_t cpcnt = 0L; 981 u_long size; 982 unsigned long crc = 0L; 983 char tbuf[FILEBLK]; 984 struct stat sb; 985 986 if (fd < 0) { 987 /* 988 * hmm, no fd, should never happen. well no crc then. 989 */ 990 arcn->crc = 0L; 991 return(0); 992 } 993 994 if ((size = (u_long)arcn->sb.st_blksize) > (u_long)sizeof(tbuf)) 995 size = (u_long)sizeof(tbuf); 996 997 /* 998 * read all the bytes we think that there are in the file. If the user 999 * is trying to archive an active file, forget this file. 1000 */ 1001 for(;;) { 1002 if ((res = read(fd, tbuf, size)) <= 0) 1003 break; 1004 cpcnt += res; 1005 for (i = 0; i < res; ++i) 1006 crc += (tbuf[i] & 0xff); 1007 } 1008 1009 /* 1010 * safety check. we want to avoid archiving files that are active as 1011 * they can create inconsistant archive copies. 1012 */ 1013 if (cpcnt != arcn->sb.st_size) 1014 warn(1, "File changed size %s", arcn->org_name); 1015 else if (fstat(fd, &sb) < 0) 1016 syswarn(1, errno, "Failed stat on %s", arcn->org_name); 1017 else if (arcn->sb.st_mtime != sb.st_mtime) 1018 warn(1, "File %s was modified during read", arcn->org_name); 1019 else if (lseek(fd, (off_t)0L, SEEK_SET) < 0) 1020 syswarn(1, errno, "File rewind failed on: %s", arcn->org_name); 1021 else { 1022 arcn->crc = crc; 1023 return(0); 1024 } 1025 return(-1); 1026 } 1027