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 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)) 49 { 50 char *source = xreadlink (from); 51 symlink (source, to); 52 free (source); 53 return; 54 } 55 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) 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 #ifdef SERVER_SUPPORT 381 (void) fprintf (stderr, "%c-> chmod(%s,%o)\n", 382 (server_active) ? 'S' : ' ', fname, 383 (unsigned int) mode); 384 #else 385 (void) fprintf (stderr, "-> chmod(%s,%o)\n", fname, 386 (unsigned int) mode); 387 #endif 388 if (noexec) 389 return; 390 391 if (chmod (fname, mode) < 0) 392 error (0, errno, "cannot change mode of file %s", fname); 393 } 394 395 /* 396 * Rename a file and die if it fails 397 */ 398 void 399 rename_file (from, to) 400 const char *from; 401 const char *to; 402 { 403 if (trace) 404 #ifdef SERVER_SUPPORT 405 (void) fprintf (stderr, "%c-> rename(%s,%s)\n", 406 (server_active) ? 'S' : ' ', from, to); 407 #else 408 (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to); 409 #endif 410 if (noexec) 411 return; 412 413 if (rename (from, to) < 0) 414 error (1, errno, "cannot rename file %s to %s", from, to); 415 } 416 417 /* 418 * link a file, if possible. Warning: the Windows NT version of this 419 * function just copies the file, so only use this function in ways 420 * that can deal with either a link or a copy. 421 */ 422 int 423 link_file (from, to) 424 const char *from; 425 const char *to; 426 { 427 if (trace) 428 #ifdef SERVER_SUPPORT 429 (void) fprintf (stderr, "%c-> link(%s,%s)\n", 430 (server_active) ? 'S' : ' ', from, to); 431 #else 432 (void) fprintf (stderr, "-> link(%s,%s)\n", from, to); 433 #endif 434 if (noexec) 435 return (0); 436 437 return (link (from, to)); 438 } 439 440 /* 441 * unlink a file, if possible. 442 */ 443 int 444 unlink_file (f) 445 const char *f; 446 { 447 if (trace) 448 #ifdef SERVER_SUPPORT 449 (void) fprintf (stderr, "%c-> unlink(%s)\n", 450 (server_active) ? 'S' : ' ', f); 451 #else 452 (void) fprintf (stderr, "-> unlink(%s)\n", f); 453 #endif 454 if (noexec) 455 return (0); 456 457 return (unlink (f)); 458 } 459 460 /* 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 */ 465 int 466 unlink_file_dir (f) 467 const char *f; 468 { 469 struct stat sb; 470 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. 487 So we first call stat() to see if it is OK to call unlink(). This 488 doesn't quite work--if someone creates a directory between the 489 call to stat() and the call to unlink(), we'll still corrupt 490 the filesystem. Where is the Unix Haters Handbook when you need 491 it? */ 492 if (stat (f, &sb) < 0) 493 { 494 if (existence_error (errno)) 495 { 496 /* The file or directory doesn't exist anyhow. */ 497 return -1; 498 } 499 } 500 else if (S_ISDIR (sb.st_mode)) 501 return deep_remove_dir (f); 502 503 return unlink (f); 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 510 static int 511 deep_remove_dir (path) 512 const char *path; 513 { 514 DIR *dirp; 515 struct dirent *dp; 516 517 if (rmdir (path) != 0) 518 { 519 if (errno == ENOTEMPTY 520 || errno == EEXIST 521 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug 522 (it defines ENOTEMPTY and EEXIST to 17 but actually 523 returns 87). */ 524 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87)) 525 { 526 if ((dirp = opendir (path)) == NULL) 527 /* If unable to open the directory return 528 * an error 529 */ 530 return -1; 531 532 while ((dp = readdir (dirp)) != NULL) 533 { 534 char *buf; 535 536 if (strcmp (dp->d_name, ".") == 0 || 537 strcmp (dp->d_name, "..") == 0) 538 continue; 539 540 buf = xmalloc (strlen (path) + strlen (dp->d_name) + 5); 541 sprintf (buf, "%s/%s", path, dp->d_name); 542 543 /* See comment in unlink_file_dir explanation of why we use 544 isdir instead of just calling unlink and checking the 545 status. */ 546 if (isdir(buf)) 547 { 548 if (deep_remove_dir(buf)) 549 { 550 closedir(dirp); 551 free (buf); 552 return -1; 553 } 554 } 555 else 556 { 557 if (unlink (buf) != 0) 558 { 559 closedir(dirp); 560 free (buf); 561 return -1; 562 } 563 } 564 free (buf); 565 } 566 closedir (dirp); 567 return rmdir (path); 568 } 569 else 570 return -1; 571 } 572 573 /* Was able to remove the directory return 0 */ 574 return 0; 575 } 576 577 /* Read NCHARS bytes from descriptor FD into BUF. 578 Return the number of characters successfully read. 579 The number returned is always NCHARS unless end-of-file or error. */ 580 static size_t 581 block_read (fd, buf, nchars) 582 int fd; 583 char *buf; 584 size_t nchars; 585 { 586 char *bp = buf; 587 size_t nread; 588 589 do 590 { 591 nread = read (fd, bp, nchars); 592 if (nread == (size_t)-1) 593 { 594 #ifdef EINTR 595 if (errno == EINTR) 596 continue; 597 #endif 598 return (size_t)-1; 599 } 600 601 if (nread == 0) 602 break; 603 604 bp += nread; 605 nchars -= nread; 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. 616 */ 617 int 618 xcmp (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 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); 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) 671 ret = 0; 672 else 673 { 674 /* FIXME: compute the optimal buffer size by computing the least 675 common multiple of the files st_blocks field */ 676 size_t buf_size = 8 * 1024; 677 size_t read1; 678 size_t read2; 679 680 buf1 = xmalloc (buf_size); 681 buf2 = xmalloc (buf_size); 682 683 do 684 { 685 read1 = block_read (fd1, buf1, buf_size); 686 if (read1 == (size_t)-1) 687 error (1, errno, "cannot read file %s for comparing", file1); 688 689 read2 = block_read (fd2, buf2, buf_size); 690 if (read2 == (size_t)-1) 691 error (1, errno, "cannot read file %s for comparing", file2); 692 693 /* assert (read1 == read2); */ 694 695 ret = memcmp(buf1, buf2, read1); 696 } while (ret == 0 && read1 == buf_size); 697 698 free (buf1); 699 free (buf2); 700 } 701 702 (void) close (fd1); 703 (void) close (fd2); 704 return (ret); 705 } 706 707 /* Generate a unique temporary filename. Returns a pointer to a newly 708 malloc'd string containing the name. Returns successfully or not at 709 all. */ 710 /* There are at least three functions for generating temporary 711 filenames. We use tempnam (SVID 3) if possible, else mktemp (BSD 712 4.3), and as last resort tmpnam (POSIX). Reason is that tempnam and 713 mktemp both allow to specify the directory in which the temporary 714 file will be created. */ 715 #ifdef HAVE_TEMPNAM 716 char * 717 cvs_temp_name () 718 { 719 char *retval; 720 721 retval = tempnam (Tmpdir, "cvs"); 722 if (retval == NULL) 723 error (1, errno, "cannot generate temporary filename"); 724 /* tempnam returns a pointer to a newly malloc'd string, so there's 725 no need for a xstrdup */ 726 return retval; 727 } 728 #else 729 char * 730 cvs_temp_name () 731 { 732 # ifdef HAVE_MKTEMP 733 char *value; 734 char *retval; 735 736 value = xmalloc (strlen (Tmpdir) + 40); 737 sprintf (value, "%s/%s", Tmpdir, "cvsXXXXXX" ); 738 retval = mktemp (value); 739 740 if (retval == NULL) 741 error (1, errno, "cannot generate temporary filename"); 742 return value; 743 # else 744 char value[L_tmpnam + 1]; 745 char *retval; 746 747 retval = tmpnam (value); 748 if (retval == NULL) 749 error (1, errno, "cannot generate temporary filename"); 750 return xstrdup (value); 751 # endif 752 } 753 #endif 754 755 /* Return non-zero iff FILENAME is absolute. 756 Trivial under Unix, but more complicated under other systems. */ 757 int 758 isabsolute (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 */ 768 char * 769 xreadlink (link) 770 const char *link; 771 { 772 char *file = NULL; 773 int buflen = BUFSIZ; 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 798 /* Return a pointer into PATH's last component. */ 799 char * 800 last_component (path) 801 char *path; 802 { 803 char *last = strrchr (path, '/'); 804 805 if (last && (last != path)) 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 814 called. Returns NULL if there is no home directory. 815 816 Note that for a pserver server, this may return root's home 817 directory. What typically happens is that upon being started from 818 inetd, before switching users, the code in cvsrc.c calls 819 get_homedir which remembers root's home directory in the static 820 variable. Then the switch happens and get_homedir might return a 821 directory that we don't even have read or execute permissions for 822 (which is bad, when various parts of CVS try to read there). One 823 fix would be to make the value returned by get_homedir only good 824 until the next call (which would free the old value). Another fix 825 would be to just always malloc our answer, and let the caller free 826 it (that is best, because some day we may need to be reentrant). 827 828 The workaround is to put -f in inetd.conf which means that 829 get_homedir won't get called until after the switch in user ID. 830 831 The whole concept of a "home directory" on the server is pretty 832 iffy, although I suppose some people probably are relying on it for 833 .cvsrc and such, in the cases where it works. */ 834 char * 835 get_homedir () 836 { 837 static char *home = NULL; 838 char *env = getenv ("HOME"); 839 struct passwd *pw; 840 841 if (home != NULL) 842 return home; 843 844 if (env) 845 home = env; 846 else if ((pw = (struct passwd *) getpwuid (getuid ())) 847 && pw->pw_dir) 848 home = xstrdup (pw->pw_dir); 849 else 850 return 0; 851 852 return home; 853 } 854 855 /* See cvs.h for description. On unix this does nothing, because the 856 shell expands the wildcards. */ 857 void 858 expand_wild (argc, argv, pargc, pargv) 859 int argc; 860 char **argv; 861 int *pargc; 862 char ***pargv; 863 { 864 int i; 865 *pargc = argc; 866 *pargv = (char **) xmalloc (argc * sizeof (char *)); 867 for (i = 0; i < argc; ++i) 868 (*pargv)[i] = xstrdup (argv[i]); 869 } 870 871 #ifdef SERVER_SUPPORT 872 /* Case-insensitive string compare. I know that some systems 873 have such a routine, but I'm not sure I see any reasons for 874 dealing with the hair of figuring out whether they do (I haven't 875 looked into whether this is a performance bottleneck; I would guess 876 not). */ 877 int 878 cvs_casecmp (str1, str2) 879 char *str1; 880 char *str2; 881 { 882 char *p; 883 char *q; 884 int pqdiff; 885 886 p = str1; 887 q = str2; 888 while ((pqdiff = tolower (*p) - tolower (*q)) == 0) 889 { 890 if (*p == '\0') 891 return 0; 892 ++p; 893 ++q; 894 } 895 return pqdiff; 896 } 897 898 /* Case-insensitive file open. As you can see, this is an expensive 899 call. We don't regard it as our main strategy for dealing with 900 case-insensitivity. Returns errno code or 0 for success. Puts the 901 new file in *FP. NAME and MODE are as for fopen. If PATHP is not 902 NULL, then put a malloc'd string containing the pathname as found 903 into *PATHP. *PATHP is only set if the return value is 0. 904 905 Might be cleaner to separate the file finding (which just gives 906 *PATHP) from the file opening (which the caller can do). For one 907 thing, might make it easier to know whether to put NAME or *PATHP 908 into error messages. */ 909 int 910 fopen_case (name, mode, fp, pathp) 911 char *name; 912 char *mode; 913 FILE **fp; 914 char **pathp; 915 { 916 struct dirent *dp; 917 DIR *dirp; 918 char *dir; 919 char *fname; 920 char *found_name; 921 int retval; 922 923 /* Separate NAME into directory DIR and filename within the directory 924 FNAME. */ 925 dir = xstrdup (name); 926 fname = strrchr (dir, '/'); 927 if (fname == NULL) 928 error (1, 0, "internal error: relative pathname in fopen_case"); 929 *fname++ = '\0'; 930 931 found_name = NULL; 932 dirp = CVS_OPENDIR (dir); 933 if (dirp == NULL) 934 { 935 if (existence_error (errno)) 936 { 937 /* This can happen if we are looking in the Attic and the Attic 938 directory does not exist. Return the error to the caller; 939 they know what to do with it. */ 940 retval = errno; 941 goto out; 942 } 943 else 944 { 945 /* Give a fatal error; that way the error message can be 946 more specific than if we returned the error to the caller. */ 947 error (1, errno, "cannot read directory %s", dir); 948 } 949 } 950 errno = 0; 951 while ((dp = readdir (dirp)) != NULL) 952 { 953 if (cvs_casecmp (dp->d_name, fname) == 0) 954 { 955 if (found_name != NULL) 956 error (1, 0, "%s is ambiguous; could mean %s or %s", 957 fname, dp->d_name, found_name); 958 found_name = xstrdup (dp->d_name); 959 } 960 } 961 if (errno != 0) 962 error (1, errno, "cannot read directory %s", dir); 963 closedir (dirp); 964 965 if (found_name == NULL) 966 { 967 *fp = NULL; 968 retval = ENOENT; 969 } 970 else 971 { 972 char *p; 973 974 /* Copy the found name back into DIR. We are assuming that 975 found_name is the same length as fname, which is true as 976 long as the above code is just ignoring case and not other 977 aspects of filename syntax. */ 978 p = dir + strlen (dir); 979 *p++ = '/'; 980 strcpy (p, found_name); 981 *fp = fopen (dir, mode); 982 if (*fp == NULL) 983 retval = errno; 984 else 985 retval = 0; 986 } 987 988 if (pathp == NULL) 989 free (dir); 990 else if (retval != 0) 991 free (dir); 992 else 993 *pathp = dir; 994 free (found_name); 995 out: 996 return retval; 997 } 998 #endif /* SERVER_SUPPORT */ 999