filesubr.c revision 1.1.1.7
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 <io.h> 21#include <windows.h> 22 23#include "cvs.h" 24 25static int deep_remove_dir PROTO((const char *path)); 26 27/* 28 * Copies "from" to "to". 29 */ 30void 31copy_file (from, to) 32 const char *from; 33 const char *to; 34{ 35 struct stat sb; 36 struct utimbuf t; 37 int fdin, fdout; 38 39 if (trace) 40#ifdef SERVER_SUPPORT 41 (void) fprintf (stderr, "%c-> copy(%s,%s)\n", 42 (server_active) ? 'S' : ' ', from, to); 43#else 44 (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to); 45#endif 46 if (noexec) 47 return; 48 49 if ((fdin = open (from, O_RDONLY | O_BINARY)) < 0) 50 error (1, errno, "cannot open %s for copying", from); 51 if (fstat (fdin, &sb) < 0) 52 error (1, errno, "cannot fstat %s", from); 53 if ((fdout = open (to, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 54 (int) sb.st_mode & 07777)) < 0) 55 error (1, errno, "cannot create %s for copying", to); 56 if (sb.st_size > 0) 57 { 58 char buf[BUFSIZ]; 59 int n; 60 61 for (;;) 62 { 63 n = read (fdin, buf, sizeof(buf)); 64 if (n == -1) 65 { 66#ifdef EINTR 67 if (errno == EINTR) 68 continue; 69#endif 70 error (1, errno, "cannot read file %s for copying", from); 71 } 72 else if (n == 0) 73 break; 74 75 if (write(fdout, buf, n) != n) { 76 error (1, errno, "cannot write file %s for copying", to); 77 } 78 } 79 80#ifdef HAVE_FSYNC 81 if (fsync (fdout)) 82 error (1, errno, "cannot fsync file %s after copying", to); 83#endif 84 } 85 86 if (close (fdin) < 0) 87 error (0, errno, "cannot close %s", from); 88 if (close (fdout) < 0) 89 error (1, errno, "cannot close %s", to); 90 91 /* now, set the times for the copied file to match those of the original */ 92 memset ((char *) &t, 0, sizeof (t)); 93 t.actime = sb.st_atime; 94 t.modtime = sb.st_mtime; 95 (void) utime (to, &t); 96} 97 98/* 99 * link a file, if possible. Warning: the Windows NT version of this 100 * function just copies the file, so only use this function in ways 101 * that can deal with either a link or a copy. 102 */ 103int 104link_file (from, to) 105 const char *from; 106 const char *to; 107{ 108 copy_file (from, to); 109 return 0; 110} 111 112/* FIXME-krp: these functions would benefit from caching the char * & 113 stat buf. */ 114 115/* 116 * Returns non-zero if the argument file is a directory, or is a symbolic 117 * link which points to a directory. 118 */ 119int 120isdir (file) 121 const char *file; 122{ 123 struct stat sb; 124 125 if (stat (file, &sb) < 0) 126 return (0); 127 return (S_ISDIR (sb.st_mode)); 128} 129 130/* 131 * Returns non-zero if the argument file is a symbolic link. 132 */ 133int 134islink (file) 135 const char *file; 136{ 137#ifdef S_ISLNK 138 struct stat sb; 139 140 if (lstat (file, &sb) < 0) 141 return (0); 142 return (S_ISLNK (sb.st_mode)); 143#else 144 return (0); 145#endif 146} 147 148/* 149 * Returns non-zero if the argument file exists. 150 */ 151int 152isfile (file) 153 const char *file; 154{ 155 return isaccessible(file, F_OK); 156} 157 158/* 159 * Returns non-zero if the argument file is readable. 160 */ 161int 162isreadable (file) 163 const char *file; 164{ 165 return isaccessible(file, R_OK); 166} 167 168/* 169 * Returns non-zero if the argument file is writable. 170 */ 171int 172iswritable (file) 173 const char *file; 174{ 175 return isaccessible(file, W_OK); 176} 177 178/* 179 * Returns non-zero if the argument file is accessable according to 180 * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid 181 * bits set. 182 */ 183int 184isaccessible (file, mode) 185 const char *file; 186 const int mode; 187{ 188#ifdef SETXID_SUPPORT 189 struct stat sb; 190 int umask = 0; 191 int gmask = 0; 192 int omask = 0; 193 int uid; 194 195 if (stat(file, &sb) == -1) 196 return 0; 197 if (mode == F_OK) 198 return 1; 199 200 uid = geteuid(); 201 if (uid == 0) /* superuser */ 202 { 203 if (mode & X_OK) 204 return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH); 205 else 206 return 1; 207 } 208 209 if (mode & R_OK) 210 { 211 umask |= S_IRUSR; 212 gmask |= S_IRGRP; 213 omask |= S_IROTH; 214 } 215 if (mode & W_OK) 216 { 217 umask |= S_IWUSR; 218 gmask |= S_IWGRP; 219 omask |= S_IWOTH; 220 } 221 if (mode & X_OK) 222 { 223 umask |= S_IXUSR; 224 gmask |= S_IXGRP; 225 omask |= S_IXOTH; 226 } 227 228 if (sb.st_uid == uid) 229 return (sb.st_mode & umask) == umask; 230 else if (sb.st_gid == getegid()) 231 return (sb.st_mode & gmask) == gmask; 232 else 233 return (sb.st_mode & omask) == omask; 234#else 235 return access(file, mode) == 0; 236#endif 237} 238 239/* 240 * Open a file and die if it fails 241 */ 242FILE * 243open_file (name, mode) 244 const char *name; 245 const char *mode; 246{ 247 FILE *fp; 248 249 if ((fp = fopen (name, mode)) == NULL) 250 error (1, errno, "cannot open %s", name); 251 return (fp); 252} 253 254/* 255 * Make a directory and die if it fails 256 */ 257void 258make_directory (name) 259 const char *name; 260{ 261 struct stat sb; 262 263 if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode))) 264 error (0, 0, "%s already exists but is not a directory", name); 265 if (!noexec && mkdir (name) < 0) 266 error (1, errno, "cannot make directory %s", name); 267} 268 269/* 270 * Make a path to the argument directory, printing a message if something 271 * goes wrong. 272 */ 273void 274make_directories (name) 275 const char *name; 276{ 277 char *cp; 278 279 if (noexec) 280 return; 281 282 if (mkdir (name) == 0 || errno == EEXIST) 283 return; 284 if (errno != ENOENT) 285 { 286 error (0, errno, "cannot make path to %s", name); 287 return; 288 } 289 if ((cp = strrchr (name, '/')) == NULL) 290 return; 291 *cp = '\0'; 292 make_directories (name); 293 *cp++ = '/'; 294 if (*cp == '\0') 295 return; 296 (void) mkdir (name); 297} 298 299/* Create directory NAME if it does not already exist; fatal error for 300 other errors. Returns 0 if directory was created; 1 if it already 301 existed. */ 302int 303mkdir_if_needed (name) 304 char *name; 305{ 306 if (mkdir (name) < 0) 307 { 308 if (errno != EEXIST 309#ifdef EACCESS 310 /* This was copied over from the OS/2 code; I would guess it 311 isn't needed here but that has not been verified. */ 312 && errno != EACCESS 313#endif 314#ifdef EACCES 315 /* This is said to be needed by NT on Alpha or PowerPC 316 (not sure what version) --August, 1996. */ 317 && errno != EACCES 318#endif 319 ) 320 error (1, errno, "cannot make directory %s", name); 321 return 1; 322 } 323 return 0; 324} 325 326/* 327 * Change the mode of a file, either adding write permissions, or removing 328 * all write permissions. Adding write permissions honors the current umask 329 * setting. 330 */ 331void 332xchmod (fname, writable) 333 char *fname; 334 int writable; 335{ 336 struct stat sb; 337 mode_t mode, oumask; 338 339 if (stat (fname, &sb) < 0) 340 { 341 if (!noexec) 342 error (0, errno, "cannot stat %s", fname); 343 return; 344 } 345 if (writable) 346 { 347 oumask = umask (0); 348 (void) umask (oumask); 349 mode = sb.st_mode | ~oumask & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0) | 350 ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0) | 351 ((sb.st_mode & S_IROTH) ? S_IWOTH : 0)); 352 } 353 else 354 { 355 mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH); 356 } 357 358 if (trace) 359#ifdef SERVER_SUPPORT 360 (void) fprintf (stderr, "%c-> chmod(%s,%o)\n", 361 (server_active) ? 'S' : ' ', fname, mode); 362#else 363 (void) fprintf (stderr, "-> chmod(%s,%o)\n", fname, mode); 364#endif 365 if (noexec) 366 return; 367 368 if (chmod (fname, mode) < 0) 369 error (0, errno, "cannot change mode of file %s", fname); 370} 371 372 373/* Read the value of a symbolic link. 374 Under Windows NT, this function always returns EINVAL. */ 375int 376readlink (char *path, char *buf, int buf_size) 377{ 378 errno = EINVAL; 379 return -1; 380} 381 382/* 383 * Rename a file and die if it fails 384 */ 385void 386rename_file (from, to) 387 const char *from; 388 const char *to; 389{ 390 if (trace) 391#ifdef SERVER_SUPPORT 392 (void) fprintf (stderr, "%c-> rename(%s,%s)\n", 393 (server_active) ? 'S' : ' ', from, to); 394#else 395 (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to); 396#endif 397 if (noexec) 398 return; 399 400 /* Win32 unlink is stupid --- it fails if the file is read-only */ 401 chmod(to, S_IWRITE); 402 unlink(to); 403 if (rename (from, to) < 0) 404 error (1, errno, "cannot rename file %s to %s", from, to); 405} 406 407/* Windows NT doesn't have hard links or symbolic links. 408 There was only one place in CVS which used this function, 409 so I rewrote it to work another way, so this function isn't 410 used any more. */ 411#if 0 412/* 413 * link a file, if possible. 414 */ 415int 416link_file (from, to) 417 const char *from; 418 const char *to; 419{ 420 if (trace) 421#ifdef SERVER_SUPPORT 422 (void) fprintf (stderr, "%c-> link(%s,%s)\n", 423 (server_active) ? 'S' : ' ', from, to); 424#else 425 (void) fprintf (stderr, "-> link(%s,%s)\n", from, to); 426#endif 427 if (noexec) 428 return (0); 429 430 return (link (from, to)); 431} 432#endif 433 434/* 435 * unlink a file, if possible. 436 */ 437int 438unlink_file (f) 439 const char *f; 440{ 441 if (trace) 442#ifdef SERVER_SUPPORT 443 (void) fprintf (stderr, "%c-> unlink(%s)\n", 444 (server_active) ? 'S' : ' ', f); 445#else 446 (void) fprintf (stderr, "-> unlink(%s)\n", f); 447#endif 448 if (noexec) 449 return (0); 450 451 /* Win32 unlink is stupid - it fails if the file is read-only */ 452 chmod (f, _S_IWRITE); 453 return (unlink (f)); 454} 455 456/* 457 * Unlink a file or dir, if possible. If it is a directory do a deep 458 * removal of all of the files in the directory. Return -1 on error 459 * (in which case errno is set). 460 */ 461int 462unlink_file_dir (f) 463 const char *f; 464{ 465 if (trace) 466#ifdef SERVER_SUPPORT 467 (void) fprintf (stderr, "%c-> unlink_file_dir(%s)\n", 468 (server_active) ? 'S' : ' ', f); 469#else 470 (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f); 471#endif 472 if (noexec) 473 return (0); 474 475 /* Win32 unlink is stupid - it fails if the file is read-only */ 476 chmod (f, _S_IWRITE); 477 if (unlink (f) != 0) 478 { 479 /* under Windows NT, unlink returns EACCES if the path 480 is a directory. Under Windows 95, ENOENT. */ 481 if (errno == EISDIR || errno == EACCES || errno == ENOENT) 482 return deep_remove_dir (f); 483 else 484 /* The file wasn't a directory and some other 485 * error occured 486 */ 487 return -1; 488 } 489 /* We were able to remove the file from the disk */ 490 return 0; 491} 492 493/* Remove a directory and everything it contains. Returns 0 for 494 * success, -1 for failure (in which case errno is set). 495 */ 496 497static int 498deep_remove_dir (path) 499 const char *path; 500{ 501 DIR *dirp; 502 struct dirent *dp; 503 char buf[PATH_MAX]; 504 505 /* ENOTEMPTY for NT (obvious) but EACCES for Win95 (not obvious) */ 506 if (rmdir (path) != 0 507 && (errno == ENOTEMPTY || errno == EACCES)) 508 { 509 if ((dirp = opendir (path)) == NULL) 510 /* If unable to open the directory return 511 * an error 512 */ 513 return -1; 514 515 while ((dp = readdir (dirp)) != NULL) 516 { 517 if (strcmp (dp->d_name, ".") == 0 || 518 strcmp (dp->d_name, "..") == 0) 519 continue; 520 521 sprintf (buf, "%s/%s", path, dp->d_name); 522 523 /* Win32 unlink is stupid - it fails if the file is read-only */ 524 chmod (buf, _S_IWRITE); 525 if (unlink (buf) != 0 ) 526 { 527 /* Under Windows NT, unlink returns EACCES if the path 528 is a directory. Under Windows 95, ENOENT. It 529 isn't really clear to me whether checking errno is 530 better or worse than using _stat to check for a directory. 531 We aren't really trying to prevent race conditions here 532 (e.g. what if something changes between readdir and 533 unlink?) */ 534 if (errno == EISDIR || errno == EACCES || errno == ENOENT) 535 { 536 if (deep_remove_dir (buf)) 537 { 538 closedir (dirp); 539 return -1; 540 } 541 } 542 else 543 { 544 /* buf isn't a directory, or there are 545 * some sort of permision problems 546 */ 547 closedir (dirp); 548 return -1; 549 } 550 } 551 } 552 closedir (dirp); 553 return rmdir (path); 554 } 555 /* Was able to remove the directory return 0 */ 556 return 0; 557} 558 559/* Read NCHARS bytes from descriptor FD into BUF. 560 Return the number of characters successfully read. 561 The number returned is always NCHARS unless end-of-file or error. */ 562static size_t 563block_read (fd, buf, nchars) 564 int fd; 565 char *buf; 566 size_t nchars; 567{ 568 char *bp = buf; 569 size_t nread; 570 571 do 572 { 573 nread = read (fd, bp, nchars); 574 if (nread == (size_t)-1) 575 { 576#ifdef EINTR 577 if (errno == EINTR) 578 continue; 579#endif 580 return (size_t)-1; 581 } 582 583 if (nread == 0) 584 break; 585 586 bp += nread; 587 nchars -= nread; 588 } while (nchars != 0); 589 590 return bp - buf; 591} 592 593 594/* 595 * Compare "file1" to "file2". Return non-zero if they don't compare exactly. 596 */ 597int 598xcmp (file1, file2) 599 const char *file1; 600 const char *file2; 601{ 602 char *buf1, *buf2; 603 struct stat sb1, sb2; 604 int fd1, fd2; 605 int ret; 606 607 if ((fd1 = open (file1, O_RDONLY | O_BINARY)) < 0) 608 error (1, errno, "cannot open file %s for comparing", file1); 609 if ((fd2 = open (file2, O_RDONLY | O_BINARY)) < 0) 610 error (1, errno, "cannot open file %s for comparing", file2); 611 if (fstat (fd1, &sb1) < 0) 612 error (1, errno, "cannot fstat %s", file1); 613 if (fstat (fd2, &sb2) < 0) 614 error (1, errno, "cannot fstat %s", file2); 615 616 /* A generic file compare routine might compare st_dev & st_ino here 617 to see if the two files being compared are actually the same file. 618 But that won't happen in CVS, so we won't bother. */ 619 620 if (sb1.st_size != sb2.st_size) 621 ret = 1; 622 else if (sb1.st_size == 0) 623 ret = 0; 624 else 625 { 626 /* FIXME: compute the optimal buffer size by computing the least 627 common multiple of the files st_blocks field */ 628 size_t buf_size = 8 * 1024; 629 size_t read1; 630 size_t read2; 631 632 buf1 = xmalloc (buf_size); 633 buf2 = xmalloc (buf_size); 634 635 do 636 { 637 read1 = block_read (fd1, buf1, buf_size); 638 if (read1 == (size_t)-1) 639 error (1, errno, "cannot read file %s for comparing", file1); 640 641 read2 = block_read (fd2, buf2, buf_size); 642 if (read2 == (size_t)-1) 643 error (1, errno, "cannot read file %s for comparing", file2); 644 645 /* assert (read1 == read2); */ 646 647 ret = memcmp(buf1, buf2, read1); 648 } while (ret == 0 && read1 == buf_size); 649 650 free (buf1); 651 free (buf2); 652 } 653 654 (void) close (fd1); 655 (void) close (fd2); 656 return (ret); 657} 658 659 660/* The equivalence class mapping for filenames. 661 Windows NT filenames are case-insensitive, but case-preserving. 662 Both / and \ are path element separators. 663 Thus, this table maps both upper and lower case to lower case, and 664 both / and \ to /. */ 665 666#if 0 667main () 668{ 669 int c; 670 671 for (c = 0; c < 256; c++) 672 { 673 int t; 674 675 if (c == '\\') 676 t = '/'; 677 else 678 t = tolower (c); 679 680 if ((c & 0x7) == 0x0) 681 printf (" "); 682 printf ("0x%02x,", t); 683 if ((c & 0x7) == 0x7) 684 putchar ('\n'); 685 else if ((c & 0x7) == 0x3) 686 putchar (' '); 687 } 688} 689#endif 690 691 692unsigned char 693WNT_filename_classes[] = 694{ 695 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 696 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, 697 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 698 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, 699 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27, 700 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f, 701 0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37, 702 0x38,0x39,0x3a,0x3b, 0x3c,0x3d,0x3e,0x3f, 703 0x40,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, 704 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, 705 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, 706 0x78,0x79,0x7a,0x5b, 0x2f,0x5d,0x5e,0x5f, 707 0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, 708 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, 709 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, 710 0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x7f, 711 0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87, 712 0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f, 713 0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97, 714 0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f, 715 0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7, 716 0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf, 717 0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,0xb7, 718 0xb8,0xb9,0xba,0xbb, 0xbc,0xbd,0xbe,0xbf, 719 0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7, 720 0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf, 721 0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,0xd7, 722 0xd8,0xd9,0xda,0xdb, 0xdc,0xdd,0xde,0xdf, 723 0xe0,0xe1,0xe2,0xe3, 0xe4,0xe5,0xe6,0xe7, 724 0xe8,0xe9,0xea,0xeb, 0xec,0xed,0xee,0xef, 725 0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7, 726 0xf8,0xf9,0xfa,0xfb, 0xfc,0xfd,0xfe,0xff, 727}; 728 729/* Like strcmp, but with the appropriate tweaks for file names. 730 Under Windows NT, filenames are case-insensitive but case-preserving, 731 and both \ and / are path element separators. */ 732int 733fncmp (const char *n1, const char *n2) 734{ 735 while (*n1 && *n2 736 && (WNT_filename_classes[(unsigned char) *n1] 737 == WNT_filename_classes[(unsigned char) *n2])) 738 n1++, n2++; 739 return (WNT_filename_classes[(unsigned char) *n1] 740 - WNT_filename_classes[(unsigned char) *n2]); 741} 742 743/* Fold characters in FILENAME to their canonical forms. 744 If FOLD_FN_CHAR is not #defined, the system provides a default 745 definition for this. */ 746void 747fnfold (char *filename) 748{ 749 while (*filename) 750 { 751 *filename = FOLD_FN_CHAR (*filename); 752 filename++; 753 } 754} 755 756 757/* Generate a unique temporary filename. Returns a pointer to a newly 758 malloc'd string containing the name. Returns successfully or not at 759 all. */ 760char * 761cvs_temp_name () 762{ 763 char *retval; 764 765 retval = _tempnam (NULL, NULL); 766 if (retval == NULL) 767 error (1, errno, "cannot generate temporary filename"); 768 return retval; 769} 770 771/* Return non-zero iff FILENAME is absolute. 772 Trivial under Unix, but more complicated under other systems. */ 773int 774isabsolute (filename) 775 const char *filename; 776{ 777 return (ISDIRSEP (filename[0]) 778 || (filename[0] != '\0' 779 && filename[1] == ':' 780 && ISDIRSEP (filename[2]))); 781} 782 783/* Return a pointer into PATH's last component. */ 784char * 785last_component (char *path) 786{ 787 char *scan; 788 char *last = 0; 789 790 for (scan = path; *scan; scan++) 791 if (ISDIRSEP (*scan)) 792 last = scan; 793 794 if (last) 795 return last + 1; 796 else 797 return path; 798} 799 800 801/* Read data from INFILE, and copy it to OUTFILE. 802 Open INFILE using INFLAGS, and OUTFILE using OUTFLAGS. 803 This is useful for converting between CRLF and LF line formats. */ 804void 805convert_file (char *infile, int inflags, 806 char *outfile, int outflags) 807{ 808 int infd, outfd; 809 char buf[8192]; 810 int len; 811 812 if ((infd = open (infile, inflags)) < 0) 813 error (1, errno, "couldn't read %s", infile); 814 if ((outfd = open (outfile, outflags, S_IWRITE)) < 0) 815 error (1, errno, "couldn't write %s", outfile); 816 817 while ((len = read (infd, buf, sizeof (buf))) > 0) 818 if (write (outfd, buf, len) < 0) 819 error (1, errno, "error writing %s", outfile); 820 if (len < 0) 821 error (1, errno, "error reading %s", infile); 822 823 if (close (outfd) < 0) 824 error (0, errno, "warning: couldn't close %s", outfile); 825 if (close (infd) < 0) 826 error (0, errno, "warning: couldn't close %s", infile); 827} 828 829 830/* NT has two evironment variables, HOMEPATH and HOMEDRIVE, which, 831 when combined as ${HOMEDRIVE}${HOMEPATH}, give the unix equivalent 832 of HOME. Some NT users are just too unixy, though, and set the 833 HOME variable themselves. Therefore, we check for HOME first, and 834 then try to combine the other two if that fails. 835 836 Looking for HOME strikes me as bogus, particularly if the only reason 837 is to cater to "unixy users". On the other hand, if the reasoning is 838 there should be a single variable, rather than requiring people to 839 set both HOMEDRIVE and HOMEPATH, then it starts to make a little more 840 sense. 841 842 Win95: The system doesn't set HOME, HOMEDRIVE, or HOMEPATH (at 843 least if you set it up as the "all users under one user ID" or 844 whatever the name of that option is). Based on thing overheard on 845 the net, it seems that users of the pserver client have gotten in 846 the habit of setting HOME (if you don't use pserver, you can 847 probably get away without having a reasonable return from 848 get_homedir. Of course you lose .cvsrc and .cvsignore, but many 849 users won't notice). So it would seem that we should be somewhat 850 careful if we try to change the current behavior. 851 852 NT 3.51 or NT 4.0: I haven't checked this myself, but I am told 853 that HOME gets set, but not to the user's home directory. It is 854 said to be set to c:\users\default by default. */ 855 856char * 857get_homedir () 858{ 859 static char *pathbuf; 860 char *hd, *hp; 861 862 if (pathbuf != NULL) 863 return pathbuf; 864 else if ((hd = getenv ("HOME"))) 865 return hd; 866 else if ((hd = getenv ("HOMEDRIVE")) && (hp = getenv ("HOMEPATH"))) 867 { 868 pathbuf = xmalloc (strlen (hd) + strlen (hp) + 5); 869 strcpy (pathbuf, hd); 870 strcat (pathbuf, hp); 871 872 return pathbuf; 873 } 874 else 875 return NULL; 876} 877 878/* See cvs.h for description. */ 879void 880expand_wild (argc, argv, pargc, pargv) 881 int argc; 882 char **argv; 883 int *pargc; 884 char ***pargv; 885{ 886 int i; 887 int new_argc; 888 char **new_argv; 889 /* Allocated size of new_argv. We arrange it so there is always room for 890 one more element. */ 891 int max_new_argc; 892 893 new_argc = 0; 894 /* Add one so this is never zero. */ 895 max_new_argc = argc + 1; 896 new_argv = (char **) xmalloc (max_new_argc * sizeof (char *)); 897 for (i = 0; i < argc; ++i) 898 { 899 HANDLE h; 900 WIN32_FIND_DATA fdata; 901 902 /* These variables help us extract the directory name from the 903 given pathname. */ 904 905 char *last_forw_slash, *last_back_slash, *end_of_dirname; 906 int dirname_length = 0; 907 908 /* FindFirstFile doesn't return pathnames, so we have to do 909 this ourselves. Luckily, it's no big deal, since globbing 910 characters under Win32s can only occur in the last segment 911 of the path. For example, 912 /a/path/q*.h valid 913 /w32/q*.dir/cant/do/this/q*.h invalid */ 914 915 /* Win32 can handle both forward and backward slashes as 916 filenames -- check for both. */ 917 918 last_forw_slash = strrchr (argv[i], '/'); 919 last_back_slash = strrchr (argv[i], '\\'); 920 921#define cvs_max(x,y) ((x >= y) ? (x) : (y)) 922 923 end_of_dirname = cvs_max (last_forw_slash, last_back_slash); 924 925 if (end_of_dirname == NULL) 926 dirname_length = 0; /* no directory name */ 927 else 928 dirname_length = end_of_dirname - argv[i] + 1; /* include slash */ 929 930 h = FindFirstFile (argv[i], &fdata); 931 if (h == INVALID_HANDLE_VALUE) 932 { 933 if (GetLastError () == ENOENT) 934 { 935 /* No match. The file specified didn't contain a wildcard (in which case 936 we clearly should return it unchanged), or it contained a wildcard which 937 didn't match (in which case it might be better for it to be an error, 938 but we don't try to do that). */ 939 new_argv [new_argc++] = xstrdup (argv[i]); 940 if (new_argc == max_new_argc) 941 { 942 max_new_argc *= 2; 943 new_argv = xrealloc (new_argv, max_new_argc * sizeof (char *)); 944 } 945 } 946 else 947 { 948 error (1, errno, "cannot find %s", argv[i]); 949 } 950 } 951 else 952 { 953 while (1) 954 { 955 new_argv[new_argc] = 956 (char *) xmalloc (strlen (fdata.cFileName) + 1 957 + dirname_length); 958 959 /* Copy the directory name, if there is one. */ 960 961 if (dirname_length) 962 { 963 strncpy (new_argv[new_argc], argv[i], dirname_length); 964 new_argv[new_argc][dirname_length] = '\0'; 965 } 966 else 967 new_argv[new_argc][0] = '\0'; 968 969 /* Copy the file name. */ 970 971 if (fncmp (argv[i] + dirname_length, fdata.cFileName) == 0) 972 /* We didn't expand a wildcard; we just matched a filename. 973 Use the file name as specified rather than the filename 974 which exists in the directory (they may differ in case). 975 This is needed to make cvs add on a directory consistently 976 use the name specified on the command line, but it is 977 probably a good idea in other contexts too. */ 978 strcpy (new_argv[new_argc], argv[i]); 979 else 980 strcat (new_argv[new_argc], fdata.cFileName); 981 982 new_argc++; 983 984 if (new_argc == max_new_argc) 985 { 986 max_new_argc *= 2; 987 new_argv = xrealloc (new_argv, max_new_argc * sizeof (char *)); 988 } 989 if (!FindNextFile (h, &fdata)) 990 { 991 if (GetLastError () == ERROR_NO_MORE_FILES) 992 break; 993 else 994 error (1, errno, "cannot find %s", argv[i]); 995 } 996 } 997 if (!FindClose (h)) 998 error (1, GetLastError (), "cannot close %s", argv[i]); 999 } 1000 } 1001 *pargc = new_argc; 1002 *pargv = new_argv; 1003} 1004