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 (void) fprintf (stderr, "%s-> copy(%s,%s)\n", 38 CLIENT_SERVER_STR, from, to); 39 if (noexec) 40 return; 41 42 /* If the file to be copied is a link or a device, then just create 43 the new link or device appropriately. */ 44 if (islink (from)) 45 { 46 char *source = xreadlink (from); 47 symlink (source, to); 48 free (source); 49 return; 50 } 51 52 if (isdevice (from)) 53 { 54 #if defined(HAVE_MKNOD) && defined(HAVE_ST_RDEV) 55 if (stat (from, &sb) < 0) 56 error (1, errno, "cannot stat %s", from); 57 mknod (to, sb.st_mode, sb.st_rdev); 58 #else 59 error (1, 0, "cannot copy device files on this system (%s)", from); 60 #endif 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) 72 { 73 char buf[BUFSIZ]; 74 int n; 75 76 for (;;) 77 { 78 n = read (fdin, buf, sizeof(buf)); 79 if (n == -1) 80 { 81 #ifdef EINTR 82 if (errno == EINTR) 83 continue; 84 #endif 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 } 93 } 94 95 #ifdef HAVE_FSYNC 96 if (fsync (fdout)) 97 error (1, errno, "cannot fsync file %s after copying", to); 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); 105 } 106 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 * & 115 stat buf. */ 116 117 /* 118 * Returns non-zero if the argument file is a directory, or is a symbolic 119 * link which points to a directory. 120 */ 121 int 122 isdir (file) 123 const char *file; 124 { 125 struct stat sb; 126 127 if (stat (file, &sb) < 0) 128 return (0); 129 return (S_ISDIR (sb.st_mode)); 130 } 131 132 /* 133 * Returns non-zero if the argument file is a symbolic link. 134 */ 135 int 136 islink (file) 137 const char *file; 138 { 139 #ifdef S_ISLNK 140 struct stat sb; 141 142 if (CVS_LSTAT (file, &sb) < 0) 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 */ 154 int 155 isdevice (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 /* 174 * Returns non-zero if the argument file exists. 175 */ 176 int 177 isfile (file) 178 const char *file; 179 { 180 return isaccessible(file, F_OK); 181 } 182 183 /* 184 * Returns non-zero if the argument file is readable. 185 */ 186 int 187 isreadable (file) 188 const char *file; 189 { 190 return isaccessible(file, R_OK); 191 } 192 193 /* 194 * Returns non-zero if the argument file is writable. 195 */ 196 int 197 iswritable (file) 198 const char *file; 199 { 200 return isaccessible(file, W_OK); 201 } 202 203 /* 204 * Returns non-zero if the argument file is accessable according to 205 * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid 206 * bits set. 207 */ 208 int 209 isaccessible (file, mode) 210 const char *file; 211 const int mode; 212 { 213 #ifdef SETXID_SUPPORT 214 struct stat sb; 215 int umask = 0; 216 int gmask = 0; 217 int omask = 0; 218 int uid; 219 220 if (stat(file, &sb) == -1) 221 return 0; 222 if (mode == F_OK) 223 return 1; 224 225 uid = geteuid(); 226 if (uid == 0) /* superuser */ 227 { 228 if (mode & X_OK) 229 return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH); 230 else 231 return 1; 232 } 233 234 if (mode & R_OK) 235 { 236 umask |= S_IRUSR; 237 gmask |= S_IRGRP; 238 omask |= S_IROTH; 239 } 240 if (mode & W_OK) 241 { 242 umask |= S_IWUSR; 243 gmask |= S_IWGRP; 244 omask |= S_IWOTH; 245 } 246 if (mode & X_OK) 247 { 248 umask |= S_IXUSR; 249 gmask |= S_IXGRP; 250 omask |= S_IXOTH; 251 } 252 253 if (sb.st_uid == uid) 254 return (sb.st_mode & umask) == umask; 255 else if (sb.st_gid == getegid()) 256 return (sb.st_mode & gmask) == gmask; 257 else 258 return (sb.st_mode & omask) == omask; 259 #else 260 return access(file, mode) == 0; 261 #endif 262 } 263 264 /* 265 * Open a file and die if it fails 266 */ 267 FILE * 268 open_file (name, mode) 269 const char *name; 270 const char *mode; 271 { 272 FILE *fp; 273 274 if ((fp = fopen (name, mode)) == NULL) 275 error (1, errno, "cannot open %s", name); 276 return (fp); 277 } 278 279 /* 280 * Make a directory and die if it fails 281 */ 282 void 283 make_directory (name) 284 const char *name; 285 { 286 struct stat sb; 287 288 if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode))) 289 error (0, 0, "%s already exists but is not a directory", name); 290 if (!noexec && mkdir (name, 0777) < 0) 291 error (1, errno, "cannot make directory %s", name); 292 } 293 294 /* 295 * Make a path to the argument directory, printing a message if something 296 * goes wrong. 297 */ 298 void 299 make_directories (name) 300 const char *name; 301 { 302 char *cp; 303 304 if (noexec) 305 return; 306 307 if (mkdir (name, 0777) == 0 || errno == EEXIST) 308 return; 309 if (! existence_error (errno)) 310 { 311 error (0, errno, "cannot make path to %s", name); 312 return; 313 } 314 if ((cp = strrchr (name, '/')) == NULL) 315 return; 316 *cp = '\0'; 317 make_directories (name); 318 *cp++ = '/'; 319 if (*cp == '\0') 320 return; 321 (void) mkdir (name, 0777); 322 } 323 324 /* Create directory NAME if it does not already exist; fatal error for 325 other errors. Returns 0 if directory was created; 1 if it already 326 existed. */ 327 int 328 mkdir_if_needed (name) 329 char *name; 330 { 331 if (mkdir (name, 0777) < 0) 332 { 333 if (!(errno == EEXIST 334 || (errno == EACCES && isdir (name)))) 335 error (1, errno, "cannot make directory %s", name); 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. 347 */ 348 void 349 xchmod (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 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); 367 if (writable) 368 { 369 mode = sb.st_mode | (~oumask 370 & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0) 371 | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0) 372 | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0))); 373 } 374 else 375 { 376 mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask; 377 } 378 379 if (trace) 380 (void) fprintf (stderr, "%s-> chmod(%s,%o)\n", 381 CLIENT_SERVER_STR, fname, 382 (unsigned int) mode); 383 if (noexec) 384 return; 385 386 if (chmod (fname, mode) < 0) 387 error (0, errno, "cannot change mode of file %s", fname); 388 } 389 390 /* 391 * Rename a file and die if it fails 392 */ 393 void 394 rename_file (from, to) 395 const char *from; 396 const char *to; 397 { 398 if (trace) 399 (void) fprintf (stderr, "%s-> rename(%s,%s)\n", 400 CLIENT_SERVER_STR, from, to); 401 if (noexec) 402 return; 403 404 if (rename (from, to) < 0) 405 error (1, errno, "cannot rename file %s to %s", from, to); 406 } 407 408 /* 409 * unlink a file, if possible. 410 */ 411 int 412 unlink_file (f) 413 const char *f; 414 { 415 if (trace) 416 (void) fprintf (stderr, "%s-> unlink(%s)\n", 417 CLIENT_SERVER_STR, f); 418 if (noexec) 419 return (0); 420 421 return (unlink (f)); 422 } 423 424 /* 425 * Unlink a file or dir, if possible. If it is a directory do a deep 426 * removal of all of the files in the directory. Return -1 on error 427 * (in which case errno is set). 428 */ 429 int 430 unlink_file_dir (f) 431 const char *f; 432 { 433 struct stat sb; 434 435 if (trace 436 #ifdef SERVER_SUPPORT 437 /* This is called by the server parent process in contexts where 438 it is not OK to send output (e.g. after we sent "ok" to the 439 client). */ 440 && !server_active 441 #endif 442 ) 443 (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f); 444 445 if (noexec) 446 return (0); 447 448 /* For at least some unices, if root tries to unlink() a directory, 449 instead of doing something rational like returning EISDIR, 450 the system will gleefully go ahead and corrupt the filesystem. 451 So we first call stat() to see if it is OK to call unlink(). This 452 doesn't quite work--if someone creates a directory between the 453 call to stat() and the call to unlink(), we'll still corrupt 454 the filesystem. Where is the Unix Haters Handbook when you need 455 it? */ 456 if (stat (f, &sb) < 0) 457 { 458 if (existence_error (errno)) 459 { 460 /* The file or directory doesn't exist anyhow. */ 461 return -1; 462 } 463 } 464 else if (S_ISDIR (sb.st_mode)) 465 return deep_remove_dir (f); 466 467 return unlink (f); 468 } 469 470 /* Remove a directory and everything it contains. Returns 0 for 471 * success, -1 for failure (in which case errno is set). 472 */ 473 474 static int 475 deep_remove_dir (path) 476 const char *path; 477 { 478 DIR *dirp; 479 struct dirent *dp; 480 481 if (rmdir (path) != 0) 482 { 483 if (errno == ENOTEMPTY 484 || errno == EEXIST 485 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug 486 (it defines ENOTEMPTY and EEXIST to 17 but actually 487 returns 87). */ 488 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87)) 489 { 490 if ((dirp = opendir (path)) == NULL) 491 /* If unable to open the directory return 492 * an error 493 */ 494 return -1; 495 496 errno = 0; 497 while ((dp = readdir (dirp)) != NULL) 498 { 499 char *buf; 500 501 if (strcmp (dp->d_name, ".") == 0 || 502 strcmp (dp->d_name, "..") == 0) 503 continue; 504 505 buf = xmalloc (strlen (path) + strlen (dp->d_name) + 5); 506 sprintf (buf, "%s/%s", path, dp->d_name); 507 508 /* See comment in unlink_file_dir explanation of why we use 509 isdir instead of just calling unlink and checking the 510 status. */ 511 if (isdir(buf)) 512 { 513 if (deep_remove_dir(buf)) 514 { 515 closedir(dirp); 516 free (buf); 517 return -1; 518 } 519 } 520 else 521 { 522 if (unlink (buf) != 0) 523 { 524 closedir(dirp); 525 free (buf); 526 return -1; 527 } 528 } 529 free (buf); 530 531 errno = 0; 532 } 533 if (errno != 0) 534 { 535 int save_errno = errno; 536 closedir (dirp); 537 errno = save_errno; 538 return -1; 539 } 540 closedir (dirp); 541 return rmdir (path); 542 } 543 else 544 return -1; 545 } 546 547 /* Was able to remove the directory return 0 */ 548 return 0; 549 } 550 551 /* Read NCHARS bytes from descriptor FD into BUF. 552 Return the number of characters successfully read. 553 The number returned is always NCHARS unless end-of-file or error. */ 554 static size_t 555 block_read (fd, buf, nchars) 556 int fd; 557 char *buf; 558 size_t nchars; 559 { 560 char *bp = buf; 561 size_t nread; 562 563 do 564 { 565 nread = read (fd, bp, nchars); 566 if (nread == (size_t)-1) 567 { 568 #ifdef EINTR 569 if (errno == EINTR) 570 continue; 571 #endif 572 return (size_t)-1; 573 } 574 575 if (nread == 0) 576 break; 577 578 bp += nread; 579 nchars -= nread; 580 } while (nchars != 0); 581 582 return bp - buf; 583 } 584 585 586 /* 587 * Compare "file1" to "file2". Return non-zero if they don't compare exactly. 588 * If FILE1 and FILE2 are special files, compare their salient characteristics 589 * (i.e. major/minor device numbers, links, etc. 590 */ 591 int 592 xcmp (file1, file2) 593 const char *file1; 594 const char *file2; 595 { 596 char *buf1, *buf2; 597 struct stat sb1, sb2; 598 int fd1, fd2; 599 int ret; 600 601 if (CVS_LSTAT (file1, &sb1) < 0) 602 error (1, errno, "cannot lstat %s", file1); 603 if (CVS_LSTAT (file2, &sb2) < 0) 604 error (1, errno, "cannot lstat %s", file2); 605 606 /* If FILE1 and FILE2 are not the same file type, they are unequal. */ 607 if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT)) 608 return 1; 609 610 /* If FILE1 and FILE2 are symlinks, they are equal if they point to 611 the same thing. */ 612 if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode)) 613 { 614 int result; 615 buf1 = xreadlink (file1); 616 buf2 = xreadlink (file2); 617 result = (strcmp (buf1, buf2) == 0); 618 free (buf1); 619 free (buf2); 620 return result; 621 } 622 623 /* If FILE1 and FILE2 are devices, they are equal if their device 624 numbers match. */ 625 if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode)) 626 { 627 #ifdef HAVE_ST_RDEV 628 if (sb1.st_rdev == sb2.st_rdev) 629 return 0; 630 else 631 return 1; 632 #else 633 error (1, 0, "cannot compare device files on this system (%s and %s)", 634 file1, file2); 635 #endif 636 } 637 638 if ((fd1 = open (file1, O_RDONLY)) < 0) 639 error (1, errno, "cannot open file %s for comparing", file1); 640 if ((fd2 = open (file2, O_RDONLY)) < 0) 641 error (1, errno, "cannot open file %s for comparing", file2); 642 643 /* A generic file compare routine might compare st_dev & st_ino here 644 to see if the two files being compared are actually the same file. 645 But that won't happen in CVS, so we won't bother. */ 646 647 if (sb1.st_size != sb2.st_size) 648 ret = 1; 649 else if (sb1.st_size == 0) 650 ret = 0; 651 else 652 { 653 /* FIXME: compute the optimal buffer size by computing the least 654 common multiple of the files st_blocks field */ 655 size_t buf_size = 8 * 1024; 656 size_t read1; 657 size_t read2; 658 659 buf1 = xmalloc (buf_size); 660 buf2 = xmalloc (buf_size); 661 662 do 663 { 664 read1 = block_read (fd1, buf1, buf_size); 665 if (read1 == (size_t)-1) 666 error (1, errno, "cannot read file %s for comparing", file1); 667 668 read2 = block_read (fd2, buf2, buf_size); 669 if (read2 == (size_t)-1) 670 error (1, errno, "cannot read file %s for comparing", file2); 671 672 /* assert (read1 == read2); */ 673 674 ret = memcmp(buf1, buf2, read1); 675 } while (ret == 0 && read1 == buf_size); 676 677 free (buf1); 678 free (buf2); 679 } 680 681 (void) close (fd1); 682 (void) close (fd2); 683 return (ret); 684 } 685 686 /* Generate a unique temporary filename. Returns a pointer to a newly 687 malloc'd string containing the name. Returns successfully or not at 688 all. */ 689 /* There are at least three functions for generating temporary 690 filenames. We use tempnam (SVID 3) if possible, else mktemp (BSD 691 4.3), and as last resort tmpnam (POSIX). Reason is that tempnam and 692 mktemp both allow to specify the directory in which the temporary 693 file will be created. */ 694 #ifdef HAVE_TEMPNAM 695 char * 696 cvs_temp_name () 697 { 698 char *retval; 699 700 retval = tempnam (Tmpdir, "cvs"); 701 if (retval == NULL) 702 error (1, errno, "cannot generate temporary filename"); 703 /* tempnam returns a pointer to a newly malloc'd string, so there's 704 no need for a xstrdup */ 705 return retval; 706 } 707 #else 708 char * 709 cvs_temp_name () 710 { 711 # ifdef HAVE_MKTEMP 712 char *value; 713 char *retval; 714 715 value = xmalloc (strlen (Tmpdir) + 40); 716 sprintf (value, "%s/%s", Tmpdir, "cvsXXXXXX" ); 717 retval = mktemp (value); 718 719 if (retval == NULL) 720 error (1, errno, "cannot generate temporary filename"); 721 return value; 722 # else 723 char value[L_tmpnam + 1]; 724 char *retval; 725 726 retval = tmpnam (value); 727 if (retval == NULL) 728 error (1, errno, "cannot generate temporary filename"); 729 return xstrdup (value); 730 # endif 731 } 732 #endif 733 734 /* Return non-zero iff FILENAME is absolute. 735 Trivial under Unix, but more complicated under other systems. */ 736 int 737 isabsolute (filename) 738 const char *filename; 739 { 740 return filename[0] == '/'; 741 } 742 743 /* 744 * Return a string (dynamically allocated) with the name of the file to which 745 * LINK is symlinked. 746 */ 747 char * 748 xreadlink (link) 749 const char *link; 750 { 751 char *file = NULL; 752 char *tfile; 753 int buflen = 128; 754 int link_name_len; 755 756 if (!islink (link)) 757 return NULL; 758 759 /* Get the name of the file to which `from' is linked. 760 FIXME: what portability issues arise here? Are readlink & 761 ENAMETOOLONG defined on all systems? -twp */ 762 do 763 { 764 file = xrealloc (file, buflen); 765 link_name_len = readlink (link, file, buflen - 1); 766 buflen *= 2; 767 } 768 while (link_name_len < 0 && errno == ENAMETOOLONG); 769 770 if (link_name_len < 0) 771 error (1, errno, "cannot readlink %s", link); 772 773 file[link_name_len] = '\0'; 774 775 tfile = xstrdup (file); 776 free (file); 777 778 return tfile; 779 } 780 781 782 /* Return a pointer into PATH's last component. */ 783 char * 784 last_component (path) 785 char *path; 786 { 787 char *last = strrchr (path, '/'); 788 789 if (last && (last != path)) 790 return last + 1; 791 else 792 return path; 793 } 794 795 /* Return the home directory. Returns a pointer to storage 796 managed by this function or its callees (currently getenv). 797 This function will return the same thing every time it is 798 called. Returns NULL if there is no home directory. 799 800 Note that for a pserver server, this may return root's home 801 directory. What typically happens is that upon being started from 802 inetd, before switching users, the code in cvsrc.c calls 803 get_homedir which remembers root's home directory in the static 804 variable. Then the switch happens and get_homedir might return a 805 directory that we don't even have read or execute permissions for 806 (which is bad, when various parts of CVS try to read there). One 807 fix would be to make the value returned by get_homedir only good 808 until the next call (which would free the old value). Another fix 809 would be to just always malloc our answer, and let the caller free 810 it (that is best, because some day we may need to be reentrant). 811 812 The workaround is to put -f in inetd.conf which means that 813 get_homedir won't get called until after the switch in user ID. 814 815 The whole concept of a "home directory" on the server is pretty 816 iffy, although I suppose some people probably are relying on it for 817 .cvsrc and such, in the cases where it works. */ 818 char * 819 get_homedir () 820 { 821 static char *home = NULL; 822 char *env = getenv ("HOME"); 823 struct passwd *pw; 824 825 if (home != NULL) 826 return home; 827 828 if (env) 829 home = env; 830 else if ((pw = (struct passwd *) getpwuid (getuid ())) 831 && pw->pw_dir) 832 home = xstrdup (pw->pw_dir); 833 else 834 return 0; 835 836 return home; 837 } 838 839 /* See cvs.h for description. On unix this does nothing, because the 840 shell expands the wildcards. */ 841 void 842 expand_wild (argc, argv, pargc, pargv) 843 int argc; 844 char **argv; 845 int *pargc; 846 char ***pargv; 847 { 848 int i; 849 *pargc = argc; 850 *pargv = (char **) xmalloc (argc * sizeof (char *)); 851 for (i = 0; i < argc; ++i) 852 (*pargv)[i] = xstrdup (argv[i]); 853 } 854 855 #ifdef SERVER_SUPPORT 856 /* Case-insensitive string compare. I know that some systems 857 have such a routine, but I'm not sure I see any reasons for 858 dealing with the hair of figuring out whether they do (I haven't 859 looked into whether this is a performance bottleneck; I would guess 860 not). */ 861 int 862 cvs_casecmp (str1, str2) 863 char *str1; 864 char *str2; 865 { 866 char *p; 867 char *q; 868 int pqdiff; 869 870 p = str1; 871 q = str2; 872 while ((pqdiff = tolower (*p) - tolower (*q)) == 0) 873 { 874 if (*p == '\0') 875 return 0; 876 ++p; 877 ++q; 878 } 879 return pqdiff; 880 } 881 882 /* Case-insensitive file open. As you can see, this is an expensive 883 call. We don't regard it as our main strategy for dealing with 884 case-insensitivity. Returns errno code or 0 for success. Puts the 885 new file in *FP. NAME and MODE are as for fopen. If PATHP is not 886 NULL, then put a malloc'd string containing the pathname as found 887 into *PATHP. *PATHP is only set if the return value is 0. 888 889 Might be cleaner to separate the file finding (which just gives 890 *PATHP) from the file opening (which the caller can do). For one 891 thing, might make it easier to know whether to put NAME or *PATHP 892 into error messages. */ 893 int 894 fopen_case (name, mode, fp, pathp) 895 char *name; 896 char *mode; 897 FILE **fp; 898 char **pathp; 899 { 900 struct dirent *dp; 901 DIR *dirp; 902 char *dir; 903 char *fname; 904 char *found_name; 905 int retval; 906 907 /* Separate NAME into directory DIR and filename within the directory 908 FNAME. */ 909 dir = xstrdup (name); 910 fname = strrchr (dir, '/'); 911 if (fname == NULL) 912 error (1, 0, "internal error: relative pathname in fopen_case"); 913 *fname++ = '\0'; 914 915 found_name = NULL; 916 dirp = CVS_OPENDIR (dir); 917 if (dirp == NULL) 918 { 919 if (existence_error (errno)) 920 { 921 /* This can happen if we are looking in the Attic and the Attic 922 directory does not exist. Return the error to the caller; 923 they know what to do with it. */ 924 retval = errno; 925 goto out; 926 } 927 else 928 { 929 /* Give a fatal error; that way the error message can be 930 more specific than if we returned the error to the caller. */ 931 error (1, errno, "cannot read directory %s", dir); 932 } 933 } 934 errno = 0; 935 while ((dp = readdir (dirp)) != NULL) 936 { 937 if (cvs_casecmp (dp->d_name, fname) == 0) 938 { 939 if (found_name != NULL) 940 error (1, 0, "%s is ambiguous; could mean %s or %s", 941 fname, dp->d_name, found_name); 942 found_name = xstrdup (dp->d_name); 943 } 944 } 945 if (errno != 0) 946 error (1, errno, "cannot read directory %s", dir); 947 closedir (dirp); 948 949 if (found_name == NULL) 950 { 951 *fp = NULL; 952 retval = ENOENT; 953 } 954 else 955 { 956 char *p; 957 958 /* Copy the found name back into DIR. We are assuming that 959 found_name is the same length as fname, which is true as 960 long as the above code is just ignoring case and not other 961 aspects of filename syntax. */ 962 p = dir + strlen (dir); 963 *p++ = '/'; 964 strcpy (p, found_name); 965 *fp = fopen (dir, mode); 966 if (*fp == NULL) 967 retval = errno; 968 else 969 retval = 0; 970 } 971 972 if (pathp == NULL) 973 free (dir); 974 else if (retval != 0) 975 free (dir); 976 else 977 *pathp = dir; 978 free (found_name); 979 out: 980 return retval; 981 } 982 #endif /* SERVER_SUPPORT */ 983