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. */
22 static int deep_remove_dir (const char *path);
25 * Copies "from" to "to".
28 copy_file (const char *from, const char *to)
34 TRACE ( 1, "copy(%s,%s)", from, to );
39 /* If the file to be copied is a link or a device, then just create
40 the new link or device appropriately. */
43 char *source = xreadlink (from);
51 #if defined(HAVE_MKNOD) && defined(HAVE_STRUCT_STAT_ST_RDEV)
52 if( CVS_STAT( from, &sb ) < 0 )
53 error (1, errno, "cannot stat %s", from);
54 mknod (to, sb.st_mode, sb.st_rdev);
56 error (1, 0, "cannot copy device files on this system (%s)", from);
61 /* Not a link or a device... probably a regular file. */
62 if ((fdin = open (from, O_RDONLY)) < 0)
63 error (1, errno, "cannot open %s for copying", from);
64 if (fstat (fdin, &sb) < 0)
65 error (1, errno, "cannot fstat %s", from);
66 if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0)
67 error (1, errno, "cannot create %s for copying", to);
75 n = read (fdin, buf, sizeof(buf));
82 error (1, errno, "cannot read file %s for copying", from);
87 if (write(fdout, buf, n) != n) {
88 error (1, errno, "cannot write file %s for copying", to);
94 error (1, errno, "cannot fsync file %s after copying", to);
99 error (0, errno, "cannot close %s", from);
100 if (close (fdout) < 0)
101 error (1, errno, "cannot close %s", to);
104 /* now, set the times for the copied file to match those of the original */
105 memset ((char *) &t, 0, sizeof (t));
106 t.actime = sb.st_atime;
107 t.modtime = sb.st_mtime;
108 (void) utime (to, &t);
111 /* FIXME-krp: these functions would benefit from caching the char * &
115 * Returns non-zero 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));
129 * Returns non-zero if the argument file is a symbolic link.
132 islink (const char *file)
137 if (CVS_LSTAT (file, &sb) < 0)
139 return (S_ISLNK (sb.st_mode));
146 * Returns non-zero if the argument file is a block or
147 * character special device.
150 isdevice (const char *file)
154 if (CVS_LSTAT (file, &sb) < 0)
157 if (S_ISBLK (sb.st_mode))
161 if (S_ISCHR (sb.st_mode))
168 * Returns non-zero if the argument file exists.
171 isfile (const char *file)
173 return isaccessible(file, F_OK);
177 * Returns non-zero if the argument file is readable.
180 isreadable (const char *file)
182 return isaccessible(file, R_OK);
186 * Returns non-zero if the argument file is writable.
189 iswritable (const char *file)
191 return isaccessible(file, W_OK);
195 * Returns non-zero if the argument file is accessable according to
196 * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid
200 isaccessible (const char *file, const int mode)
202 #ifdef SETXID_SUPPORT
209 if( CVS_STAT( file, &sb ) == -1 )
215 if (uid == 0) /* superuser */
217 if (!(mode & X_OK) || (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
243 mask = sb.st_uid == uid ? umask : sb.st_gid == getegid() ? gmask : omask;
244 if ((sb.st_mode & mask) == mask)
249 return access(file, mode) == 0;
254 * Open a file and die if it fails
257 open_file (const char *name, const char *mode)
261 if ((fp = fopen (name, mode)) == NULL)
262 error (1, errno, "cannot open %s", name);
267 * Make a directory and die if it fails
270 make_directory (const char *name)
274 if( CVS_STAT( name, &sb ) == 0 && ( !S_ISDIR( sb.st_mode ) ) )
275 error (0, 0, "%s already exists but is not a directory", name);
276 if (!noexec && mkdir (name, 0777) < 0)
277 error (1, errno, "cannot make directory %s", name);
281 * Make a path to the argument directory, printing a message if something
285 make_directories (const char *name)
292 if (mkdir (name, 0777) == 0 || errno == EEXIST)
294 if (! existence_error (errno))
296 error (0, errno, "cannot make path to %s", name);
299 if ((cp = strrchr (name, '/')) == NULL)
302 make_directories (name);
306 (void) mkdir (name, 0777);
309 /* Create directory NAME if it does not already exist; fatal error for
310 other errors. Returns 0 if directory was created; 1 if it already
313 mkdir_if_needed (const char *name)
315 if (mkdir (name, 0777) < 0)
317 int save_errno = errno;
318 if (save_errno != EEXIST && !isdir (name))
319 error (1, save_errno, "cannot make directory %s", name);
326 * Change the mode of a file, either adding write permissions, or removing
327 * all write permissions. Either change honors the current umask setting.
329 * Don't do anything if PreservePermissions is set to `yes'. This may
330 * have unexpected consequences for some uses of xchmod.
333 xchmod (const char *fname, int writable)
341 if( CVS_STAT( fname, &sb ) < 0 )
344 error (0, errno, "cannot stat %s", fname);
348 (void) umask (oumask);
351 mode = sb.st_mode | (~oumask
352 & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0)
353 | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0)
354 | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0)));
358 mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask;
361 TRACE ( 1, "chmod(%s,%o)", fname, (unsigned int) mode );
366 if (chmod (fname, mode) < 0)
367 error (0, errno, "cannot change mode of file %s", fname);
371 * Rename a file and die if it fails
374 rename_file (const char *from, const char *to)
376 TRACE ( 1, "rename(%s,%s)", from, to );
381 if (rename (from, to) < 0)
382 error (1, errno, "cannot rename file %s to %s", from, to);
386 * unlink a file, if possible.
389 unlink_file (const char *f)
391 TRACE ( 1, "unlink_file(%s)", f );
396 return (CVS_UNLINK (f));
402 * Unlink a file or dir, if possible. If it is a directory do a deep
403 * removal of all of the files in the directory. Return -1 on error
404 * (in which case errno is set).
407 unlink_file_dir (const char *f)
411 #ifdef SERVER_SUPPORT
412 /* This is called by the server parent process in contexts where
413 it is not OK to send output (e.g. after we sent "ok" to the
417 TRACE (TRACE_FUNCTION, "unlink_file_dir(%s)", f);
422 /* For at least some unices, if root tries to unlink() a directory,
423 instead of doing something rational like returning EISDIR,
424 the system will gleefully go ahead and corrupt the filesystem.
425 So we first call stat() to see if it is OK to call unlink(). This
426 doesn't quite work--if someone creates a directory between the
427 call to stat() and the call to unlink(), we'll still corrupt
428 the filesystem. Where is the Unix Haters Handbook when you need
430 if( CVS_STAT( f, &sb ) < 0 )
432 if (existence_error (errno))
434 /* The file or directory doesn't exist anyhow. */
438 else if (S_ISDIR (sb.st_mode))
439 return deep_remove_dir (f);
441 return CVS_UNLINK (f);
446 /* Remove a directory and everything it contains. Returns 0 for
447 * success, -1 for failure (in which case errno is set).
451 deep_remove_dir (const char *path)
456 if (rmdir (path) != 0)
458 if (errno == ENOTEMPTY
460 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
461 (it defines ENOTEMPTY and EEXIST to 17 but actually
463 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87))
465 if ((dirp = CVS_OPENDIR (path)) == NULL)
466 /* If unable to open the directory return
472 while ((dp = CVS_READDIR (dirp)) != NULL)
476 if (strcmp (dp->d_name, ".") == 0 ||
477 strcmp (dp->d_name, "..") == 0)
480 buf = xmalloc (strlen (path) + strlen (dp->d_name) + 5);
481 sprintf (buf, "%s/%s", path, dp->d_name);
483 /* See comment in unlink_file_dir explanation of why we use
484 isdir instead of just calling unlink and checking the
488 if (deep_remove_dir (buf))
497 if (CVS_UNLINK (buf) != 0)
510 int save_errno = errno;
522 /* Was able to remove the directory return 0 */
528 /* Read NCHARS bytes from descriptor FD into BUF.
529 Return the number of characters successfully read.
530 The number returned is always NCHARS unless end-of-file or error. */
532 block_read (int fd, char *buf, size_t nchars)
539 nread = read (fd, bp, nchars);
540 if (nread == (size_t)-1)
554 } while (nchars != 0);
561 * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
562 * If FILE1 and FILE2 are special files, compare their salient characteristics
563 * (i.e. major/minor device numbers, links, etc.
566 xcmp (const char *file1, const char *file2)
569 struct stat sb1, sb2;
573 if (CVS_LSTAT (file1, &sb1) < 0)
574 error (1, errno, "cannot lstat %s", file1);
575 if (CVS_LSTAT (file2, &sb2) < 0)
576 error (1, errno, "cannot lstat %s", file2);
578 /* If FILE1 and FILE2 are not the same file type, they are unequal. */
579 if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT))
582 /* If FILE1 and FILE2 are symlinks, they are equal if they point to
585 if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
588 buf1 = xreadlink (file1);
589 buf2 = xreadlink (file2);
590 result = (strcmp (buf1, buf2) == 0);
597 /* If FILE1 and FILE2 are devices, they are equal if their device
599 if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
601 #ifdef HAVE_STRUCT_STAT_ST_RDEV
602 if (sb1.st_rdev == sb2.st_rdev)
607 error (1, 0, "cannot compare device files on this system (%s and %s)",
612 if ((fd1 = open (file1, O_RDONLY)) < 0)
613 error (1, errno, "cannot open file %s for comparing", file1);
614 if ((fd2 = open (file2, O_RDONLY)) < 0)
615 error (1, errno, "cannot open file %s for comparing", file2);
617 /* A generic file compare routine might compare st_dev & st_ino here
618 to see if the two files being compared are actually the same file.
619 But that won't happen in CVS, so we won't bother. */
621 if (sb1.st_size != sb2.st_size)
623 else if (sb1.st_size == 0)
627 /* FIXME: compute the optimal buffer size by computing the least
628 common multiple of the files st_blocks field */
629 size_t buf_size = 8 * 1024;
633 buf1 = xmalloc (buf_size);
634 buf2 = xmalloc (buf_size);
638 read1 = block_read (fd1, buf1, buf_size);
639 if (read1 == (size_t)-1)
640 error (1, errno, "cannot read file %s for comparing", file1);
642 read2 = block_read (fd2, buf2, buf_size);
643 if (read2 == (size_t)-1)
644 error (1, errno, "cannot read file %s for comparing", file2);
646 /* assert (read1 == read2); */
648 ret = memcmp(buf1, buf2, read1);
649 } while (ret == 0 && read1 == buf_size);
660 /* Generate a unique temporary filename. Returns a pointer to a newly
661 * malloc'd string containing the name. Returns successfully or not at
664 * THIS FUNCTION IS DEPRECATED!!! USE cvs_temp_file INSTEAD!!!
666 * and yes, I know about the way the rcs commands use temp files. I think
667 * they should be converted too but I don't have time to look into it right
676 fp = cvs_temp_file (&fn);
678 error (1, errno, "Failed to create temporary file");
679 if (fclose (fp) == EOF)
680 error (0, errno, "Failed to close temporary file %s", fn);
684 /* Generate a unique temporary filename and return an open file stream
685 * to the truncated file by that name
688 * filename where to place the pointer to the newly allocated file
692 * filename dereferenced, will point to the newly allocated file
693 * name string. This value is undefined if the function
697 * An open file pointer to a read/write mode empty temporary file with the
698 * unique file name or NULL on failure.
701 * On error, errno will be set to some value either by CVS_FOPEN or
702 * whatever system function is called to generate the temporary file name.
703 * The value of filename is undefined on error.
705 FILE *cvs_temp_file (char **filename)
711 /* FIXME - I'd like to be returning NULL here in noexec mode, but I think
712 * some of the rcs & diff functions which rely on a temp file run in
716 assert (filename != NULL);
718 fn = xmalloc (strlen (Tmpdir) + 11);
719 sprintf (fn, "%s/%s", Tmpdir, "cvsXXXXXX" );
722 /* a NULL return will be interpreted by callers as an error and
723 * errno should still be set
725 if (fd == -1) fp = NULL;
726 else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL)
728 /* Attempt to close and unlink the file since mkstemp returned
729 * sucessfully and we believe it's been created and opened.
731 int save_errno = errno;
733 error (0, errno, "Failed to close temporary file %s", fn);
735 error (0, errno, "Failed to unlink temporary file %s", fn);
739 if (fp == NULL) free (fn);
741 /* mkstemp is defined to open mode 0600 using glibc 2.0.7+. There used
742 * to be a complicated #ifdef checking the library versions here and then
743 * a chmod 0600 on the temp file for versions of glibc less than 2.1. This
744 * is rather a special case, leaves a race condition open regardless, and
745 * one could hope that sysadmins have read the relevant security
746 * announcements and upgraded by now to a version with a fix committed in
749 * If it is decided at some point that old, buggy versions of glibc should
750 * still be catered to, a umask of 0600 should be set before file creation
751 * instead then reset after file creation since this would avoid the race
752 * condition that the chmod left open to exploitation.
763 * xreadlink ( const char *link )
765 * Like the X/OPEN and 4.4BSD readlink() function, but allocates and returns
769 * link The original path.
772 * The resolution of the final symbolic link in the path.
775 * This function exits with a fatal error if it fails to read the link for
779 xreadlink (const char *link)
785 /* Get the name of the file to which `from' is linked.
786 FIXME: what portability issues arise here? Are readlink &
787 ENAMETOOLONG defined on all systems? -twp */
790 file = xrealloc (file, buflen);
791 link_name_len = readlink (link, file, buflen - 1);
794 while (link_name_len < 0 && errno == ENAMETOOLONG);
796 if (link_name_len < 0)
797 error (1, errno, "cannot readlink %s", link);
799 file[link_name_len] = '\0';
803 #endif /* HAVE_READLINK */
808 * xresolvepath ( const char *path )
810 * Like xreadlink(), but resolve all links in a path.
813 * path The original path.
816 * The path with any symbolic links expanded.
819 * This function exits with a fatal error if it fails to read the link for
823 xresolvepath (const char *path)
828 assert ( isdir ( path ) );
830 /* FIXME - If HAVE_READLINK is defined, we should probably walk the path
831 * bit by bit calling xreadlink().
835 if ( CVS_CHDIR ( path ) < 0)
836 error ( 1, errno, "cannot chdir to %s", path );
837 if ( ( hardpath = xgetwd() ) == NULL )
838 error (1, errno, "cannot getwd in %s", path);
839 if ( CVS_CHDIR ( owd ) < 0)
840 error ( 1, errno, "cannot chdir to %s", owd );
847 /* Return a pointer into PATH's last component. */
849 last_component (const char *path)
851 const char *last = strrchr (path, '/');
853 if (last && (last != path))
861 /* Return the home directory. Returns a pointer to storage
862 managed by this function or its callees (currently getenv).
863 This function will return the same thing every time it is
864 called. Returns NULL if there is no home directory.
866 Note that for a pserver server, this may return root's home
867 directory. What typically happens is that upon being started from
868 inetd, before switching users, the code in cvsrc.c calls
869 get_homedir which remembers root's home directory in the static
870 variable. Then the switch happens and get_homedir might return a
871 directory that we don't even have read or execute permissions for
872 (which is bad, when various parts of CVS try to read there). One
873 fix would be to make the value returned by get_homedir only good
874 until the next call (which would free the old value). Another fix
875 would be to just always malloc our answer, and let the caller free
876 it (that is best, because some day we may need to be reentrant).
878 The workaround is to put -f in inetd.conf which means that
879 get_homedir won't get called until after the switch in user ID.
881 The whole concept of a "home directory" on the server is pretty
882 iffy, although I suppose some people probably are relying on it for
883 .cvsrc and such, in the cases where it works. */
887 static char *home = NULL;
895 #ifdef SERVER_SUPPORT
898 (env = getenv ("HOME")) != NULL)
900 else if ((pw = (struct passwd *) getpwuid (getuid ()))
902 home = xstrdup (pw->pw_dir);
909 /* Compose a path to a file in the home directory. This is necessary because
910 * of different behavior on UNIX and VMS. See the notes in vms/filesubr.c.
912 * A more clean solution would be something more along the lines of a
913 * "join a directory to a filename" kind of thing which was not specific to
914 * the homedir. This should aid portability between UNIX, Mac, Windows, VMS,
915 * and possibly others. This is already handled by Perl - it might be
916 * interesting to see how much of the code was written in C since Perl is under
917 * the GPL and the Artistic license - we might be able to use it.
920 strcat_filename_onto_homedir (const char *dir, const char *file)
922 char *path = xmalloc (strlen (dir) + 1 + strlen(file) + 1);
923 sprintf (path, "%s/%s", dir, file);
927 /* See cvs.h for description. On unix this does nothing, because the
928 shell expands the wildcards. */
930 expand_wild (int argc, char **argv, int *pargc, char ***pargv)
933 if (size_overflow_p (xtimes (argc, sizeof (char *)))) {
936 error (0, 0, "expand_wild: too many arguments");
940 *pargv = xmalloc (xtimes (argc, sizeof (char *)));
941 for (i = 0; i < argc; ++i)
942 (*pargv)[i] = xstrdup (argv[i]);
947 #ifdef SERVER_SUPPORT
948 /* Case-insensitive string compare. I know that some systems
949 have such a routine, but I'm not sure I see any reasons for
950 dealing with the hair of figuring out whether they do (I haven't
951 looked into whether this is a performance bottleneck; I would guess
954 cvs_casecmp (const char *str1, const char *str2)
962 while ((pqdiff = tolower (*p) - tolower (*q)) == 0)
971 #endif /* SERVER_SUPPORT */