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