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 "lstat.h" 22 #include "save-cwd.h" 23 #include "xsize.h" 24 25 static int deep_remove_dir (const char *path); 26 27 /* 28 * Copies "from" to "to". 29 */ 30 void 31 copy_file (const char *from, const char *to) 32 { 33 struct stat sb; 34 struct utimbuf t; 35 int fdin, fdout; 36 ssize_t rsize; 37 38 TRACE (TRACE_FUNCTION, "copy(%s,%s)", from, to); 39 40 if (noexec) 41 return; 42 43 /* If the file to be copied is a link or a device, then just create 44 the new link or device appropriately. */ 45 if ((rsize = islink (from)) > 0) 46 { 47 char *source = Xreadlink (from, rsize); 48 if (symlink (source, to) == -1) 49 error (1, errno, "cannot symlink %s to %s", source, to); 50 free (source); 51 return; 52 } 53 54 if (isdevice (from)) 55 { 56 #if defined(HAVE_MKNOD) && defined(HAVE_STRUCT_STAT_ST_RDEV) 57 if (stat (from, &sb) < 0) 58 error (1, errno, "cannot stat %s", from); 59 mknod (to, sb.st_mode, sb.st_rdev); 60 #else 61 error (1, 0, "cannot copy device files on this system (%s)", from); 62 #endif 63 } 64 else 65 { 66 /* Not a link or a device... probably a regular file. */ 67 if ((fdin = open (from, O_RDONLY)) < 0) 68 error (1, errno, "cannot open %s for copying", from); 69 if (fstat (fdin, &sb) < 0) 70 error (1, errno, "cannot fstat %s", from); 71 if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0) 72 error (1, errno, "cannot create %s for copying", to); 73 if (sb.st_size > 0) 74 { 75 char buf[BUFSIZ]; 76 int n; 77 78 for (;;) 79 { 80 n = read (fdin, buf, sizeof(buf)); 81 if (n == -1) 82 { 83 #ifdef EINTR 84 if (errno == EINTR) 85 continue; 86 #endif 87 error (1, errno, "cannot read file %s for copying", from); 88 } 89 else if (n == 0) 90 break; 91 92 if (write(fdout, buf, n) != n) { 93 error (1, errno, "cannot write file %s for copying", to); 94 } 95 } 96 } 97 98 if (close (fdin) < 0) 99 error (0, errno, "cannot close %s", from); 100 if (close (fdout) < 0) 101 error (1, errno, "cannot close %s", to); 102 } 103 104 /* preserve last access & modification times */ 105 memset ((char *) &t, 0, sizeof (t)); 106 t.actime = sb.st_atime; 107 t.modtime = sb.st_mtime; 108 (void) utime (to, &t); 109 } 110 111 112 113 /* FIXME-krp: these functions would benefit from caching the char * & 114 stat buf. */ 115 116 /* 117 * Returns true if the argument file is a directory, or is a symbolic 118 * link which points to a directory. 119 */ 120 bool 121 isdir (const char *file) 122 { 123 struct stat sb; 124 125 if (stat (file, &sb) < 0) 126 return false; 127 return S_ISDIR (sb.st_mode); 128 } 129 130 131 132 /* 133 * Returns 0 if the argument file is not a symbolic link. 134 * Returns size of the link if it is a symbolic link. 135 */ 136 ssize_t 137 islink (const char *file) 138 { 139 ssize_t retsize = 0; 140 #ifdef S_ISLNK 141 struct stat sb; 142 143 if ((lstat (file, &sb) >= 0) && S_ISLNK (sb.st_mode)) 144 retsize = sb.st_size; 145 #endif 146 return retsize; 147 } 148 149 150 151 /* 152 * Returns true if the argument file is a block or 153 * character special device. 154 */ 155 bool 156 isdevice (const char *file) 157 { 158 struct stat sb; 159 160 if (lstat (file, &sb) < 0) 161 return false; 162 #ifdef S_ISBLK 163 if (S_ISBLK (sb.st_mode)) 164 return true; 165 #endif 166 #ifdef S_ISCHR 167 if (S_ISCHR (sb.st_mode)) 168 return true; 169 #endif 170 return false; 171 } 172 173 174 175 /* 176 * Returns true if the argument file exists. 177 */ 178 bool 179 isfile (const char *file) 180 { 181 return isaccessible (file, F_OK); 182 } 183 184 #ifdef SETXID_SUPPORT 185 int 186 ingroup(gid_t gid) 187 { 188 gid_t *gidp; 189 int i, ngroups; 190 191 if (gid == getegid()) 192 return 1; 193 194 ngroups = getgroups(0, NULL); 195 if (ngroups == -1) 196 return 0; 197 198 if ((gidp = malloc(sizeof(gid_t) * ngroups)) == NULL) 199 return 0; 200 201 if (getgroups(ngroups, gidp) == -1) { 202 free(gidp); 203 return 0; 204 } 205 206 for (i = 0; i < ngroups; i++) 207 if (gid == gidp[i]) 208 break; 209 210 free(gidp); 211 return i != ngroups; 212 } 213 #endif 214 215 /* 216 * Returns non-zero if the argument file is readable. 217 */ 218 bool 219 isreadable (const char *file) 220 { 221 return isaccessible (file, R_OK); 222 } 223 224 225 226 /* 227 * Returns non-zero if the argument file is writable. 228 */ 229 bool 230 iswritable (const char *file) 231 { 232 return isaccessible (file, W_OK); 233 } 234 235 236 237 /* 238 * Returns true if the argument file is accessable according to 239 * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid 240 * bits set. 241 */ 242 bool 243 isaccessible (const char *file, const int mode) 244 { 245 #ifdef SETXID_SUPPORT 246 struct stat sb; 247 int umask = 0; 248 int gmask = 0; 249 int omask = 0; 250 int uid, mask; 251 252 if (stat (file, &sb)== -1) 253 return false; 254 if (mode == F_OK) 255 return true; 256 257 uid = geteuid(); 258 if (uid == 0) /* superuser */ 259 { 260 if (!(mode & X_OK) || (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) 261 return true; 262 263 errno = EACCES; 264 return false; 265 } 266 267 if (mode & R_OK) 268 { 269 umask |= S_IRUSR; 270 gmask |= S_IRGRP; 271 omask |= S_IROTH; 272 } 273 if (mode & W_OK) 274 { 275 umask |= S_IWUSR; 276 gmask |= S_IWGRP; 277 omask |= S_IWOTH; 278 } 279 if (mode & X_OK) 280 { 281 umask |= S_IXUSR; 282 gmask |= S_IXGRP; 283 omask |= S_IXOTH; 284 } 285 286 mask = sb.st_uid == uid ? umask : ingroup(sb.st_gid) ? gmask : omask; 287 if ((sb.st_mode & mask) == mask) 288 return true; 289 errno = EACCES; 290 return false; 291 #else /* !SETXID_SUPPORT */ 292 return access (file, mode) == 0; 293 #endif /* SETXID_SUPPORT */ 294 } 295 296 297 298 /* 299 * Make a directory and die if it fails 300 */ 301 void 302 make_directory (const char *name) 303 { 304 struct stat sb; 305 306 if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode))) 307 error (0, 0, "%s already exists but is not a directory", name); 308 if (!noexec && mkdir (name, 0777) < 0) 309 error (1, errno, "cannot make directory %s", name); 310 } 311 312 /* 313 * Make a path to the argument directory, printing a message if something 314 * goes wrong. 315 */ 316 void 317 make_directories (const char *name) 318 { 319 char *cp; 320 321 if (noexec) 322 return; 323 324 if (mkdir (name, 0777) == 0 || errno == EEXIST) 325 return; 326 if (! existence_error (errno)) 327 { 328 error (0, errno, "cannot make path to %s", name); 329 return; 330 } 331 if ((cp = strrchr (name, '/')) == NULL) 332 return; 333 *cp = '\0'; 334 make_directories (name); 335 *cp++ = '/'; 336 if (*cp == '\0') 337 return; 338 (void) mkdir (name, 0777); 339 } 340 341 /* Create directory NAME if it does not already exist; fatal error for 342 other errors. Returns 0 if directory was created; 1 if it already 343 existed. */ 344 int 345 mkdir_if_needed (const char *name) 346 { 347 if (mkdir (name, 0777) < 0) 348 { 349 int save_errno = errno; 350 if (save_errno != EEXIST && !isdir (name)) 351 error (1, save_errno, "cannot make directory %s", name); 352 return 1; 353 } 354 return 0; 355 } 356 357 /* 358 * Change the mode of a file, either adding write permissions, or removing 359 * all write permissions. Either change honors the current umask setting. 360 * 361 * Don't do anything if PreservePermissions is set to `yes'. This may 362 * have unexpected consequences for some uses of xchmod. 363 */ 364 void 365 xchmod (const char *fname, int writable) 366 { 367 struct stat sb; 368 mode_t mode, oumask; 369 370 #ifdef PRESERVE_PERMISSIONS_SUPPORT 371 if (config->preserve_perms) 372 return; 373 #endif /* PRESERVE_PERMISSIONS_SUPPORT */ 374 375 if (stat (fname, &sb) < 0) 376 { 377 if (!noexec) 378 error (0, errno, "cannot stat %s", fname); 379 return; 380 } 381 oumask = umask (0); 382 (void) umask (oumask); 383 if (writable) 384 { 385 mode = sb.st_mode | (~oumask 386 & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0) 387 | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0) 388 | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0))); 389 } 390 else 391 { 392 mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask; 393 } 394 395 TRACE (TRACE_FUNCTION, "chmod(%s,%o)", fname, (unsigned int) mode); 396 397 if (noexec) 398 return; 399 400 if (chmod (fname, mode) < 0) 401 error (0, errno, "cannot change mode of file %s", fname); 402 } 403 404 /* 405 * Rename a file and die if it fails 406 */ 407 void 408 rename_file (const char *from, const char *to) 409 { 410 TRACE (TRACE_FUNCTION, "rename(%s,%s)", from, to); 411 412 if (noexec) 413 return; 414 415 if (rename (from, to) < 0) 416 error (1, errno, "cannot rename file %s to %s", from, to); 417 } 418 419 /* 420 * unlink a file, if possible. 421 */ 422 int 423 unlink_file (const char *f) 424 { 425 TRACE (TRACE_FUNCTION, "unlink_file(%s)", f); 426 427 if (noexec) 428 return (0); 429 430 return (CVS_UNLINK (f)); 431 } 432 433 434 435 /* 436 * Unlink a file or dir, if possible. If it is a directory do a deep 437 * removal of all of the files in the directory. Return -1 on error 438 * (in which case errno is set). 439 */ 440 int 441 unlink_file_dir (const char *f) 442 { 443 struct stat sb; 444 445 /* This is called by the server parent process in contexts where 446 it is not OK to send output (e.g. after we sent "ok" to the 447 client). */ 448 if (!server_active) 449 TRACE (TRACE_FUNCTION, "unlink_file_dir(%s)", f); 450 451 if (noexec) 452 return 0; 453 454 /* For at least some unices, if root tries to unlink() a directory, 455 instead of doing something rational like returning EISDIR, 456 the system will gleefully go ahead and corrupt the filesystem. 457 So we first call stat() to see if it is OK to call unlink(). This 458 doesn't quite work--if someone creates a directory between the 459 call to stat() and the call to unlink(), we'll still corrupt 460 the filesystem. Where is the Unix Haters Handbook when you need 461 it? */ 462 if (stat (f, &sb) < 0) 463 { 464 if (existence_error (errno)) 465 { 466 /* The file or directory doesn't exist anyhow. */ 467 return -1; 468 } 469 } 470 else if (S_ISDIR (sb.st_mode)) 471 return deep_remove_dir (f); 472 473 return CVS_UNLINK (f); 474 } 475 476 477 478 /* Remove a directory and everything it contains. Returns 0 for 479 * success, -1 for failure (in which case errno is set). 480 */ 481 482 static int 483 deep_remove_dir (const char *path) 484 { 485 DIR *dirp; 486 struct dirent *dp; 487 488 if (rmdir (path) != 0) 489 { 490 if (errno == ENOTEMPTY 491 || errno == EEXIST 492 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug 493 (it defines ENOTEMPTY and EEXIST to 17 but actually 494 returns 87). */ 495 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87)) 496 { 497 if ((dirp = CVS_OPENDIR (path)) == NULL) 498 /* If unable to open the directory return 499 * an error 500 */ 501 return -1; 502 503 errno = 0; 504 while ((dp = CVS_READDIR (dirp)) != NULL) 505 { 506 char *buf; 507 508 if (strcmp (dp->d_name, ".") == 0 || 509 strcmp (dp->d_name, "..") == 0) 510 continue; 511 512 buf = Xasprintf ("%s/%s", path, dp->d_name); 513 514 /* See comment in unlink_file_dir explanation of why we use 515 isdir instead of just calling unlink and checking the 516 status. */ 517 if (isdir (buf)) 518 { 519 if (deep_remove_dir (buf)) 520 { 521 CVS_CLOSEDIR (dirp); 522 free (buf); 523 return -1; 524 } 525 } 526 else 527 { 528 if (CVS_UNLINK (buf) != 0) 529 { 530 CVS_CLOSEDIR (dirp); 531 free (buf); 532 return -1; 533 } 534 } 535 free (buf); 536 537 errno = 0; 538 } 539 if (errno != 0) 540 { 541 int save_errno = errno; 542 CVS_CLOSEDIR (dirp); 543 errno = save_errno; 544 return -1; 545 } 546 CVS_CLOSEDIR (dirp); 547 return rmdir (path); 548 } 549 else 550 return -1; 551 } 552 553 /* Was able to remove the directory return 0 */ 554 return 0; 555 } 556 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. */ 562 static size_t 563 block_read (int fd, char *buf, size_t nchars) 564 { 565 char *bp = buf; 566 size_t nread; 567 568 do 569 { 570 nread = read (fd, bp, nchars); 571 if (nread == (size_t)-1) 572 { 573 #ifdef EINTR 574 if (errno == EINTR) 575 continue; 576 #endif 577 return (size_t)-1; 578 } 579 580 if (nread == 0) 581 break; 582 583 bp += nread; 584 nchars -= nread; 585 } while (nchars != 0); 586 587 return bp - buf; 588 } 589 590 591 /* 592 * Compare "file1" to "file2". Return non-zero if they don't compare exactly. 593 * If FILE1 and FILE2 are special files, compare their salient characteristics 594 * (i.e. major/minor device numbers, links, etc. 595 */ 596 int 597 xcmp (const char *file1, const char *file2) 598 { 599 char *buf1, *buf2; 600 struct stat sb1, sb2; 601 int fd1, fd2; 602 int ret; 603 604 if (lstat (file1, &sb1) < 0) 605 error (1, errno, "cannot lstat %s", file1); 606 if (lstat (file2, &sb2) < 0) 607 error (1, errno, "cannot lstat %s", file2); 608 609 /* If FILE1 and FILE2 are not the same file type, they are unequal. */ 610 if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT)) 611 return 1; 612 613 /* If FILE1 and FILE2 are symlinks, they are equal if they point to 614 the same thing. */ 615 #ifdef S_ISLNK 616 if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode)) 617 { 618 int result; 619 buf1 = Xreadlink (file1, sb1.st_size); 620 buf2 = Xreadlink (file2, sb2.st_size); 621 result = (strcmp (buf1, buf2) == 0); 622 free (buf1); 623 free (buf2); 624 return result; 625 } 626 #endif 627 628 /* If FILE1 and FILE2 are devices, they are equal if their device 629 numbers match. */ 630 if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode)) 631 { 632 #ifdef HAVE_STRUCT_STAT_ST_RDEV 633 if (sb1.st_rdev == sb2.st_rdev) 634 return 0; 635 else 636 return 1; 637 #else 638 error (1, 0, "cannot compare device files on this system (%s and %s)", 639 file1, file2); 640 #endif 641 } 642 643 if ((fd1 = open (file1, O_RDONLY)) < 0) 644 error (1, errno, "cannot open file %s for comparing", file1); 645 if ((fd2 = open (file2, O_RDONLY)) < 0) 646 error (1, errno, "cannot open file %s for comparing", file2); 647 648 /* A generic file compare routine might compare st_dev & st_ino here 649 to see if the two files being compared are actually the same file. 650 But that won't happen in CVS, so we won't bother. */ 651 652 if (sb1.st_size != sb2.st_size) 653 ret = 1; 654 else if (sb1.st_size == 0) 655 ret = 0; 656 else 657 { 658 /* FIXME: compute the optimal buffer size by computing the least 659 common multiple of the files st_blocks field */ 660 size_t buf_size = 8 * 1024; 661 size_t read1; 662 size_t read2; 663 664 buf1 = xmalloc (buf_size); 665 buf2 = xmalloc (buf_size); 666 667 do 668 { 669 read1 = block_read (fd1, buf1, buf_size); 670 if (read1 == (size_t)-1) 671 error (1, errno, "cannot read file %s for comparing", file1); 672 673 read2 = block_read (fd2, buf2, buf_size); 674 if (read2 == (size_t)-1) 675 error (1, errno, "cannot read file %s for comparing", file2); 676 677 /* assert (read1 == read2); */ 678 679 ret = memcmp(buf1, buf2, read1); 680 } while (ret == 0 && read1 == buf_size); 681 682 free (buf1); 683 free (buf2); 684 } 685 686 (void) close (fd1); 687 (void) close (fd2); 688 return (ret); 689 } 690 691 /* Generate a unique temporary filename. Returns a pointer to a newly 692 * malloc'd string containing the name. Returns successfully or not at 693 * all. 694 * 695 * THIS FUNCTION IS DEPRECATED!!! USE cvs_temp_file INSTEAD!!! 696 * 697 * and yes, I know about the way the rcs commands use temp files. I think 698 * they should be converted too but I don't have time to look into it right 699 * now. 700 */ 701 char * 702 cvs_temp_name (void) 703 { 704 char *fn; 705 FILE *fp; 706 707 fp = cvs_temp_file (&fn); 708 if (fp == NULL) 709 error (1, errno, "Failed to create temporary file"); 710 if (fclose (fp) == EOF) 711 error (0, errno, "Failed to close temporary file %s", fn); 712 return fn; 713 } 714 715 /* Generate a unique temporary filename and return an open file stream 716 * to the truncated file by that name 717 * 718 * INPUTS 719 * filename where to place the pointer to the newly allocated file 720 * name string 721 * 722 * OUTPUTS 723 * filename dereferenced, will point to the newly allocated file 724 * name string. This value is undefined if the function 725 * returns an error. 726 * 727 * RETURNS 728 * An open file pointer to a read/write mode empty temporary file with the 729 * unique file name or NULL on failure. 730 * 731 * ERRORS 732 * On error, errno will be set to some value either by CVS_FOPEN or 733 * whatever system function is called to generate the temporary file name. 734 * The value of filename is undefined on error. 735 */ 736 FILE * 737 cvs_temp_file (char **filename) 738 { 739 char *fn; 740 FILE *fp; 741 int fd; 742 743 /* FIXME - I'd like to be returning NULL here in noexec mode, but I think 744 * some of the rcs & diff functions which rely on a temp file run in 745 * noexec mode too. 746 */ 747 748 assert (filename != NULL); 749 750 fn = Xasprintf ("%s/%s", get_cvs_tmp_dir (), "cvsXXXXXX"); 751 fd = mkstemp (fn); 752 753 /* a NULL return will be interpreted by callers as an error and 754 * errno should still be set 755 */ 756 if (fd == -1) 757 fp = NULL; 758 else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL) 759 { 760 /* Attempt to close and unlink the file since mkstemp returned 761 * sucessfully and we believe it's been created and opened. 762 */ 763 int save_errno = errno; 764 if (close (fd)) 765 error (0, errno, "Failed to close temporary file %s", fn); 766 if (CVS_UNLINK (fn)) 767 error (0, errno, "Failed to unlink temporary file %s", fn); 768 errno = save_errno; 769 } 770 771 if (fp == NULL) 772 free (fn); 773 774 /* mkstemp is defined to open mode 0600 using glibc 2.0.7+. There used 775 * to be a complicated #ifdef checking the library versions here and then 776 * a chmod 0600 on the temp file for versions of glibc less than 2.1. This 777 * is rather a special case, leaves a race condition open regardless, and 778 * one could hope that sysadmins have read the relevant security 779 * announcements and upgraded by now to a version with a fix committed in 780 * January of 1999. 781 * 782 * If it is decided at some point that old, buggy versions of glibc should 783 * still be catered to, a umask of 0600 should be set before file creation 784 * instead then reset after file creation since this would avoid the race 785 * condition that the chmod left open to exploitation. 786 */ 787 788 *filename = fn; 789 return fp; 790 } 791 792 793 794 /* Return a pointer into PATH's last component. */ 795 const char * 796 last_component (const char *path) 797 { 798 const char *last = strrchr (path, '/'); 799 800 if (last && (last != path)) 801 return last + 1; 802 else 803 return path; 804 } 805 806 807 808 /* Return the home directory. Returns a pointer to storage 809 managed by this function or its callees (currently getenv). 810 This function will return the same thing every time it is 811 called. Returns NULL if there is no home directory. 812 813 Note that for a pserver server, this may return root's home 814 directory. What typically happens is that upon being started from 815 inetd, before switching users, the code in cvsrc.c calls 816 get_homedir which remembers root's home directory in the static 817 variable. Then the switch happens and get_homedir might return a 818 directory that we don't even have read or execute permissions for 819 (which is bad, when various parts of CVS try to read there). One 820 fix would be to make the value returned by get_homedir only good 821 until the next call (which would free the old value). Another fix 822 would be to just always malloc our answer, and let the caller free 823 it (that is best, because some day we may need to be reentrant). 824 825 The workaround is to put -f in inetd.conf which means that 826 get_homedir won't get called until after the switch in user ID. 827 828 The whole concept of a "home directory" on the server is pretty 829 iffy, although I suppose some people probably are relying on it for 830 .cvsrc and such, in the cases where it works. */ 831 char * 832 get_homedir (void) 833 { 834 static char *home = NULL; 835 char *env; 836 struct passwd *pw; 837 838 if (home != NULL) 839 return home; 840 841 if (!server_active && (env = getenv ("HOME")) != NULL) 842 home = env; 843 else if ((pw = (struct passwd *) getpwuid (getuid ())) 844 && pw->pw_dir) 845 home = xstrdup (pw->pw_dir); 846 else 847 return 0; 848 849 return home; 850 } 851 852 /* Compose a path to a file in the home directory. This is necessary because 853 * of different behavior on UNIX and VMS. See the notes in vms/filesubr.c. 854 * 855 * A more clean solution would be something more along the lines of a 856 * "join a directory to a filename" kind of thing which was not specific to 857 * the homedir. This should aid portability between UNIX, Mac, Windows, VMS, 858 * and possibly others. This is already handled by Perl - it might be 859 * interesting to see how much of the code was written in C since Perl is under 860 * the GPL and the Artistic license - we might be able to use it. 861 */ 862 char * 863 strcat_filename_onto_homedir (const char *dir, const char *file) 864 { 865 char *path = Xasprintf ("%s/%s", dir, file); 866 return path; 867 } 868 869 /* See cvs.h for description. On unix this does nothing, because the 870 shell expands the wildcards. */ 871 void 872 expand_wild (int argc, char **argv, int *pargc, char ***pargv) 873 { 874 int i; 875 if (size_overflow_p (xtimes (argc, sizeof (char *)))) { 876 *pargc = 0; 877 *pargv = NULL; 878 error (0, 0, "expand_wild: too many arguments"); 879 return; 880 } 881 *pargc = argc; 882 *pargv = xnmalloc (argc, sizeof (char *)); 883 for (i = 0; i < argc; ++i) 884 (*pargv)[i] = xstrdup (argv[i]); 885 } 886 887 888 889 static char *tmpdir_env; 890 891 /* Return path to temp directory. 892 */ 893 const char * 894 get_system_temp_dir (void) 895 { 896 if (!tmpdir_env) tmpdir_env = getenv (TMPDIR_ENV); 897 return tmpdir_env; 898 } 899 900 901 902 void 903 push_env_temp_dir (void) 904 { 905 const char *tmpdir = get_cvs_tmp_dir (); 906 if (tmpdir_env && strcmp (tmpdir_env, tmpdir)) 907 setenv (TMPDIR_ENV, tmpdir, 1); 908 } 909