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 #include <sys/param.h> 22 23 /* 24 * I don't know of a convenient way to test this at configure time, or else 25 * I'd certainly do it there. 26 */ 27 #if defined(NeXT) 28 #define LOSING_TMPNAM_FUNCTION 29 #endif 30 31 static int deep_remove_dir PROTO((const char *path)); 32 33 /* 34 * Copies "from" to "to". 35 */ 36 void 37 copy_file (from, to) 38 const char *from; 39 const char *to; 40 { 41 struct stat sb; 42 struct utimbuf t; 43 int fdin, fdout; 44 45 if (trace) 46 #ifdef SERVER_SUPPORT 47 (void) fprintf (stderr, "%c-> copy(%s,%s)\n", 48 (server_active) ? 'S' : ' ', from, to); 49 #else 50 (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to); 51 #endif 52 if (noexec) 53 return; 54 55 if ((fdin = open (from, O_RDONLY | O_BINARY)) < 0) 56 error (1, errno, "cannot open %s for copying", from); 57 if (fstat (fdin, &sb) < 0) 58 error (1, errno, "cannot fstat %s", from); 59 if ((fdout = open (to, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 60 (int) sb.st_mode & 07777)) < 0) 61 error (1, errno, "cannot create %s for copying", to); 62 if (sb.st_size > 0) 63 { 64 char buf[BUFSIZ]; 65 int n; 66 67 for (;;) 68 { 69 n = read (fdin, buf, sizeof(buf)); 70 if (n == -1) 71 { 72 #ifdef EINTR 73 if (errno == EINTR) 74 continue; 75 #endif 76 error (1, errno, "cannot read file %s for copying", from); 77 } 78 else if (n == 0) 79 break; 80 81 if (write(fdout, buf, n) != n) { 82 error (1, errno, "cannot write file %s for copying", to); 83 } 84 } 85 86 #ifdef HAVE_FSYNC 87 if (fsync (fdout)) 88 error (1, errno, "cannot fsync file %s after copying", to); 89 #endif 90 } 91 92 if (close (fdin) < 0) 93 error (0, errno, "cannot close %s", from); 94 if (close (fdout) < 0) 95 error (1, errno, "cannot close %s", to); 96 97 /* now, set the times for the copied file to match those of the original */ 98 memset ((char *) &t, 0, sizeof (t)); 99 t.actime = sb.st_atime; 100 t.modtime = sb.st_mtime; 101 (void) utime (to, &t); 102 } 103 104 /* FIXME-krp: these functions would benefit from caching the char * & 105 stat buf. */ 106 107 /* 108 * Returns non-zero if the argument file is a directory, or is a symbolic 109 * link which points to a directory. 110 */ 111 int 112 isdir (file) 113 const char *file; 114 { 115 struct stat sb; 116 117 if (stat (file, &sb) < 0) 118 return (0); 119 return (S_ISDIR (sb.st_mode)); 120 } 121 122 /* 123 * Returns non-zero if the argument file is a symbolic link. 124 */ 125 int 126 islink (file) 127 const char *file; 128 { 129 #ifdef S_ISLNK 130 struct stat sb; 131 132 if (lstat (file, &sb) < 0) 133 return (0); 134 return (S_ISLNK (sb.st_mode)); 135 #else 136 return (0); 137 #endif 138 } 139 140 /* 141 * Returns non-zero if the argument file exists. 142 */ 143 int 144 isfile (file) 145 const char *file; 146 { 147 return isaccessible(file, F_OK); 148 } 149 150 /* 151 * Returns non-zero if the argument file is readable. 152 */ 153 int 154 isreadable (file) 155 const char *file; 156 { 157 return isaccessible(file, R_OK); 158 } 159 160 /* 161 * Returns non-zero if the argument file is writable. 162 */ 163 int 164 iswritable (file) 165 const char *file; 166 { 167 return isaccessible(file, W_OK); 168 } 169 170 /* 171 * Returns non-zero if the argument file is accessable according to 172 * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid 173 * bits set. 174 */ 175 int 176 isaccessible (file, mode) 177 const char *file; 178 const int mode; 179 { 180 #ifdef SETXID_SUPPORT 181 struct stat sb; 182 int umask = 0; 183 int gmask = 0; 184 int omask = 0; 185 int uid; 186 187 if (stat(file, &sb) == -1) 188 return 0; 189 if (mode == F_OK) 190 return 1; 191 192 uid = geteuid(); 193 if (uid == 0) /* superuser */ 194 { 195 if (mode & X_OK) 196 return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH); 197 else 198 return 1; 199 } 200 201 if (mode & R_OK) 202 { 203 umask |= S_IRUSR; 204 gmask |= S_IRGRP; 205 omask |= S_IROTH; 206 } 207 if (mode & W_OK) 208 { 209 umask |= S_IWUSR; 210 gmask |= S_IWGRP; 211 omask |= S_IWOTH; 212 } 213 if (mode & X_OK) 214 { 215 umask |= S_IXUSR; 216 gmask |= S_IXGRP; 217 omask |= S_IXOTH; 218 } 219 220 if (sb.st_uid == uid) 221 return (sb.st_mode & umask) == umask; 222 else if (sb.st_gid == getegid()) 223 return (sb.st_mode & gmask) == gmask; 224 else 225 return (sb.st_mode & omask) == omask; 226 #else 227 return access(file, mode) == 0; 228 #endif 229 } 230 231 /* 232 * Open a file and die if it fails 233 */ 234 FILE * 235 open_file (name, mode) 236 const char *name; 237 const char *mode; 238 { 239 FILE *fp; 240 241 if ((fp = fopen (name, mode)) == NULL) 242 error (1, errno, "cannot open %s", name); 243 return (fp); 244 } 245 246 /* 247 * Make a directory and die if it fails 248 */ 249 void 250 make_directory (name) 251 const char *name; 252 { 253 struct stat sb; 254 255 if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode))) 256 error (0, 0, "%s already exists but is not a directory", name); 257 if (!noexec && mkdir (name, 0777) < 0) 258 error (1, errno, "cannot make directory %s", name); 259 } 260 261 /* 262 * Make a path to the argument directory, printing a message if something 263 * goes wrong. 264 */ 265 void 266 make_directories (name) 267 const char *name; 268 { 269 char *cp; 270 271 if (noexec) 272 return; 273 274 if (mkdir (name, 0777) == 0 || errno == EEXIST) 275 return; 276 if (! existence_error (errno)) 277 { 278 error (0, errno, "cannot make path to %s", name); 279 return; 280 } 281 if ((cp = strrchr (name, '/')) == NULL) 282 return; 283 *cp = '\0'; 284 make_directories (name); 285 *cp++ = '/'; 286 if (*cp == '\0') 287 return; 288 (void) mkdir (name, 0777); 289 } 290 291 /* Create directory NAME if it does not already exist; fatal error for 292 other errors. Returns 0 if directory was created; 1 if it already 293 existed. */ 294 int 295 mkdir_if_needed (name) 296 char *name; 297 { 298 if (mkdir (name, 0777) < 0) 299 { 300 if (errno != EEXIST) 301 error (1, errno, "cannot make directory %s", name); 302 return 1; 303 } 304 return 0; 305 } 306 307 /* 308 * Change the mode of a file, either adding write permissions, or removing 309 * all write permissions. Either change honors the current umask setting. 310 * The EMX doc (0.9c, emxlib.doc) says that chmod sets/clears the readonly 311 * bit. But it always seemed to be a noop when I tried it. Therefore, 312 * I've copied over the "attrib" code from os2/filesubr.c. 313 */ 314 void 315 xchmod (fname, writable) 316 char *fname; 317 int writable; 318 { 319 char *attrib_cmd; 320 char *attrib_option; 321 char *whole_cmd; 322 char *p; 323 char *q; 324 325 if (!isfile (fname)) 326 { 327 error (0, 0, "cannot change mode of file %s; it does not exist", 328 fname); 329 return; 330 } 331 332 attrib_cmd = "attrib "; /* No, really? */ 333 334 if (writable) 335 attrib_option = "-r "; /* make writeable */ 336 else 337 attrib_option = "+r "; /* make read-only */ 338 339 whole_cmd = xmalloc (strlen (attrib_cmd) 340 + strlen (attrib_option) 341 + strlen (fname) 342 + 1); 343 344 strcpy (whole_cmd, attrib_cmd); 345 strcat (whole_cmd, attrib_option); 346 347 /* Copy fname to the end of whole_cmd, translating / to \. 348 Attrib doesn't take / but many parts of CVS rely 349 on being able to use it. */ 350 p = whole_cmd + strlen (whole_cmd); 351 q = fname; 352 while (*q) 353 { 354 if (*q == '/') 355 *p++ = '\\'; 356 else 357 *p++ = *q; 358 ++q; 359 } 360 *p = '\0'; 361 362 system (whole_cmd); 363 free (whole_cmd); 364 } 365 366 /* 367 * Rename a file and die if it fails 368 */ 369 void 370 rename_file (from, to) 371 const char *from; 372 const char *to; 373 { 374 if (trace) 375 #ifdef SERVER_SUPPORT 376 (void) fprintf (stderr, "%c-> rename(%s,%s)\n", 377 (server_active) ? 'S' : ' ', from, to); 378 #else 379 (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to); 380 #endif 381 if (noexec) 382 return; 383 384 unlink_file (to); 385 if (rename (from, to) != 0) 386 error (1, errno, "cannot rename file %s to %s", from, to); 387 } 388 389 /* 390 * unlink a file, if possible. 391 */ 392 int 393 unlink_file (f) 394 const char *f; 395 { 396 if (trace) 397 #ifdef SERVER_SUPPORT 398 (void) fprintf (stderr, "%c-> unlink(%s)\n", 399 (server_active) ? 'S' : ' ', f); 400 #else 401 (void) fprintf (stderr, "-> unlink(%s)\n", f); 402 #endif 403 if (noexec) 404 return (0); 405 406 if (isfile (f)) 407 xchmod ((char *)f, 1); 408 return (unlink (f)); 409 } 410 411 /* 412 * Unlink a file or dir, if possible. If it is a directory do a deep 413 * removal of all of the files in the directory. Return -1 on error 414 * (in which case errno is set). 415 */ 416 int 417 unlink_file_dir (f) 418 const char *f; 419 { 420 if (trace) 421 #ifdef SERVER_SUPPORT 422 (void) fprintf (stderr, "%c-> unlink_file_dir(%s)\n", 423 (server_active) ? 'S' : ' ', f); 424 #else 425 (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f); 426 #endif 427 if (noexec) 428 return (0); 429 430 /* For at least some unices, if root tries to unlink() a directory, 431 instead of doing something rational like returning EISDIR, 432 the system will gleefully go ahead and corrupt the filesystem. 433 So we first call isdir() to see if it is OK to call unlink(). This 434 doesn't quite work--if someone creates a directory between the 435 call to isdir() and the call to unlink(), we'll still corrupt 436 the filesystem. Where is the Unix Haters Handbook when you need 437 it? */ 438 if (isdir(f)) 439 return deep_remove_dir(f); 440 else 441 { 442 if (unlink (f) != 0) 443 return -1; 444 } 445 /* We were able to remove the file from the disk */ 446 return 0; 447 } 448 449 /* Remove a directory and everything it contains. Returns 0 for 450 * success, -1 for failure (in which case errno is set). 451 */ 452 453 static int 454 deep_remove_dir (path) 455 const char *path; 456 { 457 DIR *dirp; 458 struct dirent *dp; 459 char buf[PATH_MAX]; 460 461 if (rmdir (path) != 0) 462 { 463 if (errno == ENOTEMPTY 464 || errno == EEXIST 465 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug 466 (it defines ENOTEMPTY and EEXIST to 17 but actually 467 returns 87). */ 468 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87)) 469 { 470 if ((dirp = opendir (path)) == NULL) 471 /* If unable to open the directory return 472 * an error 473 */ 474 return -1; 475 476 while ((dp = readdir (dirp)) != NULL) 477 { 478 if (strcmp (dp->d_name, ".") == 0 || 479 strcmp (dp->d_name, "..") == 0) 480 continue; 481 482 sprintf (buf, "%s/%s", path, dp->d_name); 483 484 /* See comment in unlink_file_dir explanation of why we use 485 isdir instead of just calling unlink and checking the 486 status. */ 487 if (isdir(buf)) 488 { 489 if (deep_remove_dir(buf)) 490 { 491 closedir(dirp); 492 return -1; 493 } 494 } 495 else 496 { 497 if (unlink (buf) != 0) 498 { 499 closedir(dirp); 500 return -1; 501 } 502 } 503 } 504 closedir (dirp); 505 return rmdir (path); 506 } 507 else 508 return -1; 509 } 510 511 /* Was able to remove the directory return 0 */ 512 return 0; 513 } 514 515 /* Read NCHARS bytes from descriptor FD into BUF. 516 Return the number of characters successfully read. 517 The number returned is always NCHARS unless end-of-file or error. */ 518 static size_t 519 block_read (fd, buf, nchars) 520 int fd; 521 char *buf; 522 size_t nchars; 523 { 524 char *bp = buf; 525 size_t nread; 526 527 do 528 { 529 nread = read (fd, bp, nchars); 530 if (nread == (size_t)-1) 531 { 532 #ifdef EINTR 533 if (errno == EINTR) 534 continue; 535 #endif 536 return (size_t)-1; 537 } 538 539 if (nread == 0) 540 break; 541 542 bp += nread; 543 nchars -= nread; 544 } while (nchars != 0); 545 546 return bp - buf; 547 } 548 549 550 /* 551 * Compare "file1" to "file2". Return non-zero if they don't compare exactly. 552 */ 553 int 554 xcmp (file1, file2) 555 const char *file1; 556 const char *file2; 557 { 558 char *buf1, *buf2; 559 struct stat sb1, sb2; 560 int fd1, fd2; 561 int ret; 562 563 if ((fd1 = open (file1, O_RDONLY | O_BINARY)) < 0) 564 error (1, errno, "cannot open file %s for comparing", file1); 565 if ((fd2 = open (file2, O_RDONLY | O_BINARY)) < 0) 566 error (1, errno, "cannot open file %s for comparing", file2); 567 if (fstat (fd1, &sb1) < 0) 568 error (1, errno, "cannot fstat %s", file1); 569 if (fstat (fd2, &sb2) < 0) 570 error (1, errno, "cannot fstat %s", file2); 571 572 /* A generic file compare routine might compare st_dev & st_ino here 573 to see if the two files being compared are actually the same file. 574 But that won't happen in CVS, so we won't bother. */ 575 576 if (sb1.st_size != sb2.st_size) 577 ret = 1; 578 else if (sb1.st_size == 0) 579 ret = 0; 580 else 581 { 582 /* FIXME: compute the optimal buffer size by computing the least 583 common multiple of the files st_blocks field */ 584 size_t buf_size = 8 * 1024; 585 size_t read1; 586 size_t read2; 587 588 buf1 = xmalloc (buf_size); 589 buf2 = xmalloc (buf_size); 590 591 do 592 { 593 read1 = block_read (fd1, buf1, buf_size); 594 if (read1 == (size_t)-1) 595 error (1, errno, "cannot read file %s for comparing", file1); 596 597 read2 = block_read (fd2, buf2, buf_size); 598 if (read2 == (size_t)-1) 599 error (1, errno, "cannot read file %s for comparing", file2); 600 601 /* assert (read1 == read2); */ 602 603 ret = memcmp(buf1, buf2, read1); 604 } while (ret == 0 && read1 == buf_size); 605 606 free (buf1); 607 free (buf2); 608 } 609 610 (void) close (fd1); 611 (void) close (fd2); 612 return (ret); 613 } 614 615 616 /* Just in case this implementation does not define this. */ 617 #ifndef L_tmpnam 618 #define L_tmpnam 50 619 #endif 620 621 622 #ifdef LOSING_TMPNAM_FUNCTION 623 char * 624 cvs_temp_name () 625 { 626 char value[L_tmpnam + 1]; 627 628 /* FIXME: Should be using TMPDIR. */ 629 strcpy (value, "/tmp/cvsXXXXXX"); 630 mktemp (value); 631 return xstrdup (value); 632 } 633 #else 634 /* Generate a unique temporary filename. Returns a pointer to a newly 635 malloc'd string containing the name. Returns successfully or not at 636 all. */ 637 char * 638 cvs_temp_name () 639 { 640 char value[L_tmpnam + 1]; 641 char *retval; 642 643 /* FIXME: should be using TMPDIR, perhaps by using tempnam on systems 644 which have it. */ 645 retval = tmpnam (value); 646 if (retval == NULL) 647 error (1, errno, "cannot generate temporary filename"); 648 return xstrdup (retval); 649 } 650 #endif 651 652 653 /* Return non-zero iff FILENAME is absolute. 654 Trivial under Unix, but more complicated under other systems. 655 Under EMX let _fnisabs do all this work. */ 656 int 657 isabsolute (filename) 658 const char *filename; 659 { 660 return _fnisabs(filename); 661 } 662 663 664 /* Return a pointer into PATH's last component. */ 665 char * 666 last_component (path) 667 char *path; 668 { 669 char *last; 670 671 /* We can't be sure here if 'path' is already slashified. */ 672 _fnslashify (path); 673 674 last = strrchr (path, '/'); 675 676 if (last && (last != path)) 677 return last + 1; 678 else 679 return path; 680 } 681 682 /* Return the home directory. Returns a pointer to storage 683 managed by this function or its callees (currently getenv). 684 This function will return the same thing every time it is 685 called. */ 686 char * 687 get_homedir () 688 { 689 static char *home = NULL; 690 char *env = getenv ("HOME"); 691 struct passwd *pw; 692 693 if (home != NULL) 694 return home; 695 696 if (env) 697 home = env; 698 else if ((pw = (struct passwd *) getpwuid (getuid ())) 699 && pw->pw_dir) 700 home = xstrdup (pw->pw_dir); 701 else 702 return 0; 703 704 return home; 705 } 706 707 /* See cvs.h for description. On unix this does nothing, because the 708 shell expands the wildcards. Under EMX, use _fnexplode to get the 709 expanded filenames */ 710 void 711 expand_wild (argc, argv, pargc, pargv) 712 int argc; 713 char **argv; 714 int *pargc; 715 char ***pargv; 716 { 717 int i; 718 *pargc = argc; 719 *pargv = (char **) xmalloc (argc * sizeof (char *)); 720 for (i = 0; i < argc; ++i) 721 (*pargv)[i] = xstrdup (argv[i]); 722 } 723 724 unsigned char 725 OS2_filename_classes[] = 726 { 727 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 728 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, 729 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 730 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, 731 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27, 732 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f, 733 0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37, 734 0x38,0x39,0x3a,0x3b, 0x3c,0x3d,0x3e,0x3f, 735 0x40,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, 736 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, 737 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, 738 0x78,0x79,0x7a,0x5b, 0x2f,0x5d,0x5e,0x5f, 739 0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, 740 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, 741 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, 742 0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x7f, 743 0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87, 744 0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f, 745 0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97, 746 0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f, 747 0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7, 748 0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf, 749 0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,0xb7, 750 0xb8,0xb9,0xba,0xbb, 0xbc,0xbd,0xbe,0xbf, 751 0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7, 752 0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf, 753 0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,0xd7, 754 0xd8,0xd9,0xda,0xdb, 0xdc,0xdd,0xde,0xdf, 755 0xe0,0xe1,0xe2,0xe3, 0xe4,0xe5,0xe6,0xe7, 756 0xe8,0xe9,0xea,0xeb, 0xec,0xed,0xee,0xef, 757 0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7, 758 0xf8,0xf9,0xfa,0xfb, 0xfc,0xfd,0xfe,0xff, 759 }; 760 761 762 /* Like strcmp, but with the appropriate tweaks for file names. 763 Under OS/2, filenames are case-insensitive but case-preserving, and 764 both \ and / are path element separators. */ 765 int 766 fncmp (const char *n1, const char *n2) 767 { 768 char fn1[MAXNAMLEN], fn2[MAXNAMLEN]; 769 770 strcpy (fn1, n1); _fnslashify(fn1); 771 strcpy (fn2, n2); _fnslashify(fn2); 772 773 return _fncmp ((unsigned char *) fn1, (unsigned char *) fn2); 774 } 775 776 777 /* Fold characters in FILENAME to their canonical forms. 778 If FOLD_FN_CHAR is not #defined, the system provides a default 779 definition for this. */ 780 void 781 fnfold (char *filename) 782 { 783 while (*filename) 784 { 785 *filename = FOLD_FN_CHAR (*filename); 786 filename++; 787 } 788 } 789