cvs(1): Avoid -Wstringop-overflow warning.
[dragonfly.git] / contrib / cvs-1.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 "lstat.h"
22 #include "save-cwd.h"
23 #include "xsize.h"
24
25 static int deep_remove_dir (const char *path);
26
27 /*
28  * Copies "from" to "to".
29  */
30 void
31 copy_file (const char *from, const char *to)
32 {
33     struct stat sb;
34     struct utimbuf t;
35     int fdin, fdout;
36     ssize_t rsize;
37
38     TRACE (TRACE_FUNCTION, "copy(%s,%s)", from, to);
39
40     if (noexec)
41         return;
42
43     /* If the file to be copied is a link or a device, then just create
44        the new link or device appropriately. */
45     if ((rsize = islink (from)) > 0)
46     {
47         char *source = Xreadlink (from, rsize);
48         symlink (source, to);
49         free (source);
50         return;
51     }
52
53     if (isdevice (from))
54     {
55 #if defined(HAVE_MKNOD) && defined(HAVE_STRUCT_STAT_ST_RDEV)
56         if (stat (from, &sb) < 0)
57             error (1, errno, "cannot stat %s", from);
58         mknod (to, sb.st_mode, sb.st_rdev);
59 #else
60         error (1, 0, "cannot copy device files on this system (%s)", from);
61 #endif
62     }
63     else
64     {
65         /* Not a link or a device... probably a regular file. */
66         if ((fdin = open (from, O_RDONLY)) < 0)
67             error (1, errno, "cannot open %s for copying", from);
68         if (fstat (fdin, &sb) < 0)
69             error (1, errno, "cannot fstat %s", from);
70         if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0)
71             error (1, errno, "cannot create %s for copying", to);
72         if (sb.st_size > 0)
73         {
74             char buf[BUFSIZ];
75             int n;
76             
77             for (;;) 
78             {
79                 n = read (fdin, buf, sizeof(buf));
80                 if (n == -1)
81                 {
82 #ifdef EINTR
83                     if (errno == EINTR)
84                         continue;
85 #endif
86                     error (1, errno, "cannot read file %s for copying", from);
87                 }
88                 else if (n == 0) 
89                     break;
90                 
91                 if (write(fdout, buf, n) != n) {
92                     error (1, errno, "cannot write file %s for copying", to);
93                 }
94             }
95         }
96
97         if (close (fdin) < 0) 
98             error (0, errno, "cannot close %s", from);
99         if (close (fdout) < 0)
100             error (1, errno, "cannot close %s", to);
101     }
102
103     /* preserve last access & modification times */
104     memset ((char *) &t, 0, sizeof (t));
105     t.actime = sb.st_atime;
106     t.modtime = sb.st_mtime;
107     (void) utime (to, &t);
108 }
109
110
111
112 /* FIXME-krp: these functions would benefit from caching the char * &
113    stat buf.  */
114
115 /*
116  * Returns true if the argument file is a directory, or is a symbolic
117  * link which points to a directory.
118  */
119 bool
120 isdir (const char *file)
121 {
122     struct stat sb;
123
124     if (stat (file, &sb) < 0)
125         return false;
126     return S_ISDIR (sb.st_mode);
127 }
128
129
130
131 /*
132  * Returns 0 if the argument file is not a symbolic link.
133  * Returns size of the link if it is a symbolic link.
134  */
135 ssize_t
136 islink (const char *file)
137 {
138     ssize_t retsize = 0;
139 #ifdef S_ISLNK
140     struct stat sb;
141
142     if ((lstat (file, &sb) >= 0) && S_ISLNK (sb.st_mode))
143         retsize = sb.st_size;
144 #endif
145     return retsize;
146 }
147
148
149
150 /*
151  * Returns true if the argument file is a block or
152  * character special device.
153  */
154 bool
155 isdevice (const char *file)
156 {
157     struct stat sb;
158
159     if (lstat (file, &sb) < 0)
160         return false;
161 #ifdef S_ISBLK
162     if (S_ISBLK (sb.st_mode))
163         return true;
164 #endif
165 #ifdef S_ISCHR
166     if (S_ISCHR (sb.st_mode))
167         return true;
168 #endif
169     return false;
170 }
171
172
173
174 /*
175  * Returns true if the argument file exists.
176  */
177 bool
178 isfile (const char *file)
179 {
180     return isaccessible (file, F_OK);
181 }
182
183
184
185 /*
186  * Returns non-zero if the argument file is readable.
187  */
188 bool
189 isreadable (const char *file)
190 {
191     return isaccessible (file, R_OK);
192 }
193
194
195
196 /*
197  * Returns non-zero if the argument file is writable.
198  */
199 bool
200 iswritable (const char *file)
201 {
202     return isaccessible (file, W_OK);
203 }
204
205
206
207 /*
208  * Returns true if the argument file is accessable according to
209  * mode.  If compiled with SETXID_SUPPORT also works if cvs has setxid
210  * bits set.
211  */
212 bool
213 isaccessible (const char *file, const int mode)
214 {
215 #ifdef SETXID_SUPPORT
216     struct stat sb;
217     int umask = 0;
218     int gmask = 0;
219     int omask = 0;
220     int uid, mask;
221     
222     if (stat (file, &sb)== -1)
223         return false;
224     if (mode == F_OK)
225         return true;
226
227     uid = geteuid();
228     if (uid == 0)               /* superuser */
229     {
230         if (!(mode & X_OK) || (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
231             return true;
232
233         errno = EACCES;
234         return false;
235     }
236         
237     if (mode & R_OK)
238     {
239         umask |= S_IRUSR;
240         gmask |= S_IRGRP;
241         omask |= S_IROTH;
242     }
243     if (mode & W_OK)
244     {
245         umask |= S_IWUSR;
246         gmask |= S_IWGRP;
247         omask |= S_IWOTH;
248     }
249     if (mode & X_OK)
250     {
251         umask |= S_IXUSR;
252         gmask |= S_IXGRP;
253         omask |= S_IXOTH;
254     }
255
256     mask = sb.st_uid == uid ? umask : sb.st_gid == getegid() ? gmask : omask;
257     if ((sb.st_mode & mask) == mask)
258         return true;
259     errno = EACCES;
260     return false;
261 #else /* !SETXID_SUPPORT */
262     return access (file, mode) == 0;
263 #endif /* SETXID_SUPPORT */
264 }
265
266
267
268 /*
269  * Make a directory and die if it fails
270  */
271 void
272 make_directory (const char *name)
273 {
274     struct stat sb;
275
276     if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode)))
277             error (0, 0, "%s already exists but is not a directory", name);
278     if (!noexec && mkdir (name, 0777) < 0)
279         error (1, errno, "cannot make directory %s", name);
280 }
281
282 /*
283  * Make a path to the argument directory, printing a message if something
284  * goes wrong.
285  */
286 void
287 make_directories (const char *name)
288 {
289     char *cp;
290
291     if (noexec)
292         return;
293
294     if (mkdir (name, 0777) == 0 || errno == EEXIST)
295         return;
296     if (! existence_error (errno))
297     {
298         error (0, errno, "cannot make path to %s", name);
299         return;
300     }
301     if ((cp = strrchr (name, '/')) == NULL)
302         return;
303     *cp = '\0';
304     make_directories (name);
305     *cp++ = '/';
306     if (*cp == '\0')
307         return;
308     (void) mkdir (name, 0777);
309 }
310
311 /* Create directory NAME if it does not already exist; fatal error for
312    other errors.  Returns 0 if directory was created; 1 if it already
313    existed.  */
314 int
315 mkdir_if_needed (const char *name)
316 {
317     if (mkdir (name, 0777) < 0)
318     {
319         int save_errno = errno;
320         if (save_errno != EEXIST && !isdir (name))
321             error (1, save_errno, "cannot make directory %s", name);
322         return 1;
323     }
324     return 0;
325 }
326
327 /*
328  * Change the mode of a file, either adding write permissions, or removing
329  * all write permissions.  Either change honors the current umask setting.
330  *
331  * Don't do anything if PreservePermissions is set to `yes'.  This may
332  * have unexpected consequences for some uses of xchmod.
333  */
334 void
335 xchmod (const char *fname, int writable)
336 {
337     struct stat sb;
338     mode_t mode, oumask;
339
340 #ifdef PRESERVE_PERMISSIONS_SUPPORT
341     if (config->preserve_perms)
342         return;
343 #endif /* PRESERVE_PERMISSIONS_SUPPORT */
344
345     if (stat (fname, &sb) < 0)
346     {
347         if (!noexec)
348             error (0, errno, "cannot stat %s", fname);
349         return;
350     }
351     oumask = umask (0);
352     (void) umask (oumask);
353     if (writable)
354     {
355         mode = sb.st_mode | (~oumask
356                              & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0)
357                                 | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0)
358                                 | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0)));
359     }
360     else
361     {
362         mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask;
363     }
364
365     TRACE (TRACE_FUNCTION, "chmod(%s,%o)", fname, (unsigned int) mode);
366
367     if (noexec)
368         return;
369
370     if (chmod (fname, mode) < 0)
371         error (0, errno, "cannot change mode of file %s", fname);
372 }
373
374 /*
375  * Rename a file and die if it fails
376  */
377 void
378 rename_file (const char *from, const char *to)
379 {
380     TRACE (TRACE_FUNCTION, "rename(%s,%s)", from, to);
381
382     if (noexec)
383         return;
384
385     if (rename (from, to) < 0)
386         error (1, errno, "cannot rename file %s to %s", from, to);
387 }
388
389 /*
390  * unlink a file, if possible.
391  */
392 int
393 unlink_file (const char *f)
394 {
395     TRACE (TRACE_FUNCTION, "unlink_file(%s)", f);
396
397     if (noexec)
398         return (0);
399
400     return (CVS_UNLINK (f));
401 }
402
403
404
405 /*
406  * Unlink a file or dir, if possible.  If it is a directory do a deep
407  * removal of all of the files in the directory.  Return -1 on error
408  * (in which case errno is set).
409  */
410 int
411 unlink_file_dir (const char *f)
412 {
413     struct stat sb;
414
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         TRACE (TRACE_FUNCTION, "unlink_file_dir(%s)", f);
420
421     if (noexec)
422         return 0;
423
424     /* For at least some unices, if root tries to unlink() a directory,
425        instead of doing something rational like returning EISDIR,
426        the system will gleefully go ahead and corrupt the filesystem.
427        So we first call stat() to see if it is OK to call unlink().  This
428        doesn't quite work--if someone creates a directory between the
429        call to stat() and the call to unlink(), we'll still corrupt
430        the filesystem.  Where is the Unix Haters Handbook when you need
431        it?  */
432     if (stat (f, &sb) < 0)
433     {
434         if (existence_error (errno))
435         {
436             /* The file or directory doesn't exist anyhow.  */
437             return -1;
438         }
439     }
440     else if (S_ISDIR (sb.st_mode))
441         return deep_remove_dir (f);
442
443     return CVS_UNLINK (f);
444 }
445
446
447
448 /* Remove a directory and everything it contains.  Returns 0 for
449  * success, -1 for failure (in which case errno is set).
450  */
451
452 static int
453 deep_remove_dir (const char *path)
454 {
455     DIR           *dirp;
456     struct dirent *dp;
457
458     if (rmdir (path) != 0)
459     {
460         if (errno == ENOTEMPTY
461             || errno == EEXIST
462             /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
463                (it defines ENOTEMPTY and EEXIST to 17 but actually
464                returns 87).  */
465             || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87))
466         {
467             if ((dirp = CVS_OPENDIR (path)) == NULL)
468                 /* If unable to open the directory return
469                  * an error
470                  */
471                 return -1;
472
473             errno = 0;
474             while ((dp = CVS_READDIR (dirp)) != NULL)
475             {
476                 char *buf;
477
478                 if (strcmp (dp->d_name, ".") == 0 ||
479                             strcmp (dp->d_name, "..") == 0)
480                     continue;
481
482                 buf = Xasprintf ("%s/%s", path, dp->d_name);
483
484                 /* See comment in unlink_file_dir explanation of why we use
485                    isdir instead of just calling unlink and checking the
486                    status.  */
487                 if (isdir (buf)) 
488                 {
489                     if (deep_remove_dir (buf))
490                     {
491                         CVS_CLOSEDIR (dirp);
492                         free (buf);
493                         return -1;
494                     }
495                 }
496                 else
497                 {
498                     if (CVS_UNLINK (buf) != 0)
499                     {
500                         CVS_CLOSEDIR (dirp);
501                         free (buf);
502                         return -1;
503                     }
504                 }
505                 free (buf);
506
507                 errno = 0;
508             }
509             if (errno != 0)
510             {
511                 int save_errno = errno;
512                 CVS_CLOSEDIR (dirp);
513                 errno = save_errno;
514                 return -1;
515             }
516             CVS_CLOSEDIR (dirp);
517             return rmdir (path);
518         }
519         else
520             return -1;
521     }
522
523     /* Was able to remove the directory return 0 */
524     return 0;
525 }
526
527
528
529 /* Read NCHARS bytes from descriptor FD into BUF.
530    Return the number of characters successfully read.
531    The number returned is always NCHARS unless end-of-file or error.  */
532 static size_t
533 block_read (int fd, char *buf, size_t nchars)
534 {
535     char *bp = buf;
536     size_t nread;
537
538     do 
539     {
540         nread = read (fd, bp, nchars);
541         if (nread == (size_t)-1)
542         {
543 #ifdef EINTR
544             if (errno == EINTR)
545                 continue;
546 #endif
547             return (size_t)-1;
548         }
549
550         if (nread == 0)
551             break; 
552
553         bp += nread;
554         nchars -= nread;
555     } while (nchars != 0);
556
557     return bp - buf;
558
559
560     
561 /*
562  * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
563  * If FILE1 and FILE2 are special files, compare their salient characteristics
564  * (i.e. major/minor device numbers, links, etc.
565  */
566 int
567 xcmp (const char *file1, const char *file2)
568 {
569     char *buf1, *buf2;
570     struct stat sb1, sb2;
571     int fd1, fd2;
572     int ret;
573
574     if (lstat (file1, &sb1) < 0)
575         error (1, errno, "cannot lstat %s", file1);
576     if (lstat (file2, &sb2) < 0)
577         error (1, errno, "cannot lstat %s", file2);
578
579     /* If FILE1 and FILE2 are not the same file type, they are unequal. */
580     if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT))
581         return 1;
582
583     /* If FILE1 and FILE2 are symlinks, they are equal if they point to
584        the same thing. */
585 #ifdef S_ISLNK
586     if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
587     {
588         int result;
589         buf1 = Xreadlink (file1, sb1.st_size);
590         buf2 = Xreadlink (file2, sb2.st_size);
591         result = (strcmp (buf1, buf2) == 0);
592         free (buf1);
593         free (buf2);
594         return result;
595     }
596 #endif
597
598     /* If FILE1 and FILE2 are devices, they are equal if their device
599        numbers match. */
600     if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
601     {
602 #ifdef HAVE_STRUCT_STAT_ST_RDEV
603         if (sb1.st_rdev == sb2.st_rdev)
604             return 0;
605         else
606             return 1;
607 #else
608         error (1, 0, "cannot compare device files on this system (%s and %s)",
609                file1, file2);
610 #endif
611     }
612
613     if ((fd1 = open (file1, O_RDONLY)) < 0)
614         error (1, errno, "cannot open file %s for comparing", file1);
615     if ((fd2 = open (file2, O_RDONLY)) < 0)
616         error (1, errno, "cannot open file %s for comparing", file2);
617
618     /* A generic file compare routine might compare st_dev & st_ino here 
619        to see if the two files being compared are actually the same file.
620        But that won't happen in CVS, so we won't bother. */
621
622     if (sb1.st_size != sb2.st_size)
623         ret = 1;
624     else if (sb1.st_size == 0)
625         ret = 0;
626     else
627     {
628         /* FIXME: compute the optimal buffer size by computing the least
629            common multiple of the files st_blocks field */
630         size_t buf_size = 8 * 1024;
631         size_t read1;
632         size_t read2;
633
634         buf1 = xmalloc (buf_size);
635         buf2 = xmalloc (buf_size);
636
637         do 
638         {
639             read1 = block_read (fd1, buf1, buf_size);
640             if (read1 == (size_t)-1) {
641                 error (1, errno, "cannot read file %s for comparing", file1);
642                 exit(1);        /* to suppress -Wstringop-overflow */
643             }
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)
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) tmpdir_env = getenv (TMPDIR_ENV);
869     return tmpdir_env;
870 }
871
872
873
874 void
875 push_env_temp_dir (void)
876 {
877     const char *tmpdir = get_cvs_tmp_dir ();
878     if (tmpdir_env && strcmp (tmpdir_env, tmpdir))
879         setenv (TMPDIR_ENV, tmpdir, 1);
880 }