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