xref: /openbsd/gnu/usr.bin/cvs/src/filesubr.c (revision 404b540a)
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 <assert.h>
21 #include "cvs.h"
22 
23 static int deep_remove_dir PROTO((const char *path));
24 
25 /*
26  * Copies "from" to "to".
27  */
28 void
29 copy_file (from, to)
30     const char *from;
31     const char *to;
32 {
33     struct stat sb;
34     struct utimbuf t;
35     int fdin, fdout;
36 
37     if (trace)
38 	(void) fprintf (stderr, "%s-> copy(%s,%s)\n",
39 			CLIENT_SERVER_STR, from, to);
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 (islink (from))
46     {
47 	char *source = xreadlink (from);
48 	symlink (source, to);
49 	free (source);
50 	return;
51     }
52 
53     if (isdevice (from))
54     {
55 #if defined(HAVE_MKNOD) && defined(HAVE_ST_RDEV)
56 	if (stat (from, &sb) < 0)
57 	    error (1, errno, "cannot stat %s", from);
58 	mknod (to, sb.st_mode, sb.st_rdev);
59 #else
60 	error (1, 0, "cannot copy device files on this system (%s)", from);
61 #endif
62     }
63     else
64     {
65 	/* Not a link or a device... probably a regular file. */
66 	if ((fdin = open (from, O_RDONLY)) < 0)
67 	    error (1, errno, "cannot open %s for copying", from);
68 	if (fstat (fdin, &sb) < 0)
69 	    error (1, errno, "cannot fstat %s", from);
70 	if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0)
71 	    error (1, errno, "cannot create %s for copying", to);
72 	if (sb.st_size > 0)
73 	{
74 	    char buf[BUFSIZ];
75 	    int n;
76 
77 	    for (;;)
78 	    {
79 		n = read (fdin, buf, sizeof(buf));
80 		if (n == -1)
81 		{
82 #ifdef EINTR
83 		    if (errno == EINTR)
84 			continue;
85 #endif
86 		    error (1, errno, "cannot read file %s for copying", from);
87 		}
88 		else if (n == 0)
89 		    break;
90 
91 		if (write(fdout, buf, n) != n) {
92 		    error (1, errno, "cannot write file %s for copying", to);
93 		}
94 	    }
95 
96 #ifdef HAVE_FSYNC
97 	    if (fsync (fdout))
98 		error (1, errno, "cannot fsync file %s after copying", to);
99 #endif
100 	}
101 
102 	if (close (fdin) < 0)
103 	    error (0, errno, "cannot close %s", from);
104 	if (close (fdout) < 0)
105 	    error (1, errno, "cannot close %s", to);
106     }
107 
108     /* now, set the times for the copied file to match those of the original */
109     memset ((char *) &t, 0, sizeof (t));
110     t.actime = sb.st_atime;
111     t.modtime = sb.st_mtime;
112     (void) utime (to, &t);
113 }
114 
115 /* FIXME-krp: these functions would benefit from caching the char * &
116    stat buf.  */
117 
118 /*
119  * Returns non-zero if the argument file is a directory, or is a symbolic
120  * link which points to a directory.
121  */
122 int
123 isdir (file)
124     const char *file;
125 {
126     struct stat sb;
127 
128     if (stat (file, &sb) < 0)
129 	return (0);
130     return (S_ISDIR (sb.st_mode));
131 }
132 
133 /*
134  * Returns non-zero if the argument file is a symbolic link.
135  */
136 int
137 islink (file)
138     const char *file;
139 {
140 #ifdef S_ISLNK
141     struct stat sb;
142 
143     if (CVS_LSTAT (file, &sb) < 0)
144 	return (0);
145     return (S_ISLNK (sb.st_mode));
146 #else
147     return (0);
148 #endif
149 }
150 
151 /*
152  * Returns non-zero if the argument file is a block or
153  * character special device.
154  */
155 int
156 isdevice (file)
157     const char *file;
158 {
159     struct stat sb;
160 
161     if (CVS_LSTAT (file, &sb) < 0)
162 	return (0);
163 #ifdef S_ISBLK
164     if (S_ISBLK (sb.st_mode))
165 	return 1;
166 #endif
167 #ifdef S_ISCHR
168     if (S_ISCHR (sb.st_mode))
169 	return 1;
170 #endif
171     return 0;
172 }
173 
174 /*
175  * Returns non-zero if the argument file exists.
176  */
177 int
178 isfile (file)
179     const char *file;
180 {
181     return isaccessible(file, F_OK);
182 }
183 
184 /*
185  * Returns non-zero if the argument file is readable.
186  */
187 int
188 isreadable (file)
189     const char *file;
190 {
191     return isaccessible(file, R_OK);
192 }
193 
194 /*
195  * Returns non-zero if the argument file is writable.
196  */
197 int
198 iswritable (file)
199     const char *file;
200 {
201     return isaccessible(file, W_OK);
202 }
203 
204 /*
205  * Returns non-zero if the argument file is accessable according to
206  * mode.  If compiled with SETXID_SUPPORT also works if cvs has setxid
207  * bits set.
208  */
209 int
210 isaccessible (file, mode)
211     const char *file;
212     const int mode;
213 {
214 #ifdef SETXID_SUPPORT
215     struct stat sb;
216     int umask = 0;
217     int gmask = 0;
218     int omask = 0;
219     int uid;
220 
221     if (stat(file, &sb) == -1)
222 	return 0;
223     if (mode == F_OK)
224 	return 1;
225 
226     uid = geteuid();
227     if (uid == 0)		/* superuser */
228     {
229 	if (mode & X_OK)
230 	    return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH);
231 	else
232 	    return 1;
233     }
234 
235     if (mode & R_OK)
236     {
237 	umask |= S_IRUSR;
238 	gmask |= S_IRGRP;
239 	omask |= S_IROTH;
240     }
241     if (mode & W_OK)
242     {
243 	umask |= S_IWUSR;
244 	gmask |= S_IWGRP;
245 	omask |= S_IWOTH;
246     }
247     if (mode & X_OK)
248     {
249 	umask |= S_IXUSR;
250 	gmask |= S_IXGRP;
251 	omask |= S_IXOTH;
252     }
253 
254     if (sb.st_uid == uid)
255 	return (sb.st_mode & umask) == umask;
256     else if (sb.st_gid == getegid())
257 	return (sb.st_mode & gmask) == gmask;
258     else
259 	return (sb.st_mode & omask) == omask;
260 #else
261     return access(file, mode) == 0;
262 #endif
263 }
264 
265 /*
266  * Open a file and die if it fails
267  */
268 FILE *
269 open_file (name, mode)
270     const char *name;
271     const char *mode;
272 {
273     FILE *fp;
274 
275     if ((fp = fopen (name, mode)) == NULL)
276 	error (1, errno, "cannot open %s", name);
277     return (fp);
278 }
279 
280 /*
281  * Make a directory and die if it fails
282  */
283 void
284 make_directory (name)
285     const char *name;
286 {
287     struct stat sb;
288 
289     if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode)))
290 	    error (0, 0, "%s already exists but is not a directory", name);
291     if (!noexec && mkdir (name, 0777) < 0)
292 	error (1, errno, "cannot make directory %s", name);
293 }
294 
295 /*
296  * Make a path to the argument directory, printing a message if something
297  * goes wrong.
298  */
299 void
300 make_directories (name)
301     const char *name;
302 {
303     char *cp;
304 
305     if (noexec)
306 	return;
307 
308     if (mkdir (name, 0777) == 0 || errno == EEXIST)
309 	return;
310     if (! existence_error (errno))
311     {
312 	error (0, errno, "cannot make path to %s", name);
313 	return;
314     }
315     if ((cp = strrchr (name, '/')) == NULL)
316 	return;
317     *cp = '\0';
318     make_directories (name);
319     *cp++ = '/';
320     if (*cp == '\0')
321 	return;
322     (void) mkdir (name, 0777);
323 }
324 
325 /* Create directory NAME if it does not already exist; fatal error for
326    other errors.  Returns 0 if directory was created; 1 if it already
327    existed.  */
328 int
329 mkdir_if_needed (name)
330     char *name;
331 {
332     if (mkdir (name, 0777) < 0)
333     {
334 	if (!(errno == EEXIST
335 	      || (errno == EACCES && isdir (name))))
336 	    error (1, errno, "cannot make directory %s", name);
337 	return 1;
338     }
339     return 0;
340 }
341 
342 /*
343  * Change the mode of a file, either adding write permissions, or removing
344  * all write permissions.  Either change honors the current umask setting.
345  *
346  * Don't do anything if PreservePermissions is set to `yes'.  This may
347  * have unexpected consequences for some uses of xchmod.
348  */
349 void
350 xchmod (fname, writable)
351     char *fname;
352     int writable;
353 {
354     struct stat sb;
355     mode_t mode, oumask;
356 
357     if (preserve_perms)
358 	return;
359 
360     if (stat (fname, &sb) < 0)
361     {
362 	if (!noexec)
363 	    error (0, errno, "cannot stat %s", fname);
364 	return;
365     }
366     oumask = umask (0);
367     (void) umask (oumask);
368     if (writable)
369     {
370 	mode = sb.st_mode | (~oumask
371 			     & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0)
372 				| ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0)
373 				| ((sb.st_mode & S_IROTH) ? S_IWOTH : 0)));
374     }
375     else
376     {
377 	mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask;
378     }
379 
380     if (trace)
381 	(void) fprintf (stderr, "%s-> chmod(%s,%o)\n",
382 			CLIENT_SERVER_STR, fname,
383 			(unsigned int) mode);
384     if (noexec)
385 	return;
386 
387     if (chmod (fname, mode) < 0)
388 	error (0, errno, "cannot change mode of file %s", fname);
389 }
390 
391 /*
392  * Rename a file and die if it fails
393  */
394 void
395 rename_file (from, to)
396     const char *from;
397     const char *to;
398 {
399     if (trace)
400 	(void) fprintf (stderr, "%s-> rename(%s,%s)\n",
401 			CLIENT_SERVER_STR, from, to);
402     if (noexec)
403 	return;
404 
405     if (rename (from, to) < 0)
406 	error (1, errno, "cannot rename file %s to %s", from, to);
407 }
408 
409 /*
410  * unlink a file, if possible.
411  */
412 int
413 unlink_file (f)
414     const char *f;
415 {
416     if (trace)
417 	(void) fprintf (stderr, "%s-> unlink_file(%s)\n",
418 			CLIENT_SERVER_STR, f);
419     if (noexec)
420 	return (0);
421 
422     return (CVS_UNLINK (f));
423 }
424 
425 /*
426  * Unlink a file or dir, if possible.  If it is a directory do a deep
427  * removal of all of the files in the directory.  Return -1 on error
428  * (in which case errno is set).
429  */
430 int
431 unlink_file_dir (f)
432     const char *f;
433 {
434     struct stat sb;
435 
436     if (trace
437 #ifdef SERVER_SUPPORT
438 	/* This is called by the server parent process in contexts where
439 	   it is not OK to send output (e.g. after we sent "ok" to the
440 	   client).  */
441 	&& !server_active
442 #endif
443 	)
444 	(void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f);
445 
446     if (noexec)
447 	return (0);
448 
449     /* For at least some unices, if root tries to unlink() a directory,
450        instead of doing something rational like returning EISDIR,
451        the system will gleefully go ahead and corrupt the filesystem.
452        So we first call stat() to see if it is OK to call unlink().  This
453        doesn't quite work--if someone creates a directory between the
454        call to stat() and the call to unlink(), we'll still corrupt
455        the filesystem.  Where is the Unix Haters Handbook when you need
456        it?  */
457     if (stat (f, &sb) < 0)
458     {
459 	if (existence_error (errno))
460 	{
461 	    /* The file or directory doesn't exist anyhow.  */
462 	    return -1;
463 	}
464     }
465     else if (S_ISDIR (sb.st_mode))
466 	return deep_remove_dir (f);
467 
468     return CVS_UNLINK (f);
469 }
470 
471 /* Remove a directory and everything it contains.  Returns 0 for
472  * success, -1 for failure (in which case errno is set).
473  */
474 
475 static int
476 deep_remove_dir (path)
477     const char *path;
478 {
479     DIR		  *dirp;
480     struct dirent *dp;
481 
482     if (rmdir (path) != 0)
483     {
484 	if (errno == ENOTEMPTY
485 	    || errno == EEXIST
486 	    /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
487 	       (it defines ENOTEMPTY and EEXIST to 17 but actually
488 	       returns 87).  */
489 	    || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87))
490 	{
491 	    if ((dirp = CVS_OPENDIR (path)) == NULL)
492 		/* If unable to open the directory return
493 		 * an error
494 		 */
495 		return -1;
496 
497 	    errno = 0;
498 	    while ((dp = CVS_READDIR (dirp)) != NULL)
499 	    {
500 		char *buf;
501 
502 		if (strcmp (dp->d_name, ".") == 0 ||
503 			    strcmp (dp->d_name, "..") == 0)
504 		    continue;
505 
506 		buf = xmalloc (strlen (path) + strlen (dp->d_name) + 5);
507 		sprintf (buf, "%s/%s", path, dp->d_name);
508 
509 		/* See comment in unlink_file_dir explanation of why we use
510 		   isdir instead of just calling unlink and checking the
511 		   status.  */
512 		if (isdir(buf))
513 		{
514 		    if (deep_remove_dir(buf))
515 		    {
516 			CVS_CLOSEDIR(dirp);
517 			free (buf);
518 			return -1;
519 		    }
520 		}
521 		else
522 		{
523 		    if (CVS_UNLINK (buf) != 0)
524 		    {
525 			CVS_CLOSEDIR(dirp);
526 			free (buf);
527 			return -1;
528 		    }
529 		}
530 		free (buf);
531 
532 		errno = 0;
533 	    }
534 	    if (errno != 0)
535 	    {
536 		int save_errno = errno;
537 		CVS_CLOSEDIR (dirp);
538 		errno = save_errno;
539 		return -1;
540 	    }
541 	    CVS_CLOSEDIR (dirp);
542 	    return rmdir (path);
543 	}
544 	else
545 	    return -1;
546     }
547 
548     /* Was able to remove the directory return 0 */
549     return 0;
550 }
551 
552 /* Read NCHARS bytes from descriptor FD into BUF.
553    Return the number of characters successfully read.
554    The number returned is always NCHARS unless end-of-file or error.  */
555 static size_t
556 block_read (fd, buf, nchars)
557     int fd;
558     char *buf;
559     size_t nchars;
560 {
561     char *bp = buf;
562     size_t nread;
563 
564     do
565     {
566 	nread = read (fd, bp, nchars);
567 	if (nread == (size_t)-1)
568 	{
569 #ifdef EINTR
570 	    if (errno == EINTR)
571 		continue;
572 #endif
573 	    return (size_t)-1;
574 	}
575 
576 	if (nread == 0)
577 	    break;
578 
579 	bp += nread;
580 	nchars -= nread;
581     } while (nchars != 0);
582 
583     return bp - buf;
584 }
585 
586 
587 /*
588  * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
589  * If FILE1 and FILE2 are special files, compare their salient characteristics
590  * (i.e. major/minor device numbers, links, etc.
591  */
592 int
593 xcmp (file1, file2)
594     const char *file1;
595     const char *file2;
596 {
597     char *buf1, *buf2;
598     struct stat sb1, sb2;
599     int fd1, fd2;
600     int ret;
601 
602     if (CVS_LSTAT (file1, &sb1) < 0)
603 	error (1, errno, "cannot lstat %s", file1);
604     if (CVS_LSTAT (file2, &sb2) < 0)
605 	error (1, errno, "cannot lstat %s", file2);
606 
607     /* If FILE1 and FILE2 are not the same file type, they are unequal. */
608     if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT))
609 	return 1;
610 
611     /* If FILE1 and FILE2 are symlinks, they are equal if they point to
612        the same thing. */
613     if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
614     {
615 	int result;
616 	buf1 = xreadlink (file1);
617 	buf2 = xreadlink (file2);
618 	result = (strcmp (buf1, buf2) == 0);
619 	free (buf1);
620 	free (buf2);
621 	return result;
622     }
623 
624     /* If FILE1 and FILE2 are devices, they are equal if their device
625        numbers match. */
626     if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
627     {
628 #ifdef HAVE_ST_RDEV
629 	if (sb1.st_rdev == sb2.st_rdev)
630 	    return 0;
631 	else
632 	    return 1;
633 #else
634 	error (1, 0, "cannot compare device files on this system (%s and %s)",
635 	       file1, file2);
636 #endif
637     }
638 
639     if ((fd1 = open (file1, O_RDONLY)) < 0)
640 	error (1, errno, "cannot open file %s for comparing", file1);
641     if ((fd2 = open (file2, O_RDONLY)) < 0)
642 	error (1, errno, "cannot open file %s for comparing", file2);
643 
644     /* A generic file compare routine might compare st_dev & st_ino here
645        to see if the two files being compared are actually the same file.
646        But that won't happen in CVS, so we won't bother. */
647 
648     if (sb1.st_size != sb2.st_size)
649 	ret = 1;
650     else if (sb1.st_size == 0)
651 	ret = 0;
652     else
653     {
654 	/* FIXME: compute the optimal buffer size by computing the least
655 	   common multiple of the files st_blocks field */
656 	size_t buf_size = 8 * 1024;
657 	size_t read1;
658 	size_t read2;
659 
660 	buf1 = xmalloc (buf_size);
661 	buf2 = xmalloc (buf_size);
662 
663 	do
664 	{
665 	    read1 = block_read (fd1, buf1, buf_size);
666 	    if (read1 == (size_t)-1)
667 		error (1, errno, "cannot read file %s for comparing", file1);
668 
669 	    read2 = block_read (fd2, buf2, buf_size);
670 	    if (read2 == (size_t)-1)
671 		error (1, errno, "cannot read file %s for comparing", file2);
672 
673 	    /* assert (read1 == read2); */
674 
675 	    ret = memcmp(buf1, buf2, read1);
676 	} while (ret == 0 && read1 == buf_size);
677 
678 	free (buf1);
679 	free (buf2);
680     }
681 
682     (void) close (fd1);
683     (void) close (fd2);
684     return (ret);
685 }
686 
687 /* Generate a unique temporary filename.  Returns a pointer to a newly
688  * malloc'd string containing the name.  Returns successfully or not at
689  * all.
690  *
691  *     THIS FUNCTION IS DEPRECATED!!!  USE cvs_temp_file INSTEAD!!!
692  *
693  * and yes, I know about the way the rcs commands use temp files.  I think
694  * they should be converted too but I don't have time to look into it right
695  * now.
696  */
697 char *
698 cvs_temp_name ()
699 {
700     char *fn;
701     FILE *fp;
702 
703     fp = cvs_temp_file (&fn);
704     if (fp == NULL)
705 	error (1, errno, "Failed to create temporary file");
706     if (fclose (fp) == EOF)
707 	error (0, errno, "Failed to close temporary file %s", fn);
708     return fn;
709 }
710 
711 /* Generate a unique temporary filename and return an open file stream
712  * to the truncated file by that name
713  *
714  *  INPUTS
715  *	filename	where to place the pointer to the newly allocated file
716  *   			name string
717  *
718  *  OUTPUTS
719  *	filename	dereferenced, will point to the newly allocated file
720  *			name string.  This value is undefined if the function
721  *			returns an error.
722  *
723  *  RETURNS
724  *	An open file pointer to a read/write mode empty temporary file with the
725  *	unique file name or NULL on failure.
726  *
727  *  ERRORS
728  *	on error, errno will be set to some value either by CVS_FOPEN or
729  *	whatever system function is called to generate the temporary file name
730  */
731 /* There are at least four functions for generating temporary
732  * filenames.  We use mkstemp (BSD 4.3) if possible, else tempnam (SVID 3),
733  * else mktemp (BSD 4.3), and as last resort tmpnam (POSIX).  Reason is that
734  * mkstemp, tempnam, and mktemp both allow to specify the directory in which
735  * the temporary file will be created.
736  *
737  * And the _correct_ way to use the deprecated functions probably involves
738  * opening file descriptors using O_EXCL & O_CREAT and even doing the annoying
739  * NFS locking thing, but until I hear of more problems, I'm not going to
740  * bother.
741  */
742 FILE *cvs_temp_file (filename)
743     char **filename;
744 {
745     char *fn;
746     FILE *fp;
747 
748     /* FIXME - I'd like to be returning NULL here in noexec mode, but I think
749      * some of the rcs & diff functions which rely on a temp file run in
750      * noexec mode too.
751      */
752 
753     assert (filename != NULL);
754 
755 #ifdef HAVE_MKSTEMP
756 
757     {
758     int fd;
759 
760     fn = xmalloc (strlen (Tmpdir) + 11);
761     sprintf (fn, "%s/%s", Tmpdir, "cvsXXXXXX" );
762     fd = mkstemp (fn);
763 
764     /* a NULL return will be interpreted by callers as an error and
765      * errno should still be set
766      */
767     if (fd == -1) fp = NULL;
768     else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL)
769     {
770 	/* attempt to close and unlink the file since mkstemp returned successfully and
771 	 * we believe it's been created and opened
772 	 */
773  	int save_errno = errno;
774 	if (close (fd))
775 	    error (0, errno, "Failed to close temporary file %s", fn);
776 	if (CVS_UNLINK (fn))
777 	    error (0, errno, "Failed to unlink temporary file %s", fn);
778 	errno = save_errno;
779     }
780 
781     if (fp == NULL) free (fn);
782     /* mkstemp is defined to open mode 0600 using glibc 2.0.7+ */
783     /* FIXME - configure can probably tell us which version of glibc we are
784      * linking to and not chmod for 2.0.7+
785      */
786     else chmod (fn, 0600);
787 
788     }
789 
790 #elif HAVE_TEMPNAM
791 
792     /* tempnam has been deprecated due to under-specification */
793 
794     fn = tempnam (Tmpdir, "cvs");
795     if (fn == NULL) fp = NULL;
796     else if ((fp = CVS_FOPEN (fn, "w+")) == NULL) free (fn);
797     else chmod (fn, 0600);
798 
799     /* tempnam returns a pointer to a newly malloc'd string, so there's
800      * no need for a xstrdup
801      */
802 
803 #elif HAVE_MKTEMP
804 
805     /* mktemp has been deprecated due to the BSD 4.3 specification specifying
806      * that XXXXXX will be replaced by a PID and a letter, creating only 26
807      * possibilities, a security risk, and a race condition.
808      */
809 
810     {
811     char *ifn;
812 
813     ifn = xmalloc (strlen (Tmpdir) + 11);
814     sprintf (ifn, "%s/%s", Tmpdir, "cvsXXXXXX" );
815     fn = mktemp (ifn);
816 
817     if (fn == NULL) fp = NULL;
818     else fp = CVS_FOPEN (fn, "w+");
819 
820     if (fp == NULL) free (ifn);
821     else chmod (fn, 0600);
822 
823     }
824 
825 #else	/* use tmpnam if all else fails */
826 
827     /* tmpnam is deprecated */
828 
829     {
830     char ifn[L_tmpnam + 1];
831 
832     fn = tmpnam (ifn);
833 
834     if (fn == NULL) fp = NULL;
835     else if ((fp = CVS_FOPEN (ifn, "w+")) != NULL)
836     {
837 	fn = xstrdup (ifn);
838 	chmod (fn, 0600);
839     }
840 
841     }
842 
843 #endif
844 
845     *filename = fn;
846     return fp;
847 }
848 
849 /* Return non-zero iff FILENAME is absolute.
850    Trivial under Unix, but more complicated under other systems.  */
851 int
852 isabsolute (filename)
853     const char *filename;
854 {
855     return filename[0] == '/';
856 }
857 
858 /*
859  * Return a string (dynamically allocated) with the name of the file to which
860  * LINK is symlinked.
861  */
862 char *
863 xreadlink (link)
864     const char *link;
865 {
866     char *file = NULL;
867     char *tfile;
868     int buflen = 128;
869     int link_name_len;
870 
871     if (!islink (link))
872 	return NULL;
873 
874     /* Get the name of the file to which `from' is linked.
875        FIXME: what portability issues arise here?  Are readlink &
876        ENAMETOOLONG defined on all systems? -twp */
877     do
878     {
879 	file = xrealloc (file, buflen);
880 	link_name_len = readlink (link, file, buflen - 1);
881 	buflen *= 2;
882     }
883     while (link_name_len < 0 && errno == ENAMETOOLONG);
884 
885     if (link_name_len < 0)
886 	error (1, errno, "cannot readlink %s", link);
887 
888     file[link_name_len] = '\0';
889 
890     tfile = xstrdup (file);
891     free (file);
892 
893     return tfile;
894 }
895 
896 
897 /* Return a pointer into PATH's last component.  */
898 char *
899 last_component (path)
900     char *path;
901 {
902     char *last = strrchr (path, '/');
903 
904     if (last && (last != path))
905         return last + 1;
906     else
907         return path;
908 }
909 
910 /* Return the home directory.  Returns a pointer to storage
911    managed by this function or its callees (currently getenv).
912    This function will return the same thing every time it is
913    called.  Returns NULL if there is no home directory.
914 
915    Note that for a pserver server, this may return root's home
916    directory.  What typically happens is that upon being started from
917    inetd, before switching users, the code in cvsrc.c calls
918    get_homedir which remembers root's home directory in the static
919    variable.  Then the switch happens and get_homedir might return a
920    directory that we don't even have read or execute permissions for
921    (which is bad, when various parts of CVS try to read there).  One
922    fix would be to make the value returned by get_homedir only good
923    until the next call (which would free the old value).  Another fix
924    would be to just always malloc our answer, and let the caller free
925    it (that is best, because some day we may need to be reentrant).
926 
927    The workaround is to put -f in inetd.conf which means that
928    get_homedir won't get called until after the switch in user ID.
929 
930    The whole concept of a "home directory" on the server is pretty
931    iffy, although I suppose some people probably are relying on it for
932    .cvsrc and such, in the cases where it works.  */
933 char *
934 get_homedir ()
935 {
936     static char *home = NULL;
937     char *env;
938     struct passwd *pw;
939 
940     if (home != NULL)
941 	return home;
942 
943     if (
944 #ifdef SERVER_SUPPORT
945 	!server_active &&
946 #endif
947 	(env = getenv ("HOME")) != NULL)
948 	home = env;
949     else if ((pw = (struct passwd *) getpwuid (getuid ()))
950 	     && pw->pw_dir)
951 	home = xstrdup (pw->pw_dir);
952     else
953 	return 0;
954 
955     return home;
956 }
957 
958 /* See cvs.h for description.  On unix this does nothing, because the
959    shell expands the wildcards.  */
960 void
961 expand_wild (argc, argv, pargc, pargv)
962     int argc;
963     char **argv;
964     int *pargc;
965     char ***pargv;
966 {
967     int i;
968     if (size_overflow_p (xtimes (argc, sizeof (char *)))) {
969 	*pargc = 0;
970 	*pargv = NULL;
971 	error (0, 0, "expand_wild: too many arguments");
972 	return;
973     }
974     *pargc = argc;
975     *pargv = xmalloc (xtimes (argc, sizeof (char *)));
976     for (i = 0; i < argc; ++i)
977 	(*pargv)[i] = xstrdup (argv[i]);
978 }
979 
980 #ifdef SERVER_SUPPORT
981 /* Case-insensitive string compare.  I know that some systems
982    have such a routine, but I'm not sure I see any reasons for
983    dealing with the hair of figuring out whether they do (I haven't
984    looked into whether this is a performance bottleneck; I would guess
985    not).  */
986 int
987 cvs_casecmp (str1, str2)
988     char *str1;
989     char *str2;
990 {
991     char *p;
992     char *q;
993     int pqdiff;
994 
995     p = str1;
996     q = str2;
997     while ((pqdiff = tolower (*p) - tolower (*q)) == 0)
998     {
999 	if (*p == '\0')
1000 	    return 0;
1001 	++p;
1002 	++q;
1003     }
1004     return pqdiff;
1005 }
1006 
1007 /* Case-insensitive file open.  As you can see, this is an expensive
1008    call.  We don't regard it as our main strategy for dealing with
1009    case-insensitivity.  Returns errno code or 0 for success.  Puts the
1010    new file in *FP.  NAME and MODE are as for fopen.  If PATHP is not
1011    NULL, then put a malloc'd string containing the pathname as found
1012    into *PATHP.  *PATHP is only set if the return value is 0.
1013 
1014    Might be cleaner to separate the file finding (which just gives
1015    *PATHP) from the file opening (which the caller can do).  For one
1016    thing, might make it easier to know whether to put NAME or *PATHP
1017    into error messages.  */
1018 int
1019 fopen_case (name, mode, fp, pathp)
1020     char *name;
1021     char *mode;
1022     FILE **fp;
1023     char **pathp;
1024 {
1025     struct dirent *dp;
1026     DIR *dirp;
1027     char *dir;
1028     char *fname;
1029     char *found_name;
1030     int retval;
1031 
1032     /* Separate NAME into directory DIR and filename within the directory
1033        FNAME.  */
1034     dir = xstrdup (name);
1035     fname = strrchr (dir, '/');
1036     if (fname == NULL)
1037 	error (1, 0, "internal error: relative pathname in fopen_case");
1038     *fname++ = '\0';
1039 
1040     found_name = NULL;
1041     dirp = CVS_OPENDIR (dir);
1042     if (dirp == NULL)
1043     {
1044 	if (existence_error (errno))
1045 	{
1046 	    /* This can happen if we are looking in the Attic and the Attic
1047 	       directory does not exist.  Return the error to the caller;
1048 	       they know what to do with it.  */
1049 	    retval = errno;
1050 	    goto out;
1051 	}
1052 	else
1053 	{
1054 	    /* Give a fatal error; that way the error message can be
1055 	       more specific than if we returned the error to the caller.  */
1056 	    error (1, errno, "cannot read directory %s", dir);
1057 	}
1058     }
1059     errno = 0;
1060     while ((dp = CVS_READDIR (dirp)) != NULL)
1061     {
1062 	if (cvs_casecmp (dp->d_name, fname) == 0)
1063 	{
1064 	    if (found_name != NULL)
1065 		error (1, 0, "%s is ambiguous; could mean %s or %s",
1066 		       fname, dp->d_name, found_name);
1067 	    found_name = xstrdup (dp->d_name);
1068 	}
1069     }
1070     if (errno != 0)
1071 	error (1, errno, "cannot read directory %s", dir);
1072     CVS_CLOSEDIR (dirp);
1073 
1074     if (found_name == NULL)
1075     {
1076 	*fp = NULL;
1077 	retval = ENOENT;
1078     }
1079     else
1080     {
1081 	char *p;
1082 
1083 	/* Copy the found name back into DIR.  We are assuming that
1084 	   found_name is the same length as fname, which is true as
1085 	   long as the above code is just ignoring case and not other
1086 	   aspects of filename syntax.  */
1087 	p = dir + strlen (dir);
1088 	*p++ = '/';
1089 	strcpy (p, found_name);
1090 	*fp = fopen (dir, mode);
1091 	if (*fp == NULL)
1092 	    retval = errno;
1093 	else
1094 	    retval = 0;
1095     }
1096 
1097     if (pathp == NULL)
1098 	free (dir);
1099     else if (retval != 0)
1100 	free (dir);
1101     else
1102 	*pathp = dir;
1103     free (found_name);
1104  out:
1105     return retval;
1106 }
1107 #endif /* SERVER_SUPPORT */
1108