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. */
24 static int deep_remove_dir (const char *path);
27 * Copies "from" to "to".
30 copy_file (const char *from, const char *to)
37 TRACE (TRACE_FUNCTION, "copy(%s,%s)", from, to);
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)
46 char *source = Xreadlink (from, rsize);
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);
59 error (1, 0, "cannot copy device files on this system (%s)", from);
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);
78 n = read (fdin, buf, sizeof(buf));
85 error (1, errno, "cannot read file %s for copying", from);
90 if (write(fdout, buf, n) != n) {
91 error (1, errno, "cannot write file %s for copying", to);
97 error (0, errno, "cannot close %s", from);
98 if (close (fdout) < 0)
99 error (1, errno, "cannot close %s", to);
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);
111 /* FIXME-krp: these functions would benefit from caching the char * &
115 * Returns true if the argument file is a directory, or is a symbolic
116 * link which points to a directory.
119 isdir (const char *file)
123 if (CVS_STAT (file, &sb) < 0)
125 return S_ISDIR (sb.st_mode);
131 * Returns 0 if the argument file is not a symbolic link.
132 * Returns size of the link if it is a symbolic link.
135 islink (const char *file)
141 if ((CVS_LSTAT (file, &sb) >= 0) && S_ISLNK (sb.st_mode))
142 retsize = sb.st_size;
150 * Returns true if the argument file is a block or
151 * character special device.
154 isdevice (const char *file)
158 if (CVS_LSTAT (file, &sb) < 0)
161 if (S_ISBLK (sb.st_mode))
165 if (S_ISCHR (sb.st_mode))
174 * Returns true if the argument file exists.
177 isfile (const char *file)
179 return isaccessible (file, F_OK);
185 * Returns non-zero if the argument file is readable.
188 isreadable (const char *file)
190 return isaccessible (file, R_OK);
196 * Returns non-zero if the argument file is writable.
199 iswritable (const char *file)
201 return isaccessible (file, W_OK);
207 * Returns true if the argument file is accessable according to
208 * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid
212 isaccessible (const char *file, const int mode)
214 #ifdef SETXID_SUPPORT
221 if (CVS_STAT (file, &sb)== -1)
227 if (uid == 0) /* superuser */
229 if (!(mode & X_OK) || (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
255 mask = sb.st_uid == uid ? umask : sb.st_gid == getegid() ? gmask : omask;
256 if ((sb.st_mode & mask) == mask)
260 #else /* !SETXID_SUPPORT */
261 return access (file, mode) == 0;
262 #endif /* SETXID_SUPPORT */
268 * Make a directory and die if it fails
271 make_directory (const char *name)
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);
282 * Make a path to the argument directory, printing a message if something
286 make_directories (const char *name)
293 if (mkdir (name, 0777) == 0 || errno == EEXIST)
295 if (! existence_error (errno))
297 error (0, errno, "cannot make path to %s", name);
300 if ((cp = strrchr (name, '/')) == NULL)
303 make_directories (name);
307 (void) mkdir (name, 0777);
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
314 mkdir_if_needed (const char *name)
316 if (mkdir (name, 0777) < 0)
318 int save_errno = errno;
319 if (save_errno != EEXIST && !isdir (name))
320 error (1, save_errno, "cannot make directory %s", name);
327 * Change the mode of a file, either adding write permissions, or removing
328 * all write permissions. Either change honors the current umask setting.
330 * Don't do anything if PreservePermissions is set to `yes'. This may
331 * have unexpected consequences for some uses of xchmod.
334 xchmod (const char *fname, int writable)
339 #ifdef PRESERVE_PERMISSIONS_SUPPORT
340 if (config->preserve_perms)
342 #endif /* PRESERVE_PERMISSIONS_SUPPORT */
344 if( CVS_STAT( fname, &sb ) < 0 )
347 error (0, errno, "cannot stat %s", fname);
351 (void) umask (oumask);
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)));
361 mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask;
364 TRACE (TRACE_FUNCTION, "chmod(%s,%o)", fname, (unsigned int) mode);
369 if (chmod (fname, mode) < 0)
370 error (0, errno, "cannot change mode of file %s", fname);
374 * Rename a file and die if it fails
377 rename_file (const char *from, const char *to)
379 TRACE (TRACE_FUNCTION, "rename(%s,%s)", from, to);
384 if (rename (from, to) < 0)
385 error (1, errno, "cannot rename file %s to %s", from, to);
389 * unlink a file, if possible.
392 unlink_file (const char *f)
394 TRACE (TRACE_FUNCTION, "unlink_file(%s)", f);
399 return (CVS_UNLINK (f));
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).
410 unlink_file_dir (const char *f)
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
420 TRACE (TRACE_FUNCTION, "unlink_file_dir(%s)", f);
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
433 if( CVS_STAT( f, &sb ) < 0 )
435 if (existence_error (errno))
437 /* The file or directory doesn't exist anyhow. */
441 else if (S_ISDIR (sb.st_mode))
442 return deep_remove_dir (f);
444 return CVS_UNLINK (f);
449 /* Remove a directory and everything it contains. Returns 0 for
450 * success, -1 for failure (in which case errno is set).
454 deep_remove_dir (const char *path)
459 if (rmdir (path) != 0)
461 if (errno == ENOTEMPTY
463 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
464 (it defines ENOTEMPTY and EEXIST to 17 but actually
466 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87))
468 if ((dirp = CVS_OPENDIR (path)) == NULL)
469 /* If unable to open the directory return
475 while ((dp = CVS_READDIR (dirp)) != NULL)
479 if (strcmp (dp->d_name, ".") == 0 ||
480 strcmp (dp->d_name, "..") == 0)
483 buf = Xasprintf ("%s/%s", path, dp->d_name);
485 /* See comment in unlink_file_dir explanation of why we use
486 isdir instead of just calling unlink and checking the
490 if (deep_remove_dir (buf))
499 if (CVS_UNLINK (buf) != 0)
512 int save_errno = errno;
524 /* Was able to remove the directory return 0 */
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. */
534 block_read (int fd, char *buf, size_t nchars)
541 nread = read (fd, bp, nchars);
542 if (nread == (size_t)-1)
556 } while (nchars != 0);
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.
568 xcmp (const char *file1, const char *file2)
571 struct stat sb1, sb2;
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);
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))
584 /* If FILE1 and FILE2 are symlinks, they are equal if they point to
587 if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
590 buf1 = Xreadlink (file1, sb1.st_size);
591 buf2 = Xreadlink (file2, sb2.st_size);
592 result = (strcmp (buf1, buf2) == 0);
599 /* If FILE1 and FILE2 are devices, they are equal if their device
601 if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
603 #ifdef HAVE_STRUCT_STAT_ST_RDEV
604 if (sb1.st_rdev == sb2.st_rdev)
609 error (1, 0, "cannot compare device files on this system (%s and %s)",
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);
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. */
623 if (sb1.st_size != sb2.st_size)
625 else if (sb1.st_size == 0)
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;
635 buf1 = xmalloc (buf_size);
636 buf2 = xmalloc (buf_size);
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);
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);
648 /* assert (read1 == read2); */
650 ret = memcmp(buf1, buf2, read1);
651 } while (ret == 0 && read1 == buf_size);
662 /* Generate a unique temporary filename. Returns a pointer to a newly
663 * malloc'd string containing the name. Returns successfully or not at
666 * THIS FUNCTION IS DEPRECATED!!! USE cvs_temp_file INSTEAD!!!
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
678 fp = cvs_temp_file (&fn);
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);
686 /* Generate a unique temporary filename and return an open file stream
687 * to the truncated file by that name
690 * filename where to place the pointer to the newly allocated file
694 * filename dereferenced, will point to the newly allocated file
695 * name string. This value is undefined if the function
699 * An open file pointer to a read/write mode empty temporary file with the
700 * unique file name or NULL on failure.
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.
708 cvs_temp_file (char **filename)
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
719 assert (filename != NULL);
721 fn = Xasprintf ("%s/%s", Tmpdir, "cvsXXXXXX");
724 /* a NULL return will be interpreted by callers as an error and
725 * errno should still be set
729 else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL)
731 /* Attempt to close and unlink the file since mkstemp returned
732 * sucessfully and we believe it's been created and opened.
734 int save_errno = errno;
736 error (0, errno, "Failed to close temporary file %s", fn);
738 error (0, errno, "Failed to unlink temporary file %s", fn);
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
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.
766 * xresolvepath (const char *path)
768 * Like xreadlink(), but resolve all links in a path.
771 * path The original path.
774 * The path with any symbolic links expanded.
777 * This function exits with a fatal error if it fails to read the link for
781 xresolvepath (const char *path)
784 struct saved_cwd owd;
786 assert (isdir (path));
788 /* FIXME - If HAVE_READLINK is defined, we should probably walk the path
789 * bit by bit calling xreadlink().
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");
805 /* Return a pointer into PATH's last component. */
807 last_component (const char *path)
809 const char *last = strrchr (path, '/');
811 if (last && (last != path))
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.
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).
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.
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. */
845 static char *home = NULL;
853 #ifdef SERVER_SUPPORT
856 (env = getenv ("HOME")) != NULL)
858 else if ((pw = (struct passwd *) getpwuid (getuid ()))
860 home = xstrdup (pw->pw_dir);
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.
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.
878 strcat_filename_onto_homedir (const char *dir, const char *file)
880 char *path = Xasprintf ("%s/%s", dir, file);
884 /* See cvs.h for description. On unix this does nothing, because the
885 shell expands the wildcards. */
887 expand_wild (int argc, char **argv, int *pargc, char ***pargv)
890 if (size_overflow_p (xtimes (argc, sizeof (char *)))) {
893 error (0, 0, "expand_wild: too many arguments");
897 *pargv = xnmalloc (argc, sizeof (char *));
898 for (i = 0; i < argc; ++i)
899 (*pargv)[i] = xstrdup (argv[i]);