1 /* filesubr.c --- subroutines for dealing with files
2 Jim Blandy <jimb@cyclic.com>
4 This file is part of GNU CVS.
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
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. */
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. */
25 static int deep_remove_dir (const char *path
);
28 * Copies "from" to "to".
31 copy_file (const char *from
, const char *to
)
38 TRACE (TRACE_FUNCTION
, "copy(%s,%s)", from
, to
);
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)
47 char *source
= Xreadlink (from
, rsize
);
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
);
60 error (1, 0, "cannot copy device files on this system (%s)", from
);
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
);
79 n
= read (fdin
, buf
, sizeof(buf
));
86 error (1, errno
, "cannot read file %s for copying", from
);
91 if (write(fdout
, buf
, n
) != n
) {
92 error (1, errno
, "cannot write file %s for copying", to
);
98 error (0, errno
, "cannot close %s", from
);
99 if (close (fdout
) < 0)
100 error (1, errno
, "cannot close %s", to
);
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
);
112 /* FIXME-krp: these functions would benefit from caching the char * &
116 * Returns true if the argument file is a directory, or is a symbolic
117 * link which points to a directory.
120 isdir (const char *file
)
124 if (stat (file
, &sb
) < 0)
126 return S_ISDIR (sb
.st_mode
);
132 * Returns 0 if the argument file is not a symbolic link.
133 * Returns size of the link if it is a symbolic link.
136 islink (const char *file
)
142 if ((lstat (file
, &sb
) >= 0) && S_ISLNK (sb
.st_mode
))
143 retsize
= sb
.st_size
;
151 * Returns true if the argument file is a block or
152 * character special device.
155 isdevice (const char *file
)
159 if (lstat (file
, &sb
) < 0)
162 if (S_ISBLK (sb
.st_mode
))
166 if (S_ISCHR (sb
.st_mode
))
175 * Returns true if the argument file exists.
178 isfile (const char *file
)
180 return isaccessible (file
, F_OK
);
183 #ifdef SETXID_SUPPORT
190 if (gid
== getegid())
193 ngroups
= getgroups(0, NULL
);
197 if ((gidp
= malloc(sizeof(gid_t
) * ngroups
)) == NULL
)
200 if (getgroups(ngroups
, gidp
) == -1) {
205 for (i
= 0; i
< ngroups
; i
++)
215 * Returns non-zero if the argument file is readable.
218 isreadable (const char *file
)
220 return isaccessible (file
, R_OK
);
226 * Returns non-zero if the argument file is writable.
229 iswritable (const char *file
)
231 return isaccessible (file
, W_OK
);
237 * Returns true if the argument file is accessable according to
238 * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid
242 isaccessible (const char *file
, const int mode
)
244 #ifdef SETXID_SUPPORT
251 if (stat (file
, &sb
)== -1)
257 if (uid
== 0) /* superuser */
259 if (!(mode
& X_OK
) || (sb
.st_mode
& (S_IXUSR
|S_IXGRP
|S_IXOTH
)))
285 mask
= sb
.st_uid
== uid
? umask
: ingroup(sb
.st_gid
) ? gmask
: omask
;
286 if ((sb
.st_mode
& mask
) == mask
)
290 #else /* !SETXID_SUPPORT */
291 return access (file
, mode
) == 0;
292 #endif /* SETXID_SUPPORT */
298 * Make a directory and die if it fails
301 make_directory (const char *name
)
305 if (stat (name
, &sb
) == 0 && (!S_ISDIR (sb
.st_mode
)))
306 error (0, 0, "%s already exists but is not a directory", name
);
307 if (!noexec
&& mkdir (name
, 0777) < 0)
308 error (1, errno
, "cannot make directory %s", name
);
312 * Make a path to the argument directory, printing a message if something
316 make_directories (const char *name
)
323 if (mkdir (name
, 0777) == 0 || errno
== EEXIST
)
325 if (! existence_error (errno
))
327 error (0, errno
, "cannot make path to %s", name
);
330 if ((cp
= strrchr (name
, '/')) == NULL
)
333 make_directories (name
);
337 (void) mkdir (name
, 0777);
340 /* Create directory NAME if it does not already exist; fatal error for
341 other errors. Returns 0 if directory was created; 1 if it already
344 mkdir_if_needed (const char *name
)
346 if (mkdir (name
, 0777) < 0)
348 int save_errno
= errno
;
349 if (save_errno
!= EEXIST
&& !isdir (name
))
350 error (1, save_errno
, "cannot make directory %s", name
);
357 * Change the mode of a file, either adding write permissions, or removing
358 * all write permissions. Either change honors the current umask setting.
360 * Don't do anything if PreservePermissions is set to `yes'. This may
361 * have unexpected consequences for some uses of xchmod.
364 xchmod (const char *fname
, int writable
)
369 #ifdef PRESERVE_PERMISSIONS_SUPPORT
370 if (config
->preserve_perms
)
372 #endif /* PRESERVE_PERMISSIONS_SUPPORT */
374 if (stat (fname
, &sb
) < 0)
377 error (0, errno
, "cannot stat %s", fname
);
381 (void) umask (oumask
);
384 mode
= sb
.st_mode
| (~oumask
385 & (((sb
.st_mode
& S_IRUSR
) ? S_IWUSR
: 0)
386 | ((sb
.st_mode
& S_IRGRP
) ? S_IWGRP
: 0)
387 | ((sb
.st_mode
& S_IROTH
) ? S_IWOTH
: 0)));
391 mode
= sb
.st_mode
& ~(S_IWRITE
| S_IWGRP
| S_IWOTH
) & ~oumask
;
394 TRACE (TRACE_FUNCTION
, "chmod(%s,%o)", fname
, (unsigned int) mode
);
399 if (chmod (fname
, mode
) < 0)
400 error (0, errno
, "cannot change mode of file %s", fname
);
404 * Rename a file and die if it fails
407 rename_file (const char *from
, const char *to
)
409 TRACE (TRACE_FUNCTION
, "rename(%s,%s)", from
, to
);
414 if (rename (from
, to
) < 0)
415 error (1, errno
, "cannot rename file %s to %s", from
, to
);
419 * unlink a file, if possible.
422 unlink_file (const char *f
)
424 TRACE (TRACE_FUNCTION
, "unlink_file(%s)", f
);
429 return (CVS_UNLINK (f
));
435 * Unlink a file or dir, if possible. If it is a directory do a deep
436 * removal of all of the files in the directory. Return -1 on error
437 * (in which case errno is set).
440 unlink_file_dir (const char *f
)
444 /* This is called by the server parent process in contexts where
445 it is not OK to send output (e.g. after we sent "ok" to the
448 TRACE (TRACE_FUNCTION
, "unlink_file_dir(%s)", f
);
453 /* For at least some unices, if root tries to unlink() a directory,
454 instead of doing something rational like returning EISDIR,
455 the system will gleefully go ahead and corrupt the filesystem.
456 So we first call stat() to see if it is OK to call unlink(). This
457 doesn't quite work--if someone creates a directory between the
458 call to stat() and the call to unlink(), we'll still corrupt
459 the filesystem. Where is the Unix Haters Handbook when you need
461 if (stat (f
, &sb
) < 0)
463 if (existence_error (errno
))
465 /* The file or directory doesn't exist anyhow. */
469 else if (S_ISDIR (sb
.st_mode
))
470 return deep_remove_dir (f
);
472 return CVS_UNLINK (f
);
477 /* Remove a directory and everything it contains. Returns 0 for
478 * success, -1 for failure (in which case errno is set).
482 deep_remove_dir (const char *path
)
487 if (rmdir (path
) != 0)
489 if (errno
== ENOTEMPTY
491 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
492 (it defines ENOTEMPTY and EEXIST to 17 but actually
494 || (ENOTEMPTY
== 17 && EEXIST
== 17 && errno
== 87))
496 if ((dirp
= CVS_OPENDIR (path
)) == NULL
)
497 /* If unable to open the directory return
503 while ((dp
= CVS_READDIR (dirp
)) != NULL
)
507 if (strcmp (dp
->d_name
, ".") == 0 ||
508 strcmp (dp
->d_name
, "..") == 0)
511 buf
= Xasprintf ("%s/%s", path
, dp
->d_name
);
513 /* See comment in unlink_file_dir explanation of why we use
514 isdir instead of just calling unlink and checking the
518 if (deep_remove_dir (buf
))
527 if (CVS_UNLINK (buf
) != 0)
540 int save_errno
= errno
;
552 /* Was able to remove the directory return 0 */
558 /* Read NCHARS bytes from descriptor FD into BUF.
559 Return the number of characters successfully read.
560 The number returned is always NCHARS unless end-of-file or error. */
562 block_read (int fd
, char *buf
, size_t nchars
)
569 nread
= read (fd
, bp
, nchars
);
570 if (nread
== (size_t)-1)
584 } while (nchars
!= 0);
591 * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
592 * If FILE1 and FILE2 are special files, compare their salient characteristics
593 * (i.e. major/minor device numbers, links, etc.
596 xcmp (const char *file1
, const char *file2
)
599 struct stat sb1
, sb2
;
603 if (lstat (file1
, &sb1
) < 0)
604 error (1, errno
, "cannot lstat %s", file1
);
605 if (lstat (file2
, &sb2
) < 0)
606 error (1, errno
, "cannot lstat %s", file2
);
608 /* If FILE1 and FILE2 are not the same file type, they are unequal. */
609 if ((sb1
.st_mode
& S_IFMT
) != (sb2
.st_mode
& S_IFMT
))
612 /* If FILE1 and FILE2 are symlinks, they are equal if they point to
615 if (S_ISLNK (sb1
.st_mode
) && S_ISLNK (sb2
.st_mode
))
618 buf1
= Xreadlink (file1
, sb1
.st_size
);
619 buf2
= Xreadlink (file2
, sb2
.st_size
);
620 result
= (strcmp (buf1
, buf2
) == 0);
627 /* If FILE1 and FILE2 are devices, they are equal if their device
629 if (S_ISBLK (sb1
.st_mode
) || S_ISCHR (sb1
.st_mode
))
631 #ifdef HAVE_STRUCT_STAT_ST_RDEV
632 if (sb1
.st_rdev
== sb2
.st_rdev
)
637 error (1, 0, "cannot compare device files on this system (%s and %s)",
642 if ((fd1
= open (file1
, O_RDONLY
)) < 0)
643 error (1, errno
, "cannot open file %s for comparing", file1
);
644 if ((fd2
= open (file2
, O_RDONLY
)) < 0)
645 error (1, errno
, "cannot open file %s for comparing", file2
);
647 /* A generic file compare routine might compare st_dev & st_ino here
648 to see if the two files being compared are actually the same file.
649 But that won't happen in CVS, so we won't bother. */
651 if (sb1
.st_size
!= sb2
.st_size
)
653 else if (sb1
.st_size
== 0)
657 /* FIXME: compute the optimal buffer size by computing the least
658 common multiple of the files st_blocks field */
659 size_t buf_size
= 8 * 1024;
663 buf1
= xmalloc (buf_size
);
664 buf2
= xmalloc (buf_size
);
668 read1
= block_read (fd1
, buf1
, buf_size
);
669 if (read1
== (size_t)-1)
670 error (1, errno
, "cannot read file %s for comparing", file1
);
672 read2
= block_read (fd2
, buf2
, buf_size
);
673 if (read2
== (size_t)-1)
674 error (1, errno
, "cannot read file %s for comparing", file2
);
676 /* assert (read1 == read2); */
678 ret
= memcmp(buf1
, buf2
, read1
);
679 } while (ret
== 0 && read1
== buf_size
);
690 /* Generate a unique temporary filename. Returns a pointer to a newly
691 * malloc'd string containing the name. Returns successfully or not at
694 * THIS FUNCTION IS DEPRECATED!!! USE cvs_temp_file INSTEAD!!!
696 * and yes, I know about the way the rcs commands use temp files. I think
697 * they should be converted too but I don't have time to look into it right
706 fp
= cvs_temp_file (&fn
);
708 error (1, errno
, "Failed to create temporary file");
709 if (fclose (fp
) == EOF
)
710 error (0, errno
, "Failed to close temporary file %s", fn
);
714 /* Generate a unique temporary filename and return an open file stream
715 * to the truncated file by that name
718 * filename where to place the pointer to the newly allocated file
722 * filename dereferenced, will point to the newly allocated file
723 * name string. This value is undefined if the function
727 * An open file pointer to a read/write mode empty temporary file with the
728 * unique file name or NULL on failure.
731 * On error, errno will be set to some value either by CVS_FOPEN or
732 * whatever system function is called to generate the temporary file name.
733 * The value of filename is undefined on error.
736 cvs_temp_file (char **filename
)
742 /* FIXME - I'd like to be returning NULL here in noexec mode, but I think
743 * some of the rcs & diff functions which rely on a temp file run in
747 assert (filename
!= NULL
);
749 fn
= Xasprintf ("%s/%s", get_cvs_tmp_dir (), "cvsXXXXXX");
752 /* a NULL return will be interpreted by callers as an error and
753 * errno should still be set
757 else if ((fp
= CVS_FDOPEN (fd
, "w+")) == NULL
)
759 /* Attempt to close and unlink the file since mkstemp returned
760 * sucessfully and we believe it's been created and opened.
762 int save_errno
= errno
;
764 error (0, errno
, "Failed to close temporary file %s", fn
);
766 error (0, errno
, "Failed to unlink temporary file %s", fn
);
773 /* mkstemp is defined to open mode 0600 using glibc 2.0.7+. There used
774 * to be a complicated #ifdef checking the library versions here and then
775 * a chmod 0600 on the temp file for versions of glibc less than 2.1. This
776 * is rather a special case, leaves a race condition open regardless, and
777 * one could hope that sysadmins have read the relevant security
778 * announcements and upgraded by now to a version with a fix committed in
781 * If it is decided at some point that old, buggy versions of glibc should
782 * still be catered to, a umask of 0600 should be set before file creation
783 * instead then reset after file creation since this would avoid the race
784 * condition that the chmod left open to exploitation.
793 /* Return a pointer into PATH's last component. */
795 last_component (const char *path
)
797 const char *last
= strrchr (path
, '/');
799 if (last
&& (last
!= path
))
807 /* Return the home directory. Returns a pointer to storage
808 managed by this function or its callees (currently getenv).
809 This function will return the same thing every time it is
810 called. Returns NULL if there is no home directory.
812 Note that for a pserver server, this may return root's home
813 directory. What typically happens is that upon being started from
814 inetd, before switching users, the code in cvsrc.c calls
815 get_homedir which remembers root's home directory in the static
816 variable. Then the switch happens and get_homedir might return a
817 directory that we don't even have read or execute permissions for
818 (which is bad, when various parts of CVS try to read there). One
819 fix would be to make the value returned by get_homedir only good
820 until the next call (which would free the old value). Another fix
821 would be to just always malloc our answer, and let the caller free
822 it (that is best, because some day we may need to be reentrant).
824 The workaround is to put -f in inetd.conf which means that
825 get_homedir won't get called until after the switch in user ID.
827 The whole concept of a "home directory" on the server is pretty
828 iffy, although I suppose some people probably are relying on it for
829 .cvsrc and such, in the cases where it works. */
833 static char *home
= NULL
;
840 if (!server_active
&& (env
= getenv ("HOME")) != NULL
)
842 else if ((pw
= (struct passwd
*) getpwuid (getuid ()))
844 home
= xstrdup (pw
->pw_dir
);
851 /* Compose a path to a file in the home directory. This is necessary because
852 * of different behavior on UNIX and VMS. See the notes in vms/filesubr.c.
854 * A more clean solution would be something more along the lines of a
855 * "join a directory to a filename" kind of thing which was not specific to
856 * the homedir. This should aid portability between UNIX, Mac, Windows, VMS,
857 * and possibly others. This is already handled by Perl - it might be
858 * interesting to see how much of the code was written in C since Perl is under
859 * the GPL and the Artistic license - we might be able to use it.
862 strcat_filename_onto_homedir (const char *dir
, const char *file
)
864 char *path
= Xasprintf ("%s/%s", dir
, file
);
868 /* See cvs.h for description. On unix this does nothing, because the
869 shell expands the wildcards. */
871 expand_wild (int argc
, char **argv
, int *pargc
, char ***pargv
)
874 if (size_overflow_p (xtimes (argc
, sizeof (char *)))) {
877 error (0, 0, "expand_wild: too many arguments");
881 *pargv
= xnmalloc (argc
, sizeof (char *));
882 for (i
= 0; i
< argc
; ++i
)
883 (*pargv
)[i
] = xstrdup (argv
[i
]);
888 static char *tmpdir_env
;
890 /* Return path to temp directory.
893 get_system_temp_dir (void)
895 if (!tmpdir_env
) tmpdir_env
= getenv (TMPDIR_ENV
);
902 push_env_temp_dir (void)
904 const char *tmpdir
= get_cvs_tmp_dir ();
905 if (tmpdir_env
&& strcmp (tmpdir_env
, tmpdir
))
906 setenv (TMPDIR_ENV
, tmpdir
, 1);