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