filesubr.c (32785) | filesubr.c (34461) |
---|---|
1/* filesubr.c --- subroutines for dealing with files 2 Jim Blandy <jimb@cyclic.com> 3 4 This file is part of GNU CVS. 5 6 GNU CVS is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published by the 8 Free Software Foundation; either version 2, or (at your option) any --- 29 unchanged lines hidden (view full) --- 38 (void) fprintf (stderr, "%c-> copy(%s,%s)\n", 39 (server_active) ? 'S' : ' ', from, to); 40#else 41 (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to); 42#endif 43 if (noexec) 44 return; 45 | 1/* filesubr.c --- subroutines for dealing with files 2 Jim Blandy <jimb@cyclic.com> 3 4 This file is part of GNU CVS. 5 6 GNU CVS is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published by the 8 Free Software Foundation; either version 2, or (at your option) any --- 29 unchanged lines hidden (view full) --- 38 (void) fprintf (stderr, "%c-> copy(%s,%s)\n", 39 (server_active) ? 'S' : ' ', from, to); 40#else 41 (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to); 42#endif 43 if (noexec) 44 return; 45 |
46 if ((fdin = open (from, O_RDONLY)) < 0) 47 error (1, errno, "cannot open %s for copying", from); 48 if (fstat (fdin, &sb) < 0) 49 error (1, errno, "cannot fstat %s", from); 50 if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0) 51 error (1, errno, "cannot create %s for copying", to); 52 if (sb.st_size > 0) | 46 /* If the file to be copied is a link or a device, then just create 47 the new link or device appropriately. */ 48 if (islink (from)) |
53 { | 49 { |
54 char buf[BUFSIZ]; 55 int n; | 50 char *source = xreadlink (from); 51 symlink (source, to); 52 free (source); 53 return; 54 } |
56 | 55 |
57 for (;;) | 56 if (isdevice (from)) 57 { 58 if (stat (from, &sb) < 0) 59 error (1, errno, "cannot stat %s", from); 60 mknod (to, sb.st_mode, sb.st_rdev); 61 } 62 else 63 { 64 /* Not a link or a device... probably a regular file. */ 65 if ((fdin = open (from, O_RDONLY)) < 0) 66 error (1, errno, "cannot open %s for copying", from); 67 if (fstat (fdin, &sb) < 0) 68 error (1, errno, "cannot fstat %s", from); 69 if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0) 70 error (1, errno, "cannot create %s for copying", to); 71 if (sb.st_size > 0) |
58 { | 72 { |
59 n = read (fdin, buf, sizeof(buf)); 60 if (n == -1) | 73 char buf[BUFSIZ]; 74 int n; 75 76 for (;;) |
61 { | 77 { |
78 n = read (fdin, buf, sizeof(buf)); 79 if (n == -1) 80 { |
|
62#ifdef EINTR | 81#ifdef EINTR |
63 if (errno == EINTR) 64 continue; | 82 if (errno == EINTR) 83 continue; |
65#endif | 84#endif |
66 error (1, errno, "cannot read file %s for copying", from); | 85 error (1, errno, "cannot read file %s for copying", from); 86 } 87 else if (n == 0) 88 break; 89 90 if (write(fdout, buf, n) != n) { 91 error (1, errno, "cannot write file %s for copying", to); 92 } |
67 } | 93 } |
68 else if (n == 0) 69 break; 70 71 if (write(fdout, buf, n) != n) { 72 error (1, errno, "cannot write file %s for copying", to); 73 } 74 } | |
75 76#ifdef HAVE_FSYNC | 94 95#ifdef HAVE_FSYNC |
77 if (fsync (fdout)) 78 error (1, errno, "cannot fsync file %s after copying", to); | 96 if (fsync (fdout)) 97 error (1, errno, "cannot fsync file %s after copying", to); |
79#endif | 98#endif |
99 } 100 101 if (close (fdin) < 0) 102 error (0, errno, "cannot close %s", from); 103 if (close (fdout) < 0) 104 error (1, errno, "cannot close %s", to); |
|
80 } 81 | 105 } 106 |
82 if (close (fdin) < 0) 83 error (0, errno, "cannot close %s", from); 84 if (close (fdout) < 0) 85 error (1, errno, "cannot close %s", to); 86 | |
87 /* now, set the times for the copied file to match those of the original */ 88 memset ((char *) &t, 0, sizeof (t)); 89 t.actime = sb.st_atime; 90 t.modtime = sb.st_mtime; 91 (void) utime (to, &t); 92} 93 94/* FIXME-krp: these functions would benefit from caching the char * & --- 19 unchanged lines hidden (view full) --- 114 */ 115int 116islink (file) 117 const char *file; 118{ 119#ifdef S_ISLNK 120 struct stat sb; 121 | 107 /* now, set the times for the copied file to match those of the original */ 108 memset ((char *) &t, 0, sizeof (t)); 109 t.actime = sb.st_atime; 110 t.modtime = sb.st_mtime; 111 (void) utime (to, &t); 112} 113 114/* FIXME-krp: these functions would benefit from caching the char * & --- 19 unchanged lines hidden (view full) --- 134 */ 135int 136islink (file) 137 const char *file; 138{ 139#ifdef S_ISLNK 140 struct stat sb; 141 |
122 if (lstat (file, &sb) < 0) | 142 if (CVS_LSTAT (file, &sb) < 0) |
123 return (0); 124 return (S_ISLNK (sb.st_mode)); 125#else 126 return (0); 127#endif 128} 129 130/* | 143 return (0); 144 return (S_ISLNK (sb.st_mode)); 145#else 146 return (0); 147#endif 148} 149 150/* |
151 * Returns non-zero if the argument file is a block or 152 * character special device. 153 */ 154int 155isdevice (file) 156 const char *file; 157{ 158 struct stat sb; 159 160 if (CVS_LSTAT (file, &sb) < 0) 161 return (0); 162#ifdef S_ISBLK 163 if (S_ISBLK (sb.st_mode)) 164 return 1; 165#endif 166#ifdef S_ISCHR 167 if (S_ISCHR (sb.st_mode)) 168 return 1; 169#endif 170 return 0; 171} 172 173/* |
|
131 * Returns non-zero if the argument file exists. 132 */ 133int 134isfile (file) 135 const char *file; 136{ 137 return isaccessible(file, F_OK); 138} --- 154 unchanged lines hidden (view full) --- 293 return 1; 294 } 295 return 0; 296} 297 298/* 299 * Change the mode of a file, either adding write permissions, or removing 300 * all write permissions. Either change honors the current umask setting. | 174 * Returns non-zero if the argument file exists. 175 */ 176int 177isfile (file) 178 const char *file; 179{ 180 return isaccessible(file, F_OK); 181} --- 154 unchanged lines hidden (view full) --- 336 return 1; 337 } 338 return 0; 339} 340 341/* 342 * Change the mode of a file, either adding write permissions, or removing 343 * all write permissions. Either change honors the current umask setting. |
344 * 345 * Don't do anything if PreservePermissions is set to `yes'. This may 346 * have unexpected consequences for some uses of xchmod. |
|
301 */ 302void 303xchmod (fname, writable) 304 char *fname; 305 int writable; 306{ 307 struct stat sb; 308 mode_t mode, oumask; 309 | 347 */ 348void 349xchmod (fname, writable) 350 char *fname; 351 int writable; 352{ 353 struct stat sb; 354 mode_t mode, oumask; 355 |
356 if (preserve_perms) 357 return; 358 |
|
310 if (stat (fname, &sb) < 0) 311 { 312 if (!noexec) 313 error (0, errno, "cannot stat %s", fname); 314 return; 315 } 316 oumask = umask (0); 317 (void) umask (oumask); --- 94 unchanged lines hidden (view full) --- 412 * Unlink a file or dir, if possible. If it is a directory do a deep 413 * removal of all of the files in the directory. Return -1 on error 414 * (in which case errno is set). 415 */ 416int 417unlink_file_dir (f) 418 const char *f; 419{ | 359 if (stat (fname, &sb) < 0) 360 { 361 if (!noexec) 362 error (0, errno, "cannot stat %s", fname); 363 return; 364 } 365 oumask = umask (0); 366 (void) umask (oumask); --- 94 unchanged lines hidden (view full) --- 461 * Unlink a file or dir, if possible. If it is a directory do a deep 462 * removal of all of the files in the directory. Return -1 on error 463 * (in which case errno is set). 464 */ 465int 466unlink_file_dir (f) 467 const char *f; 468{ |
469 struct stat sb; 470 |
|
420 if (trace 421#ifdef SERVER_SUPPORT 422 /* This is called by the server parent process in contexts where 423 it is not OK to send output (e.g. after we sent "ok" to the 424 client). */ 425 && !server_active 426#endif 427 ) 428 (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f); 429 430 if (noexec) 431 return (0); 432 433 /* For at least some unices, if root tries to unlink() a directory, 434 instead of doing something rational like returning EISDIR, 435 the system will gleefully go ahead and corrupt the filesystem. | 471 if (trace 472#ifdef SERVER_SUPPORT 473 /* This is called by the server parent process in contexts where 474 it is not OK to send output (e.g. after we sent "ok" to the 475 client). */ 476 && !server_active 477#endif 478 ) 479 (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f); 480 481 if (noexec) 482 return (0); 483 484 /* For at least some unices, if root tries to unlink() a directory, 485 instead of doing something rational like returning EISDIR, 486 the system will gleefully go ahead and corrupt the filesystem. |
436 So we first call isdir() to see if it is OK to call unlink(). This | 487 So we first call stat() to see if it is OK to call unlink(). This |
437 doesn't quite work--if someone creates a directory between the | 488 doesn't quite work--if someone creates a directory between the |
438 call to isdir() and the call to unlink(), we'll still corrupt | 489 call to stat() and the call to unlink(), we'll still corrupt |
439 the filesystem. Where is the Unix Haters Handbook when you need 440 it? */ | 490 the filesystem. Where is the Unix Haters Handbook when you need 491 it? */ |
441 if (isdir(f)) 442 return deep_remove_dir(f); 443 else | 492 if (stat (f, &sb) < 0) |
444 { | 493 { |
445 if (unlink (f) != 0) | 494 if (existence_error (errno)) 495 { 496 /* The file or directory doesn't exist anyhow. */ |
446 return -1; | 497 return -1; |
498 } |
|
447 } | 499 } |
448 /* We were able to remove the file from the disk */ 449 return 0; | 500 else if (S_ISDIR (sb.st_mode)) 501 return deep_remove_dir (f); 502 503 return unlink (f); |
450} 451 452/* Remove a directory and everything it contains. Returns 0 for 453 * success, -1 for failure (in which case errno is set). 454 */ 455 456static int 457deep_remove_dir (path) --- 94 unchanged lines hidden (view full) --- 552 } while (nchars != 0); 553 554 return bp - buf; 555} 556 557 558/* 559 * Compare "file1" to "file2". Return non-zero if they don't compare exactly. | 504} 505 506/* Remove a directory and everything it contains. Returns 0 for 507 * success, -1 for failure (in which case errno is set). 508 */ 509 510static int 511deep_remove_dir (path) --- 94 unchanged lines hidden (view full) --- 606 } while (nchars != 0); 607 608 return bp - buf; 609} 610 611 612/* 613 * Compare "file1" to "file2". Return non-zero if they don't compare exactly. |
614 * If FILE1 and FILE2 are special files, compare their salient characteristics 615 * (i.e. major/minor device numbers, links, etc. |
|
560 */ 561int 562xcmp (file1, file2) 563 const char *file1; 564 const char *file2; 565{ 566 char *buf1, *buf2; 567 struct stat sb1, sb2; 568 int fd1, fd2; 569 int ret; 570 | 616 */ 617int 618xcmp (file1, file2) 619 const char *file1; 620 const char *file2; 621{ 622 char *buf1, *buf2; 623 struct stat sb1, sb2; 624 int fd1, fd2; 625 int ret; 626 |
627 if (CVS_LSTAT (file1, &sb1) < 0) 628 error (1, errno, "cannot lstat %s", file1); 629 if (CVS_LSTAT (file2, &sb2) < 0) 630 error (1, errno, "cannot lstat %s", file2); 631 632 /* If FILE1 and FILE2 are not the same file type, they are unequal. */ 633 if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT)) 634 return 1; 635 636 /* If FILE1 and FILE2 are symlinks, they are equal if they point to 637 the same thing. */ 638 if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode)) 639 { 640 int result; 641 buf1 = xreadlink (file1); 642 buf2 = xreadlink (file2); 643 result = (strcmp (buf1, buf2) == 0); 644 free (buf1); 645 free (buf2); 646 return result; 647 } 648 649 /* If FILE1 and FILE2 are devices, they are equal if their device 650 numbers match. */ 651 if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode)) 652 { 653 if (sb1.st_rdev == sb2.st_rdev) 654 return 0; 655 else 656 return 1; 657 } 658 |
|
571 if ((fd1 = open (file1, O_RDONLY)) < 0) 572 error (1, errno, "cannot open file %s for comparing", file1); 573 if ((fd2 = open (file2, O_RDONLY)) < 0) 574 error (1, errno, "cannot open file %s for comparing", file2); | 659 if ((fd1 = open (file1, O_RDONLY)) < 0) 660 error (1, errno, "cannot open file %s for comparing", file1); 661 if ((fd2 = open (file2, O_RDONLY)) < 0) 662 error (1, errno, "cannot open file %s for comparing", file2); |
575 if (fstat (fd1, &sb1) < 0) 576 error (1, errno, "cannot fstat %s", file1); 577 if (fstat (fd2, &sb2) < 0) 578 error (1, errno, "cannot fstat %s", file2); | |
579 580 /* A generic file compare routine might compare st_dev & st_ino here 581 to see if the two files being compared are actually the same file. 582 But that won't happen in CVS, so we won't bother. */ 583 584 if (sb1.st_size != sb2.st_size) 585 ret = 1; 586 else if (sb1.st_size == 0) --- 85 unchanged lines hidden (view full) --- 672 Trivial under Unix, but more complicated under other systems. */ 673int 674isabsolute (filename) 675 const char *filename; 676{ 677 return filename[0] == '/'; 678} 679 | 663 664 /* A generic file compare routine might compare st_dev & st_ino here 665 to see if the two files being compared are actually the same file. 666 But that won't happen in CVS, so we won't bother. */ 667 668 if (sb1.st_size != sb2.st_size) 669 ret = 1; 670 else if (sb1.st_size == 0) --- 85 unchanged lines hidden (view full) --- 756 Trivial under Unix, but more complicated under other systems. */ 757int 758isabsolute (filename) 759 const char *filename; 760{ 761 return filename[0] == '/'; 762} 763 |
764/* 765 * Return a string (dynamically allocated) with the name of the file to which 766 * LINK is symlinked. 767 */ 768char * 769xreadlink (link) 770 const char *link; 771{ 772 char *file = NULL; 773 int buflen = BUFSIZ; |
|
680 | 774 |
775 if (!islink (link)) 776 return NULL; 777 778 /* Get the name of the file to which `from' is linked. 779 FIXME: what portability issues arise here? Are readlink & 780 ENAMETOOLONG defined on all systems? -twp */ 781 do 782 { 783 file = xrealloc (file, buflen); 784 errno = 0; 785 readlink (link, file, buflen); 786 buflen *= 2; 787 } 788 while (errno == ENAMETOOLONG); 789 790 if (errno) 791 error (1, errno, "cannot readlink %s", link); 792 793 return file; 794} 795 796 797 |
|
681/* Return a pointer into PATH's last component. */ 682char * 683last_component (path) 684 char *path; 685{ 686 char *last = strrchr (path, '/'); | 798/* Return a pointer into PATH's last component. */ 799char * 800last_component (path) 801 char *path; 802{ 803 char *last = strrchr (path, '/'); |
687 688 if (last) | 804 805 if (last && (last != path)) |
689 return last + 1; 690 else 691 return path; 692} 693 694/* Return the home directory. Returns a pointer to storage 695 managed by this function or its callees (currently getenv). 696 This function will return the same thing every time it is --- 185 unchanged lines hidden --- | 806 return last + 1; 807 else 808 return path; 809} 810 811/* Return the home directory. Returns a pointer to storage 812 managed by this function or its callees (currently getenv). 813 This function will return the same thing every time it is --- 185 unchanged lines hidden --- |