xref: /openbsd-src/gnu/usr.bin/cvs/src/filesubr.c (revision 5e617892100bd75f195dd997a7ce0514322cf7e8)
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