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 9 later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. */ 15 16 /* These functions were moved out of subr.c because they need different 17 definitions under operating systems (like, say, Windows NT) with different 18 file system semantics. */ 19 20 #include "cvs.h" 21 22 static int deep_remove_dir PROTO((const char *path)); 23 24 /* 25 * Copies "from" to "to". 26 */ 27 void 28 copy_file (from, to) 29 const char *from; 30 const char *to; 31 { 32 struct stat sb; 33 struct utimbuf t; 34 int fdin, fdout; 35 36 if (trace) 37 #ifdef SERVER_SUPPORT 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) 53 { 54 char buf[BUFSIZ]; 55 int n; 56 57 for (;;) 58 { 59 n = read (fdin, buf, sizeof(buf)); 60 if (n == -1) 61 { 62 #ifdef EINTR 63 if (errno == EINTR) 64 continue; 65 #endif 66 error (1, errno, "cannot read file %s for copying", from); 67 } 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 77 if (fsync (fdout)) 78 error (1, errno, "cannot fsync file %s after copying", to); 79 #endif 80 } 81 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 * & 95 stat buf. */ 96 97 /* 98 * Returns non-zero if the argument file is a directory, or is a symbolic 99 * link which points to a directory. 100 */ 101 int 102 isdir (file) 103 const char *file; 104 { 105 struct stat sb; 106 107 if (stat (file, &sb) < 0) 108 return (0); 109 return (S_ISDIR (sb.st_mode)); 110 } 111 112 /* 113 * Returns non-zero if the argument file is a symbolic link. 114 */ 115 int 116 islink (file) 117 const char *file; 118 { 119 #ifdef S_ISLNK 120 struct stat sb; 121 122 if (lstat (file, &sb) < 0) 123 return (0); 124 return (S_ISLNK (sb.st_mode)); 125 #else 126 return (0); 127 #endif 128 } 129 130 /* 131 * Returns non-zero if the argument file exists. 132 */ 133 int 134 isfile (file) 135 const char *file; 136 { 137 return isaccessible(file, F_OK); 138 } 139 140 /* 141 * Returns non-zero if the argument file is readable. 142 */ 143 int 144 isreadable (file) 145 const char *file; 146 { 147 return isaccessible(file, R_OK); 148 } 149 150 /* 151 * Returns non-zero if the argument file is writable. 152 */ 153 int 154 iswritable (file) 155 const char *file; 156 { 157 return isaccessible(file, W_OK); 158 } 159 160 /* 161 * Returns non-zero if the argument file is accessable according to 162 * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid 163 * bits set. 164 */ 165 int 166 isaccessible (file, mode) 167 const char *file; 168 const int mode; 169 { 170 #ifdef SETXID_SUPPORT 171 struct stat sb; 172 int umask = 0; 173 int gmask = 0; 174 int omask = 0; 175 int uid; 176 177 if (stat(file, &sb) == -1) 178 return 0; 179 if (mode == F_OK) 180 return 1; 181 182 uid = geteuid(); 183 if (uid == 0) /* superuser */ 184 { 185 if (mode & X_OK) 186 return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH); 187 else 188 return 1; 189 } 190 191 if (mode & R_OK) 192 { 193 umask |= S_IRUSR; 194 gmask |= S_IRGRP; 195 omask |= S_IROTH; 196 } 197 if (mode & W_OK) 198 { 199 umask |= S_IWUSR; 200 gmask |= S_IWGRP; 201 omask |= S_IWOTH; 202 } 203 if (mode & X_OK) 204 { 205 umask |= S_IXUSR; 206 gmask |= S_IXGRP; 207 omask |= S_IXOTH; 208 } 209 210 if (sb.st_uid == uid) 211 return (sb.st_mode & umask) == umask; 212 else if (sb.st_gid == getegid()) 213 return (sb.st_mode & gmask) == gmask; 214 else 215 return (sb.st_mode & omask) == omask; 216 #else 217 return access(file, mode) == 0; 218 #endif 219 } 220 221 /* 222 * Open a file and die if it fails 223 */ 224 FILE * 225 open_file (name, mode) 226 const char *name; 227 const char *mode; 228 { 229 FILE *fp; 230 231 if ((fp = fopen (name, mode)) == NULL) 232 error (1, errno, "cannot open %s", name); 233 return (fp); 234 } 235 236 /* 237 * Make a directory and die if it fails 238 */ 239 void 240 make_directory (name) 241 const char *name; 242 { 243 struct stat sb; 244 245 if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode))) 246 error (0, 0, "%s already exists but is not a directory", name); 247 if (!noexec && mkdir (name, 0777) < 0) 248 error (1, errno, "cannot make directory %s", name); 249 } 250 251 /* 252 * Make a path to the argument directory, printing a message if something 253 * goes wrong. 254 */ 255 void 256 make_directories (name) 257 const char *name; 258 { 259 char *cp; 260 261 if (noexec) 262 return; 263 264 if (mkdir (name, 0777) == 0 || errno == EEXIST) 265 return; 266 if (! existence_error (errno)) 267 { 268 error (0, errno, "cannot make path to %s", name); 269 return; 270 } 271 if ((cp = strrchr (name, '/')) == NULL) 272 return; 273 *cp = '\0'; 274 make_directories (name); 275 *cp++ = '/'; 276 if (*cp == '\0') 277 return; 278 (void) mkdir (name, 0777); 279 } 280 281 /* Create directory NAME if it does not already exist; fatal error for 282 other errors. Returns 0 if directory was created; 1 if it already 283 existed. */ 284 int 285 mkdir_if_needed (name) 286 char *name; 287 { 288 if (mkdir (name, 0777) < 0) 289 { 290 if (errno != EEXIST) 291 error (1, errno, "cannot make directory %s", name); 292 return 1; 293 } 294 return 0; 295 } 296 297 /* 298 * Change the mode of a file, either adding write permissions, or removing 299 * all write permissions. Either change honors the current umask setting. 300 */ 301 void 302 xchmod (fname, writable) 303 char *fname; 304 int writable; 305 { 306 struct stat sb; 307 mode_t mode, oumask; 308 309 if (stat (fname, &sb) < 0) 310 { 311 if (!noexec) 312 error (0, errno, "cannot stat %s", fname); 313 return; 314 } 315 oumask = umask (0); 316 (void) umask (oumask); 317 if (writable) 318 { 319 mode = sb.st_mode | (~oumask 320 & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0) 321 | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0) 322 | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0))); 323 } 324 else 325 { 326 mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask; 327 } 328 329 if (trace) 330 #ifdef SERVER_SUPPORT 331 (void) fprintf (stderr, "%c-> chmod(%s,%o)\n", 332 (server_active) ? 'S' : ' ', fname, 333 (unsigned int) mode); 334 #else 335 (void) fprintf (stderr, "-> chmod(%s,%o)\n", fname, 336 (unsigned int) mode); 337 #endif 338 if (noexec) 339 return; 340 341 if (chmod (fname, mode) < 0) 342 error (0, errno, "cannot change mode of file %s", fname); 343 } 344 345 /* 346 * Rename a file and die if it fails 347 */ 348 void 349 rename_file (from, to) 350 const char *from; 351 const char *to; 352 { 353 if (trace) 354 #ifdef SERVER_SUPPORT 355 (void) fprintf (stderr, "%c-> rename(%s,%s)\n", 356 (server_active) ? 'S' : ' ', from, to); 357 #else 358 (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to); 359 #endif 360 if (noexec) 361 return; 362 363 if (rename (from, to) < 0) 364 error (1, errno, "cannot rename file %s to %s", from, to); 365 } 366 367 /* 368 * link a file, if possible. Warning: the Windows NT version of this 369 * function just copies the file, so only use this function in ways 370 * that can deal with either a link or a copy. 371 */ 372 int 373 link_file (from, to) 374 const char *from; 375 const char *to; 376 { 377 if (trace) 378 #ifdef SERVER_SUPPORT 379 (void) fprintf (stderr, "%c-> link(%s,%s)\n", 380 (server_active) ? 'S' : ' ', from, to); 381 #else 382 (void) fprintf (stderr, "-> link(%s,%s)\n", from, to); 383 #endif 384 if (noexec) 385 return (0); 386 387 return (link (from, to)); 388 } 389 390 /* 391 * unlink a file, if possible. 392 */ 393 int 394 unlink_file (f) 395 const char *f; 396 { 397 if (trace) 398 #ifdef SERVER_SUPPORT 399 (void) fprintf (stderr, "%c-> unlink(%s)\n", 400 (server_active) ? 'S' : ' ', f); 401 #else 402 (void) fprintf (stderr, "-> unlink(%s)\n", f); 403 #endif 404 if (noexec) 405 return (0); 406 407 return (unlink (f)); 408 } 409 410 /* 411 * Unlink a file or dir, if possible. If it is a directory do a deep 412 * removal of all of the files in the directory. Return -1 on error 413 * (in which case errno is set). 414 */ 415 int 416 unlink_file_dir (f) 417 const char *f; 418 { 419 if (trace) 420 #ifdef SERVER_SUPPORT 421 (void) fprintf (stderr, "%c-> unlink_file_dir(%s)\n", 422 (server_active) ? 'S' : ' ', f); 423 #else 424 (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f); 425 #endif 426 if (noexec) 427 return (0); 428 429 /* For at least some unices, if root tries to unlink() a directory, 430 instead of doing something rational like returning EISDIR, 431 the system will gleefully go ahead and corrupt the filesystem. 432 So we first call isdir() to see if it is OK to call unlink(). This 433 doesn't quite work--if someone creates a directory between the 434 call to isdir() and the call to unlink(), we'll still corrupt 435 the filesystem. Where is the Unix Haters Handbook when you need 436 it? */ 437 if (isdir(f)) 438 return deep_remove_dir(f); 439 else 440 { 441 if (unlink (f) != 0) 442 return -1; 443 } 444 /* We were able to remove the file from the disk */ 445 return 0; 446 } 447 448 /* Remove a directory and everything it contains. Returns 0 for 449 * success, -1 for failure (in which case errno is set). 450 */ 451 452 static int 453 deep_remove_dir (path) 454 const char *path; 455 { 456 DIR *dirp; 457 struct dirent *dp; 458 459 if (rmdir (path) != 0) 460 { 461 if (errno == ENOTEMPTY 462 || errno == EEXIST 463 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug 464 (it defines ENOTEMPTY and EEXIST to 17 but actually 465 returns 87). */ 466 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87)) 467 { 468 if ((dirp = opendir (path)) == NULL) 469 /* If unable to open the directory return 470 * an error 471 */ 472 return -1; 473 474 while ((dp = readdir (dirp)) != NULL) 475 { 476 char *buf; 477 478 if (strcmp (dp->d_name, ".") == 0 || 479 strcmp (dp->d_name, "..") == 0) 480 continue; 481 482 buf = xmalloc (strlen (path) + strlen (dp->d_name) + 5); 483 sprintf (buf, "%s/%s", path, dp->d_name); 484 485 /* See comment in unlink_file_dir explanation of why we use 486 isdir instead of just calling unlink and checking the 487 status. */ 488 if (isdir(buf)) 489 { 490 if (deep_remove_dir(buf)) 491 { 492 closedir(dirp); 493 free (buf); 494 return -1; 495 } 496 } 497 else 498 { 499 if (unlink (buf) != 0) 500 { 501 closedir(dirp); 502 free (buf); 503 return -1; 504 } 505 } 506 free (buf); 507 } 508 closedir (dirp); 509 return rmdir (path); 510 } 511 else 512 return -1; 513 } 514 515 /* Was able to remove the directory return 0 */ 516 return 0; 517 } 518 519 /* Read NCHARS bytes from descriptor FD into BUF. 520 Return the number of characters successfully read. 521 The number returned is always NCHARS unless end-of-file or error. */ 522 static size_t 523 block_read (fd, buf, nchars) 524 int fd; 525 char *buf; 526 size_t nchars; 527 { 528 char *bp = buf; 529 size_t nread; 530 531 do 532 { 533 nread = read (fd, bp, nchars); 534 if (nread == (size_t)-1) 535 { 536 #ifdef EINTR 537 if (errno == EINTR) 538 continue; 539 #endif 540 return (size_t)-1; 541 } 542 543 if (nread == 0) 544 break; 545 546 bp += nread; 547 nchars -= nread; 548 } while (nchars != 0); 549 550 return bp - buf; 551 } 552 553 554 /* 555 * Compare "file1" to "file2". Return non-zero if they don't compare exactly. 556 */ 557 int 558 xcmp (file1, file2) 559 const char *file1; 560 const char *file2; 561 { 562 char *buf1, *buf2; 563 struct stat sb1, sb2; 564 int fd1, fd2; 565 int ret; 566 567 if ((fd1 = open (file1, O_RDONLY)) < 0) 568 error (1, errno, "cannot open file %s for comparing", file1); 569 if ((fd2 = open (file2, O_RDONLY)) < 0) 570 error (1, errno, "cannot open file %s for comparing", file2); 571 if (fstat (fd1, &sb1) < 0) 572 error (1, errno, "cannot fstat %s", file1); 573 if (fstat (fd2, &sb2) < 0) 574 error (1, errno, "cannot fstat %s", file2); 575 576 /* A generic file compare routine might compare st_dev & st_ino here 577 to see if the two files being compared are actually the same file. 578 But that won't happen in CVS, so we won't bother. */ 579 580 if (sb1.st_size != sb2.st_size) 581 ret = 1; 582 else if (sb1.st_size == 0) 583 ret = 0; 584 else 585 { 586 /* FIXME: compute the optimal buffer size by computing the least 587 common multiple of the files st_blocks field */ 588 size_t buf_size = 8 * 1024; 589 size_t read1; 590 size_t read2; 591 592 buf1 = xmalloc (buf_size); 593 buf2 = xmalloc (buf_size); 594 595 do 596 { 597 read1 = block_read (fd1, buf1, buf_size); 598 if (read1 == (size_t)-1) 599 error (1, errno, "cannot read file %s for comparing", file1); 600 601 read2 = block_read (fd2, buf2, buf_size); 602 if (read2 == (size_t)-1) 603 error (1, errno, "cannot read file %s for comparing", file2); 604 605 /* assert (read1 == read2); */ 606 607 ret = memcmp(buf1, buf2, read1); 608 } while (ret == 0 && read1 == buf_size); 609 610 free (buf1); 611 free (buf2); 612 } 613 614 (void) close (fd1); 615 (void) close (fd2); 616 return (ret); 617 } 618 619 /* Generate a unique temporary filename. Returns a pointer to a newly 620 malloc'd string containing the name. Returns successfully or not at 621 all. */ 622 /* There are at least three functions for generating temporary 623 filenames. We use tempnam (SVID 3) if possible, else mktemp (BSD 624 4.3), and as last resort tmpnam (POSIX). Reason is that tempnam and 625 mktemp both allow to specify the directory in which the temporary 626 file will be created. */ 627 #ifdef HAVE_TEMPNAM 628 char * 629 cvs_temp_name () 630 { 631 char *retval; 632 633 retval = tempnam (Tmpdir, "cvs"); 634 if (retval == NULL) 635 error (1, errno, "cannot generate temporary filename"); 636 /* tempnam returns a pointer to a newly malloc'd string, so there's 637 no need for a xstrdup */ 638 return retval; 639 } 640 #else 641 char * 642 cvs_temp_name () 643 { 644 # ifdef HAVE_MKTEMP 645 char *value; 646 char *retval; 647 648 value = xmalloc (strlen (Tmpdir) + 40); 649 sprintf (value, "%s/%s", Tmpdir, "cvsXXXXXX" ); 650 retval = mktemp (value); 651 652 if (retval == NULL) 653 error (1, errno, "cannot generate temporary filename"); 654 return value; 655 # else 656 char value[L_tmpnam + 1]; 657 char *retval; 658 659 retval = tmpnam (value); 660 if (retval == NULL) 661 error (1, errno, "cannot generate temporary filename"); 662 return xstrdup (value); 663 # endif 664 } 665 #endif 666 667 /* Return non-zero iff FILENAME is absolute. 668 Trivial under Unix, but more complicated under other systems. */ 669 int 670 isabsolute (filename) 671 const char *filename; 672 { 673 return filename[0] == '/'; 674 } 675 676 677 /* Return a pointer into PATH's last component. */ 678 char * 679 last_component (path) 680 char *path; 681 { 682 char *last = strrchr (path, '/'); 683 684 if (last) 685 return last + 1; 686 else 687 return path; 688 } 689 690 /* Return the home directory. Returns a pointer to storage 691 managed by this function or its callees (currently getenv). 692 This function will return the same thing every time it is 693 called. */ 694 char * 695 get_homedir () 696 { 697 static char *home = NULL; 698 char *env = getenv ("HOME"); 699 struct passwd *pw; 700 701 if (home != NULL) 702 return home; 703 704 if (env) 705 home = env; 706 else if ((pw = (struct passwd *) getpwuid (getuid ())) 707 && pw->pw_dir) 708 home = xstrdup (pw->pw_dir); 709 else 710 return 0; 711 712 return home; 713 } 714 715 /* See cvs.h for description. On unix this does nothing, because the 716 shell expands the wildcards. */ 717 void 718 expand_wild (argc, argv, pargc, pargv) 719 int argc; 720 char **argv; 721 int *pargc; 722 char ***pargv; 723 { 724 int i; 725 *pargc = argc; 726 *pargv = (char **) xmalloc (argc * sizeof (char *)); 727 for (i = 0; i < argc; ++i) 728 (*pargv)[i] = xstrdup (argv[i]); 729 } 730 731 #ifdef SERVER_SUPPORT 732 /* Case-insensitive string compare. I know that some systems 733 have such a routine, but I'm not sure I see any reasons for 734 dealing with the hair of figuring out whether they do (I haven't 735 looked into whether this is a performance bottleneck; I would guess 736 not). */ 737 int 738 cvs_casecmp (str1, str2) 739 char *str1; 740 char *str2; 741 { 742 char *p; 743 char *q; 744 int pqdiff; 745 746 p = str1; 747 q = str2; 748 while ((pqdiff = tolower (*p) - tolower (*q)) == 0) 749 { 750 if (*p == '\0') 751 return 0; 752 ++p; 753 ++q; 754 } 755 return pqdiff; 756 } 757 758 /* Case-insensitive file open. As you can see, this is an expensive 759 call. We don't regard it as our main strategy for dealing with 760 case-insensitivity. Returns errno code or 0 for success. Puts the 761 new file in *FP. NAME and MODE are as for fopen. If PATHP is not 762 NULL, then put a malloc'd string containing the pathname as found 763 into *PATHP. *PATHP is only set if the return value is 0. 764 765 Might be cleaner to separate the file finding (which just gives 766 *PATHP) from the file opening (which the caller can do). For one 767 thing, might make it easier to know whether to put NAME or *PATHP 768 into error messages. */ 769 int 770 fopen_case (name, mode, fp, pathp) 771 char *name; 772 char *mode; 773 FILE **fp; 774 char **pathp; 775 { 776 struct dirent *dp; 777 DIR *dirp; 778 char *dir; 779 char *fname; 780 char *found_name; 781 int retval; 782 783 /* Separate NAME into directory DIR and filename within the directory 784 FNAME. */ 785 dir = xstrdup (name); 786 fname = strrchr (dir, '/'); 787 if (fname == NULL) 788 error (1, 0, "internal error: relative pathname in fopen_case"); 789 *fname++ = '\0'; 790 791 found_name = NULL; 792 dirp = CVS_OPENDIR (dir); 793 if (dirp == NULL) 794 { 795 if (existence_error (errno)) 796 { 797 /* This can happen if we are looking in the Attic and the Attic 798 directory does not exist. Return the error to the caller; 799 they know what to do with it. */ 800 retval = errno; 801 goto out; 802 } 803 else 804 { 805 /* Give a fatal error; that way the error message can be 806 more specific than if we returned the error to the caller. */ 807 error (1, errno, "cannot read directory %s", dir); 808 } 809 } 810 errno = 0; 811 while ((dp = readdir (dirp)) != NULL) 812 { 813 if (cvs_casecmp (dp->d_name, fname) == 0) 814 { 815 if (found_name != NULL) 816 error (1, 0, "%s is ambiguous; could mean %s or %s", 817 fname, dp->d_name, found_name); 818 found_name = xstrdup (dp->d_name); 819 } 820 } 821 if (errno != 0) 822 error (1, errno, "cannot read directory %s", dir); 823 closedir (dirp); 824 825 if (found_name == NULL) 826 { 827 *fp = NULL; 828 retval = ENOENT; 829 } 830 else 831 { 832 char *p; 833 834 /* Copy the found name back into DIR. We are assuming that 835 found_name is the same length as fname, which is true as 836 long as the above code is just ignoring case and not other 837 aspects of filename syntax. */ 838 p = dir + strlen (dir); 839 *p++ = '/'; 840 strcpy (p, found_name); 841 *fp = fopen (dir, mode); 842 if (*fp == NULL) 843 retval = errno; 844 else 845 retval = 0; 846 } 847 848 if (pathp == NULL) 849 free (dir); 850 else if (retval != 0) 851 free (dir); 852 else 853 *pathp = dir; 854 free (found_name); 855 out: 856 return retval; 857 } 858 #endif /* SERVER_SUPPORT */ 859