Add CVS 1.12.12.
[dragonfly.git] / contrib / cvs-1.12.12 / 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 (TRACE_FUNCTION, "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  * Make a directory and die if it fails
269  */
270 void
271 make_directory (const char *name)
272 {
273     struct stat sb;
274
275     if( CVS_STAT( name, &sb ) == 0 && ( !S_ISDIR( sb.st_mode ) ) )
276             error (0, 0, "%s already exists but is not a directory", name);
277     if (!noexec && mkdir (name, 0777) < 0)
278         error (1, errno, "cannot make directory %s", name);
279 }
280
281 /*
282  * Make a path to the argument directory, printing a message if something
283  * goes wrong.
284  */
285 void
286 make_directories (const char *name)
287 {
288     char *cp;
289
290     if (noexec)
291         return;
292
293     if (mkdir (name, 0777) == 0 || errno == EEXIST)
294         return;
295     if (! existence_error (errno))
296     {
297         error (0, errno, "cannot make path to %s", name);
298         return;
299     }
300     if ((cp = strrchr (name, '/')) == NULL)
301         return;
302     *cp = '\0';
303     make_directories (name);
304     *cp++ = '/';
305     if (*cp == '\0')
306         return;
307     (void) mkdir (name, 0777);
308 }
309
310 /* Create directory NAME if it does not already exist; fatal error for
311    other errors.  Returns 0 if directory was created; 1 if it already
312    existed.  */
313 int
314 mkdir_if_needed (const char *name)
315 {
316     if (mkdir (name, 0777) < 0)
317     {
318         int save_errno = errno;
319         if (save_errno != EEXIST && !isdir (name))
320             error (1, save_errno, "cannot make directory %s", name);
321         return 1;
322     }
323     return 0;
324 }
325
326 /*
327  * Change the mode of a file, either adding write permissions, or removing
328  * all write permissions.  Either change honors the current umask setting.
329  *
330  * Don't do anything if PreservePermissions is set to `yes'.  This may
331  * have unexpected consequences for some uses of xchmod.
332  */
333 void
334 xchmod (const char *fname, int writable)
335 {
336     struct stat sb;
337     mode_t mode, oumask;
338
339 #ifdef PRESERVE_PERMISSIONS_SUPPORT
340     if (config->preserve_perms)
341         return;
342 #endif /* PRESERVE_PERMISSIONS_SUPPORT */
343
344     if( CVS_STAT( fname, &sb ) < 0 )
345     {
346         if (!noexec)
347             error (0, errno, "cannot stat %s", fname);
348         return;
349     }
350     oumask = umask (0);
351     (void) umask (oumask);
352     if (writable)
353     {
354         mode = sb.st_mode | (~oumask
355                              & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0)
356                                 | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0)
357                                 | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0)));
358     }
359     else
360     {
361         mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask;
362     }
363
364     TRACE (TRACE_FUNCTION, "chmod(%s,%o)", fname, (unsigned int) mode);
365
366     if (noexec)
367         return;
368
369     if (chmod (fname, mode) < 0)
370         error (0, errno, "cannot change mode of file %s", fname);
371 }
372
373 /*
374  * Rename a file and die if it fails
375  */
376 void
377 rename_file (const char *from, const char *to)
378 {
379     TRACE (TRACE_FUNCTION, "rename(%s,%s)", from, to);
380
381     if (noexec)
382         return;
383
384     if (rename (from, to) < 0)
385         error (1, errno, "cannot rename file %s to %s", from, to);
386 }
387
388 /*
389  * unlink a file, if possible.
390  */
391 int
392 unlink_file (const char *f)
393 {
394     TRACE (TRACE_FUNCTION, "unlink_file(%s)", f);
395
396     if (noexec)
397         return (0);
398
399     return (CVS_UNLINK (f));
400 }
401
402
403
404 /*
405  * Unlink a file or dir, if possible.  If it is a directory do a deep
406  * removal of all of the files in the directory.  Return -1 on error
407  * (in which case errno is set).
408  */
409 int
410 unlink_file_dir (const char *f)
411 {
412     struct stat sb;
413
414 #ifdef SERVER_SUPPORT
415         /* This is called by the server parent process in contexts where
416            it is not OK to send output (e.g. after we sent "ok" to the
417            client).  */
418         if (!server_active)
419 #endif
420         TRACE (TRACE_FUNCTION, "unlink_file_dir(%s)", f);
421
422     if (noexec)
423         return 0;
424
425     /* For at least some unices, if root tries to unlink() a directory,
426        instead of doing something rational like returning EISDIR,
427        the system will gleefully go ahead and corrupt the filesystem.
428        So we first call stat() to see if it is OK to call unlink().  This
429        doesn't quite work--if someone creates a directory between the
430        call to stat() and the call to unlink(), we'll still corrupt
431        the filesystem.  Where is the Unix Haters Handbook when you need
432        it?  */
433     if( CVS_STAT( f, &sb ) < 0 )
434     {
435         if (existence_error (errno))
436         {
437             /* The file or directory doesn't exist anyhow.  */
438             return -1;
439         }
440     }
441     else if (S_ISDIR (sb.st_mode))
442         return deep_remove_dir (f);
443
444     return CVS_UNLINK (f);
445 }
446
447
448
449 /* Remove a directory and everything it contains.  Returns 0 for
450  * success, -1 for failure (in which case errno is set).
451  */
452
453 static int
454 deep_remove_dir (const char *path)
455 {
456     DIR           *dirp;
457     struct dirent *dp;
458
459     if (rmdir (path) != 0)
460     {
461         if (errno == ENOTEMPTY
462             || errno == EEXIST
463             /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
464                (it defines ENOTEMPTY and EEXIST to 17 but actually
465                returns 87).  */
466             || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87))
467         {
468             if ((dirp = CVS_OPENDIR (path)) == NULL)
469                 /* If unable to open the directory return
470                  * an error
471                  */
472                 return -1;
473
474             errno = 0;
475             while ((dp = CVS_READDIR (dirp)) != NULL)
476             {
477                 char *buf;
478
479                 if (strcmp (dp->d_name, ".") == 0 ||
480                             strcmp (dp->d_name, "..") == 0)
481                     continue;
482
483                 buf = Xasprintf ("%s/%s", path, dp->d_name);
484
485                 /* See comment in unlink_file_dir explanation of why we use
486                    isdir instead of just calling unlink and checking the
487                    status.  */
488                 if (isdir (buf)) 
489                 {
490                     if (deep_remove_dir (buf))
491                     {
492                         CVS_CLOSEDIR (dirp);
493                         free (buf);
494                         return -1;
495                     }
496                 }
497                 else
498                 {
499                     if (CVS_UNLINK (buf) != 0)
500                     {
501                         CVS_CLOSEDIR (dirp);
502                         free (buf);
503                         return -1;
504                     }
505                 }
506                 free (buf);
507
508                 errno = 0;
509             }
510             if (errno != 0)
511             {
512                 int save_errno = errno;
513                 CVS_CLOSEDIR (dirp);
514                 errno = save_errno;
515                 return -1;
516             }
517             CVS_CLOSEDIR (dirp);
518             return rmdir (path);
519         }
520         else
521             return -1;
522     }
523
524     /* Was able to remove the directory return 0 */
525     return 0;
526 }
527
528
529
530 /* Read NCHARS bytes from descriptor FD into BUF.
531    Return the number of characters successfully read.
532    The number returned is always NCHARS unless end-of-file or error.  */
533 static size_t
534 block_read (int fd, char *buf, size_t nchars)
535 {
536     char *bp = buf;
537     size_t nread;
538
539     do 
540     {
541         nread = read (fd, bp, nchars);
542         if (nread == (size_t)-1)
543         {
544 #ifdef EINTR
545             if (errno == EINTR)
546                 continue;
547 #endif
548             return (size_t)-1;
549         }
550
551         if (nread == 0)
552             break; 
553
554         bp += nread;
555         nchars -= nread;
556     } while (nchars != 0);
557
558     return bp - buf;
559
560
561     
562 /*
563  * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
564  * If FILE1 and FILE2 are special files, compare their salient characteristics
565  * (i.e. major/minor device numbers, links, etc.
566  */
567 int
568 xcmp (const char *file1, const char *file2)
569 {
570     char *buf1, *buf2;
571     struct stat sb1, sb2;
572     int fd1, fd2;
573     int ret;
574
575     if (CVS_LSTAT (file1, &sb1) < 0)
576         error (1, errno, "cannot lstat %s", file1);
577     if (CVS_LSTAT (file2, &sb2) < 0)
578         error (1, errno, "cannot lstat %s", file2);
579
580     /* If FILE1 and FILE2 are not the same file type, they are unequal. */
581     if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT))
582         return 1;
583
584     /* If FILE1 and FILE2 are symlinks, they are equal if they point to
585        the same thing. */
586 #ifdef S_ISLNK
587     if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
588     {
589         int result;
590         buf1 = Xreadlink (file1, sb1.st_size);
591         buf2 = Xreadlink (file2, sb2.st_size);
592         result = (strcmp (buf1, buf2) == 0);
593         free (buf1);
594         free (buf2);
595         return result;
596     }
597 #endif
598
599     /* If FILE1 and FILE2 are devices, they are equal if their device
600        numbers match. */
601     if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
602     {
603 #ifdef HAVE_STRUCT_STAT_ST_RDEV
604         if (sb1.st_rdev == sb2.st_rdev)
605             return 0;
606         else
607             return 1;
608 #else
609         error (1, 0, "cannot compare device files on this system (%s and %s)",
610                file1, file2);
611 #endif
612     }
613
614     if ((fd1 = open (file1, O_RDONLY)) < 0)
615         error (1, errno, "cannot open file %s for comparing", file1);
616     if ((fd2 = open (file2, O_RDONLY)) < 0)
617         error (1, errno, "cannot open file %s for comparing", file2);
618
619     /* A generic file compare routine might compare st_dev & st_ino here 
620        to see if the two files being compared are actually the same file.
621        But that won't happen in CVS, so we won't bother. */
622
623     if (sb1.st_size != sb2.st_size)
624         ret = 1;
625     else if (sb1.st_size == 0)
626         ret = 0;
627     else
628     {
629         /* FIXME: compute the optimal buffer size by computing the least
630            common multiple of the files st_blocks field */
631         size_t buf_size = 8 * 1024;
632         size_t read1;
633         size_t read2;
634
635         buf1 = xmalloc (buf_size);
636         buf2 = xmalloc (buf_size);
637
638         do 
639         {
640             read1 = block_read (fd1, buf1, buf_size);
641             if (read1 == (size_t)-1)
642                 error (1, errno, "cannot read file %s for comparing", file1);
643
644             read2 = block_read (fd2, buf2, buf_size);
645             if (read2 == (size_t)-1)
646                 error (1, errno, "cannot read file %s for comparing", file2);
647
648             /* assert (read1 == read2); */
649
650             ret = memcmp(buf1, buf2, read1);
651         } while (ret == 0 && read1 == buf_size);
652
653         free (buf1);
654         free (buf2);
655     }
656         
657     (void) close (fd1);
658     (void) close (fd2);
659     return (ret);
660 }
661 \f
662 /* Generate a unique temporary filename.  Returns a pointer to a newly
663  * malloc'd string containing the name.  Returns successfully or not at
664  * all.
665  *
666  *     THIS FUNCTION IS DEPRECATED!!!  USE cvs_temp_file INSTEAD!!!
667  *
668  * and yes, I know about the way the rcs commands use temp files.  I think
669  * they should be converted too but I don't have time to look into it right
670  * now.
671  */
672 char *
673 cvs_temp_name (void)
674 {
675     char *fn;
676     FILE *fp;
677
678     fp = cvs_temp_file (&fn);
679     if (fp == NULL)
680         error (1, errno, "Failed to create temporary file");
681     if (fclose (fp) == EOF)
682         error (0, errno, "Failed to close temporary file %s", fn);
683     return fn;
684 }
685
686 /* Generate a unique temporary filename and return an open file stream
687  * to the truncated file by that name
688  *
689  *  INPUTS
690  *      filename        where to place the pointer to the newly allocated file
691  *                      name string
692  *
693  *  OUTPUTS
694  *      filename        dereferenced, will point to the newly allocated file
695  *                      name string.  This value is undefined if the function
696  *                      returns an error.
697  *
698  *  RETURNS
699  *      An open file pointer to a read/write mode empty temporary file with the
700  *      unique file name or NULL on failure.
701  *
702  *  ERRORS
703  *      On error, errno will be set to some value either by CVS_FOPEN or
704  *      whatever system function is called to generate the temporary file name.
705  *      The value of filename is undefined on error.
706  */
707 FILE *
708 cvs_temp_file (char **filename)
709 {
710     char *fn;
711     FILE *fp;
712     int fd;
713
714     /* FIXME - I'd like to be returning NULL here in noexec mode, but I think
715      * some of the rcs & diff functions which rely on a temp file run in
716      * noexec mode too.
717      */
718
719     assert (filename != NULL);
720
721     fn = Xasprintf ("%s/%s", Tmpdir, "cvsXXXXXX");
722     fd = mkstemp (fn);
723
724     /* a NULL return will be interpreted by callers as an error and
725      * errno should still be set
726      */
727     if (fd == -1)
728         fp = NULL;
729     else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL)
730     {
731         /* Attempt to close and unlink the file since mkstemp returned
732          * sucessfully and we believe it's been created and opened.
733          */
734         int save_errno = errno;
735         if (close (fd))
736             error (0, errno, "Failed to close temporary file %s", fn);
737         if (CVS_UNLINK (fn))
738             error (0, errno, "Failed to unlink temporary file %s", fn);
739         errno = save_errno;
740     }
741
742     if (fp == NULL)
743         free (fn);
744
745     /* mkstemp is defined to open mode 0600 using glibc 2.0.7+.  There used
746      * to be a complicated #ifdef checking the library versions here and then
747      * a chmod 0600 on the temp file for versions of glibc less than 2.1.  This
748      * is rather a special case, leaves a race condition open regardless, and
749      * one could hope that sysadmins have read the relevant security
750      * announcements and upgraded by now to a version with a fix committed in
751      * January of 1999.
752      *
753      * If it is decided at some point that old, buggy versions of glibc should
754      * still be catered to, a umask of 0600 should be set before file creation
755      * instead then reset after file creation since this would avoid the race
756      * condition that the chmod left open to exploitation.
757      */
758
759     *filename = fn;
760     return fp;
761 }
762
763
764
765 /* char *
766  * xresolvepath (const char *path)
767  *
768  * Like xreadlink(), but resolve all links in a path.
769  *
770  * INPUTS
771  *  path        The original path.
772  *
773  * RETURNS
774  *  The path with any symbolic links expanded.
775  *
776  * ERRORS
777  *  This function exits with a fatal error if it fails to read the link for
778  *  any reason.
779  */
780 char *
781 xresolvepath (const char *path)
782 {
783     char *hardpath;
784     struct saved_cwd owd;
785
786     assert (isdir (path));
787
788     /* FIXME - If HAVE_READLINK is defined, we should probably walk the path
789      * bit by bit calling xreadlink().
790      */
791
792     if (save_cwd (&owd))
793         error (1, 0, "failed to save current working directory");
794     if (CVS_CHDIR (path ) < 0)
795         error (1, errno, "cannot chdir to %s", path);
796     if ((hardpath = xgetcwd ()) == NULL)
797         error (1, errno, "cannot getwd in %s", path);
798     if (restore_cwd (&owd) < 0)
799         error (1, 0, "failed to restore working directory");
800     return hardpath;
801 }
802
803
804
805 /* Return a pointer into PATH's last component.  */
806 const char *
807 last_component (const char *path)
808 {
809     const char *last = strrchr (path, '/');
810     
811     if (last && (last != path))
812         return last + 1;
813     else
814         return path;
815 }
816
817
818
819 /* Return the home directory.  Returns a pointer to storage
820    managed by this function or its callees (currently getenv).
821    This function will return the same thing every time it is
822    called.  Returns NULL if there is no home directory.
823
824    Note that for a pserver server, this may return root's home
825    directory.  What typically happens is that upon being started from
826    inetd, before switching users, the code in cvsrc.c calls
827    get_homedir which remembers root's home directory in the static
828    variable.  Then the switch happens and get_homedir might return a
829    directory that we don't even have read or execute permissions for
830    (which is bad, when various parts of CVS try to read there).  One
831    fix would be to make the value returned by get_homedir only good
832    until the next call (which would free the old value).  Another fix
833    would be to just always malloc our answer, and let the caller free
834    it (that is best, because some day we may need to be reentrant).
835
836    The workaround is to put -f in inetd.conf which means that
837    get_homedir won't get called until after the switch in user ID.
838
839    The whole concept of a "home directory" on the server is pretty
840    iffy, although I suppose some people probably are relying on it for
841    .cvsrc and such, in the cases where it works.  */
842 char *
843 get_homedir (void)
844 {
845     static char *home = NULL;
846     char *env;
847     struct passwd *pw;
848
849     if (home != NULL)
850         return home;
851
852     if (
853 #ifdef SERVER_SUPPORT
854         !server_active &&
855 #endif
856         (env = getenv ("HOME")) != NULL)
857         home = env;
858     else if ((pw = (struct passwd *) getpwuid (getuid ()))
859              && pw->pw_dir)
860         home = xstrdup (pw->pw_dir);
861     else
862         return 0;
863
864     return home;
865 }
866
867 /* Compose a path to a file in the home directory.  This is necessary because
868  * of different behavior on UNIX and VMS.  See the notes in vms/filesubr.c.
869  *
870  * A more clean solution would be something more along the lines of a
871  * "join a directory to a filename" kind of thing which was not specific to
872  * the homedir.  This should aid portability between UNIX, Mac, Windows, VMS,
873  * and possibly others.  This is already handled by Perl - it might be
874  * interesting to see how much of the code was written in C since Perl is under
875  * the GPL and the Artistic license - we might be able to use it.
876  */
877 char *
878 strcat_filename_onto_homedir (const char *dir, const char *file)
879 {
880     char *path = Xasprintf ("%s/%s", dir, file);
881     return path;
882 }
883
884 /* See cvs.h for description.  On unix this does nothing, because the
885    shell expands the wildcards.  */
886 void
887 expand_wild (int argc, char **argv, int *pargc, char ***pargv)
888 {
889     int i;
890     if (size_overflow_p (xtimes (argc, sizeof (char *)))) {
891         *pargc = 0;
892         *pargv = NULL;
893         error (0, 0, "expand_wild: too many arguments");
894         return;
895     }
896     *pargc = argc;
897     *pargv = xnmalloc (argc, sizeof (char *));
898     for (i = 0; i < argc; ++i)
899         (*pargv)[i] = xstrdup (argv[i]);
900 }