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 ( 1, "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 * Open a file and die if it fails
271 open_file (const char *name, const char *mode)
275 if ((fp = fopen (name, mode)) == NULL)
276 error (1, errno, "cannot open %s", name);
281 * Make a directory and die if it fails
284 make_directory (const char *name)
288 if( CVS_STAT( name, &sb ) == 0 && ( !S_ISDIR( sb.st_mode ) ) )
289 error (0, 0, "%s already exists but is not a directory", name);
290 if (!noexec && mkdir (name, 0777) < 0)
291 error (1, errno, "cannot make directory %s", name);
295 * Make a path to the argument directory, printing a message if something
299 make_directories (const char *name)
306 if (mkdir (name, 0777) == 0 || errno == EEXIST)
308 if (! existence_error (errno))
310 error (0, errno, "cannot make path to %s", name);
313 if ((cp = strrchr (name, '/')) == NULL)
316 make_directories (name);
320 (void) mkdir (name, 0777);
323 /* Create directory NAME if it does not already exist; fatal error for
324 other errors. Returns 0 if directory was created; 1 if it already
327 mkdir_if_needed (const char *name)
329 if (mkdir (name, 0777) < 0)
331 int save_errno = errno;
332 if (save_errno != EEXIST && !isdir (name))
333 error (1, save_errno, "cannot make directory %s", name);
340 * Change the mode of a file, either adding write permissions, or removing
341 * all write permissions. Either change honors the current umask setting.
343 * Don't do anything if PreservePermissions is set to `yes'. This may
344 * have unexpected consequences for some uses of xchmod.
347 xchmod (const char *fname, int writable)
352 #ifdef PRESERVE_PERMISSIONS_SUPPORT
353 if (config->preserve_perms)
355 #endif /* PRESERVE_PERMISSIONS_SUPPORT */
357 if( CVS_STAT( fname, &sb ) < 0 )
360 error (0, errno, "cannot stat %s", fname);
364 (void) umask (oumask);
367 mode = sb.st_mode | (~oumask
368 & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0)
369 | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0)
370 | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0)));
374 mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask;
377 TRACE ( 1, "chmod(%s,%o)", fname, (unsigned int) mode );
382 if (chmod (fname, mode) < 0)
383 error (0, errno, "cannot change mode of file %s", fname);
387 * Rename a file and die if it fails
390 rename_file (const char *from, const char *to)
392 TRACE ( 1, "rename(%s,%s)", from, to );
397 if (rename (from, to) < 0)
398 error (1, errno, "cannot rename file %s to %s", from, to);
402 * unlink a file, if possible.
405 unlink_file (const char *f)
407 TRACE ( 1, "unlink_file(%s)", f );
412 return (CVS_UNLINK (f));
418 * Unlink a file or dir, if possible. If it is a directory do a deep
419 * removal of all of the files in the directory. Return -1 on error
420 * (in which case errno is set).
423 unlink_file_dir (const char *f)
427 #ifdef SERVER_SUPPORT
428 /* This is called by the server parent process in contexts where
429 it is not OK to send output (e.g. after we sent "ok" to the
433 TRACE (TRACE_FUNCTION, "unlink_file_dir(%s)", f);
438 /* For at least some unices, if root tries to unlink() a directory,
439 instead of doing something rational like returning EISDIR,
440 the system will gleefully go ahead and corrupt the filesystem.
441 So we first call stat() to see if it is OK to call unlink(). This
442 doesn't quite work--if someone creates a directory between the
443 call to stat() and the call to unlink(), we'll still corrupt
444 the filesystem. Where is the Unix Haters Handbook when you need
446 if( CVS_STAT( f, &sb ) < 0 )
448 if (existence_error (errno))
450 /* The file or directory doesn't exist anyhow. */
454 else if (S_ISDIR (sb.st_mode))
455 return deep_remove_dir (f);
457 return CVS_UNLINK (f);
462 /* Remove a directory and everything it contains. Returns 0 for
463 * success, -1 for failure (in which case errno is set).
467 deep_remove_dir (const char *path)
472 if (rmdir (path) != 0)
474 if (errno == ENOTEMPTY
476 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
477 (it defines ENOTEMPTY and EEXIST to 17 but actually
479 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87))
481 if ((dirp = CVS_OPENDIR (path)) == NULL)
482 /* If unable to open the directory return
488 while ((dp = CVS_READDIR (dirp)) != NULL)
492 if (strcmp (dp->d_name, ".") == 0 ||
493 strcmp (dp->d_name, "..") == 0)
496 buf = xmalloc (strlen (path) + strlen (dp->d_name) + 5);
497 sprintf (buf, "%s/%s", path, dp->d_name);
499 /* See comment in unlink_file_dir explanation of why we use
500 isdir instead of just calling unlink and checking the
504 if (deep_remove_dir (buf))
513 if (CVS_UNLINK (buf) != 0)
526 int save_errno = errno;
538 /* Was able to remove the directory return 0 */
544 /* Read NCHARS bytes from descriptor FD into BUF.
545 Return the number of characters successfully read.
546 The number returned is always NCHARS unless end-of-file or error. */
548 block_read (int fd, char *buf, size_t nchars)
555 nread = read (fd, bp, nchars);
556 if (nread == (size_t)-1)
570 } while (nchars != 0);
577 * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
578 * If FILE1 and FILE2 are special files, compare their salient characteristics
579 * (i.e. major/minor device numbers, links, etc.
582 xcmp (const char *file1, const char *file2)
585 struct stat sb1, sb2;
589 if (CVS_LSTAT (file1, &sb1) < 0)
590 error (1, errno, "cannot lstat %s", file1);
591 if (CVS_LSTAT (file2, &sb2) < 0)
592 error (1, errno, "cannot lstat %s", file2);
594 /* If FILE1 and FILE2 are not the same file type, they are unequal. */
595 if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT))
598 /* If FILE1 and FILE2 are symlinks, they are equal if they point to
601 if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
604 buf1 = Xreadlink (file1, sb1.st_size);
605 buf2 = Xreadlink (file2, sb2.st_size);
606 result = (strcmp (buf1, buf2) == 0);
613 /* If FILE1 and FILE2 are devices, they are equal if their device
615 if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
617 #ifdef HAVE_STRUCT_STAT_ST_RDEV
618 if (sb1.st_rdev == sb2.st_rdev)
623 error (1, 0, "cannot compare device files on this system (%s and %s)",
628 if ((fd1 = open (file1, O_RDONLY)) < 0)
629 error (1, errno, "cannot open file %s for comparing", file1);
630 if ((fd2 = open (file2, O_RDONLY)) < 0)
631 error (1, errno, "cannot open file %s for comparing", file2);
633 /* A generic file compare routine might compare st_dev & st_ino here
634 to see if the two files being compared are actually the same file.
635 But that won't happen in CVS, so we won't bother. */
637 if (sb1.st_size != sb2.st_size)
639 else if (sb1.st_size == 0)
643 /* FIXME: compute the optimal buffer size by computing the least
644 common multiple of the files st_blocks field */
645 size_t buf_size = 8 * 1024;
649 buf1 = xmalloc (buf_size);
650 buf2 = xmalloc (buf_size);
654 read1 = block_read (fd1, buf1, buf_size);
655 if (read1 == (size_t)-1)
656 error (1, errno, "cannot read file %s for comparing", file1);
658 read2 = block_read (fd2, buf2, buf_size);
659 if (read2 == (size_t)-1)
660 error (1, errno, "cannot read file %s for comparing", file2);
662 /* assert (read1 == read2); */
664 ret = memcmp(buf1, buf2, read1);
665 } while (ret == 0 && read1 == buf_size);
676 /* Generate a unique temporary filename. Returns a pointer to a newly
677 * malloc'd string containing the name. Returns successfully or not at
680 * THIS FUNCTION IS DEPRECATED!!! USE cvs_temp_file INSTEAD!!!
682 * and yes, I know about the way the rcs commands use temp files. I think
683 * they should be converted too but I don't have time to look into it right
692 fp = cvs_temp_file (&fn);
694 error (1, errno, "Failed to create temporary file");
695 if (fclose (fp) == EOF)
696 error (0, errno, "Failed to close temporary file %s", fn);
700 /* Generate a unique temporary filename and return an open file stream
701 * to the truncated file by that name
704 * filename where to place the pointer to the newly allocated file
708 * filename dereferenced, will point to the newly allocated file
709 * name string. This value is undefined if the function
713 * An open file pointer to a read/write mode empty temporary file with the
714 * unique file name or NULL on failure.
717 * On error, errno will be set to some value either by CVS_FOPEN or
718 * whatever system function is called to generate the temporary file name.
719 * The value of filename is undefined on error.
721 FILE *cvs_temp_file (char **filename)
727 /* FIXME - I'd like to be returning NULL here in noexec mode, but I think
728 * some of the rcs & diff functions which rely on a temp file run in
732 assert (filename != NULL);
734 fn = xmalloc (strlen (Tmpdir) + 11);
735 sprintf (fn, "%s/%s", Tmpdir, "cvsXXXXXX" );
738 /* a NULL return will be interpreted by callers as an error and
739 * errno should still be set
741 if (fd == -1) fp = NULL;
742 else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL)
744 /* Attempt to close and unlink the file since mkstemp returned
745 * sucessfully and we believe it's been created and opened.
747 int save_errno = errno;
749 error (0, errno, "Failed to close temporary file %s", fn);
751 error (0, errno, "Failed to unlink temporary file %s", fn);
755 if (fp == NULL) free (fn);
757 /* mkstemp is defined to open mode 0600 using glibc 2.0.7+. There used
758 * to be a complicated #ifdef checking the library versions here and then
759 * a chmod 0600 on the temp file for versions of glibc less than 2.1. This
760 * is rather a special case, leaves a race condition open regardless, and
761 * one could hope that sysadmins have read the relevant security
762 * announcements and upgraded by now to a version with a fix committed in
765 * If it is decided at some point that old, buggy versions of glibc should
766 * still be catered to, a umask of 0600 should be set before file creation
767 * instead then reset after file creation since this would avoid the race
768 * condition that the chmod left open to exploitation.
778 * xresolvepath (const char *path)
780 * Like xreadlink(), but resolve all links in a path.
783 * path The original path.
786 * The path with any symbolic links expanded.
789 * This function exits with a fatal error if it fails to read the link for
793 xresolvepath (const char *path)
796 struct saved_cwd owd;
798 assert (isdir (path));
800 /* FIXME - If HAVE_READLINK is defined, we should probably walk the path
801 * bit by bit calling xreadlink().
805 error (1, 0, "failed to save current working directory");
806 if (CVS_CHDIR (path ) < 0)
807 error (1, errno, "cannot chdir to %s", path);
808 if ((hardpath = xgetcwd ()) == NULL)
809 error (1, errno, "cannot getwd in %s", path);
810 if (restore_cwd (&owd) < 0)
811 error (1, 0, "failed to restore working directory");
817 /* Return a pointer into PATH's last component. */
819 last_component (const char *path)
821 const char *last = strrchr (path, '/');
823 if (last && (last != path))
831 /* Return the home directory. Returns a pointer to storage
832 managed by this function or its callees (currently getenv).
833 This function will return the same thing every time it is
834 called. Returns NULL if there is no home directory.
836 Note that for a pserver server, this may return root's home
837 directory. What typically happens is that upon being started from
838 inetd, before switching users, the code in cvsrc.c calls
839 get_homedir which remembers root's home directory in the static
840 variable. Then the switch happens and get_homedir might return a
841 directory that we don't even have read or execute permissions for
842 (which is bad, when various parts of CVS try to read there). One
843 fix would be to make the value returned by get_homedir only good
844 until the next call (which would free the old value). Another fix
845 would be to just always malloc our answer, and let the caller free
846 it (that is best, because some day we may need to be reentrant).
848 The workaround is to put -f in inetd.conf which means that
849 get_homedir won't get called until after the switch in user ID.
851 The whole concept of a "home directory" on the server is pretty
852 iffy, although I suppose some people probably are relying on it for
853 .cvsrc and such, in the cases where it works. */
857 static char *home = NULL;
865 #ifdef SERVER_SUPPORT
868 (env = getenv ("HOME")) != NULL)
870 else if ((pw = (struct passwd *) getpwuid (getuid ()))
872 home = xstrdup (pw->pw_dir);
879 /* Compose a path to a file in the home directory. This is necessary because
880 * of different behavior on UNIX and VMS. See the notes in vms/filesubr.c.
882 * A more clean solution would be something more along the lines of a
883 * "join a directory to a filename" kind of thing which was not specific to
884 * the homedir. This should aid portability between UNIX, Mac, Windows, VMS,
885 * and possibly others. This is already handled by Perl - it might be
886 * interesting to see how much of the code was written in C since Perl is under
887 * the GPL and the Artistic license - we might be able to use it.
890 strcat_filename_onto_homedir (const char *dir, const char *file)
892 char *path = xmalloc (strlen (dir) + 1 + strlen(file) + 1);
893 sprintf (path, "%s/%s", dir, file);
897 /* See cvs.h for description. On unix this does nothing, because the
898 shell expands the wildcards. */
900 expand_wild (int argc, char **argv, int *pargc, char ***pargv)
903 if (size_overflow_p (xtimes (argc, sizeof (char *)))) {
906 error (0, 0, "expand_wild: too many arguments");
910 *pargv = xmalloc (xtimes (argc, sizeof (char *)));
911 for (i = 0; i < argc; ++i)
912 (*pargv)[i] = xstrdup (argv[i]);