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