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. */
27 static int deep_remove_dir PROTO((const char *path));
30 * Copies "from" to "to".
42 (void) fprintf (stderr, "%s-> copy(%s,%s)\n",
43 CLIENT_SERVER_STR, from, to);
47 /* If the file to be copied is a link or a device, then just create
48 the new link or device appropriately. */
51 char *source = xreadlink (from);
59 #if defined(HAVE_MKNOD) && defined(HAVE_STRUCT_STAT_ST_RDEV)
60 if (stat (from, &sb) < 0)
61 error (1, errno, "cannot stat %s", from);
62 mknod (to, sb.st_mode, sb.st_rdev);
64 error (1, 0, "cannot copy device files on this system (%s)", from);
69 /* Not a link or a device... probably a regular file. */
70 if ((fdin = open (from, O_RDONLY)) < 0)
71 error (1, errno, "cannot open %s for copying", from);
72 if (fstat (fdin, &sb) < 0)
73 error (1, errno, "cannot fstat %s", from);
74 if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0)
75 error (1, errno, "cannot create %s for copying", to);
83 n = read (fdin, buf, sizeof(buf));
90 error (1, errno, "cannot read file %s for copying", from);
95 if (write(fdout, buf, n) != n) {
96 error (1, errno, "cannot write file %s for copying", to);
102 error (1, errno, "cannot fsync file %s after copying", to);
106 if (close (fdin) < 0)
107 error (0, errno, "cannot close %s", from);
108 if (close (fdout) < 0)
109 error (1, errno, "cannot close %s", to);
112 /* now, set the times for the copied file to match those of the original */
113 memset ((char *) &t, 0, sizeof (t));
114 t.actime = sb.st_atime;
115 t.modtime = sb.st_mtime;
116 (void) utime (to, &t);
119 /* FIXME-krp: these functions would benefit from caching the char * &
123 * Returns non-zero if the argument file is a directory, or is a symbolic
124 * link which points to a directory.
132 if (stat (file, &sb) < 0)
134 return (S_ISDIR (sb.st_mode));
138 * Returns non-zero if the argument file is a symbolic link.
147 if (CVS_LSTAT (file, &sb) < 0)
149 return (S_ISLNK (sb.st_mode));
156 * Returns non-zero if the argument file is a block or
157 * character special device.
165 if (CVS_LSTAT (file, &sb) < 0)
168 if (S_ISBLK (sb.st_mode))
172 if (S_ISCHR (sb.st_mode))
179 * Returns non-zero if the argument file exists.
185 return isaccessible(file, F_OK);
189 * Returns non-zero if the argument file is readable.
195 return isaccessible(file, R_OK);
199 * Returns non-zero if the argument file is writable.
205 return isaccessible(file, W_OK);
209 * Returns non-zero if the argument file is accessable according to
210 * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid
214 isaccessible (file, mode)
218 #ifdef SETXID_SUPPORT
225 if (stat(file, &sb) == -1)
231 if (uid == 0) /* superuser */
233 if (!(mode & X_OK) || (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
259 mask = sb.st_uid == uid ? umask : sb.st_gid == getegid() ? gmask : omask;
260 if ((sb.st_mode & mask) == mask)
265 return access(file, mode) == 0;
270 * Open a file and die if it fails
273 open_file (name, mode)
279 if ((fp = fopen (name, mode)) == NULL)
280 error (1, errno, "cannot open %s", name);
285 * Make a directory and die if it fails
288 make_directory (name)
293 if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode)))
294 error (0, 0, "%s already exists but is not a directory", name);
295 if (!noexec && mkdir (name, 0777) < 0)
296 error (1, errno, "cannot make directory %s", name);
300 * Make a path to the argument directory, printing a message if something
304 make_directories (name)
312 if (mkdir (name, 0777) == 0 || errno == EEXIST)
314 if (! existence_error (errno))
316 error (0, errno, "cannot make path to %s", name);
319 if ((cp = strrchr (name, '/')) == NULL)
322 make_directories (name);
326 (void) mkdir (name, 0777);
329 /* Create directory NAME if it does not already exist; fatal error for
330 other errors. Returns 0 if directory was created; 1 if it already
333 mkdir_if_needed (name)
336 if (mkdir (name, 0777) < 0)
338 int save_errno = errno;
339 if (save_errno != EEXIST && !isdir (name))
340 error (1, save_errno, "cannot make directory %s", name);
347 * Change the mode of a file, either adding write permissions, or removing
348 * all write permissions. Either change honors the current umask setting.
350 * Don't do anything if PreservePermissions is set to `yes'. This may
351 * have unexpected consequences for some uses of xchmod.
354 xchmod (fname, writable)
364 if (stat (fname, &sb) < 0)
367 error (0, errno, "cannot stat %s", fname);
371 (void) umask (oumask);
374 mode = sb.st_mode | (~oumask
375 & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0)
376 | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0)
377 | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0)));
381 mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask;
385 (void) fprintf (stderr, "%s-> chmod(%s,%o)\n",
386 CLIENT_SERVER_STR, fname,
387 (unsigned int) mode);
391 if (chmod (fname, mode) < 0)
392 error (0, errno, "cannot change mode of file %s", fname);
396 * Rename a file and die if it fails
399 rename_file (from, to)
404 (void) fprintf (stderr, "%s-> rename(%s,%s)\n",
405 CLIENT_SERVER_STR, from, to);
409 if (rename (from, to) < 0)
410 error (1, errno, "cannot rename file %s to %s", from, to);
414 * unlink a file, if possible.
421 (void) fprintf (stderr, "%s-> unlink_file(%s)\n",
422 CLIENT_SERVER_STR, f);
426 return (CVS_UNLINK (f));
430 * Unlink a file or dir, if possible. If it is a directory do a deep
431 * removal of all of the files in the directory. Return -1 on error
432 * (in which case errno is set).
441 #ifdef SERVER_SUPPORT
442 /* This is called by the server parent process in contexts where
443 it is not OK to send output (e.g. after we sent "ok" to the
448 (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", 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);
475 /* Remove a directory and everything it contains. Returns 0 for
476 * success, -1 for failure (in which case errno is set).
480 deep_remove_dir (path)
486 if (rmdir (path) != 0)
488 if (errno == ENOTEMPTY
490 /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
491 (it defines ENOTEMPTY and EEXIST to 17 but actually
493 || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87))
495 if ((dirp = CVS_OPENDIR (path)) == NULL)
496 /* If unable to open the directory return
502 while ((dp = CVS_READDIR (dirp)) != NULL)
506 if (strcmp (dp->d_name, ".") == 0 ||
507 strcmp (dp->d_name, "..") == 0)
510 buf = xmalloc (strlen (path) + strlen (dp->d_name) + 5);
511 sprintf (buf, "%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 */
556 /* Read NCHARS bytes from descriptor FD into BUF.
557 Return the number of characters successfully read.
558 The number returned is always NCHARS unless end-of-file or error. */
560 block_read (fd, buf, nchars)
570 nread = read (fd, bp, nchars);
571 if (nread == (size_t)-1)
585 } while (nchars != 0);
592 * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
593 * If FILE1 and FILE2 are special files, compare their salient characteristics
594 * (i.e. major/minor device numbers, links, etc.
602 struct stat sb1, sb2;
606 if (CVS_LSTAT (file1, &sb1) < 0)
607 error (1, errno, "cannot lstat %s", file1);
608 if (CVS_LSTAT (file2, &sb2) < 0)
609 error (1, errno, "cannot lstat %s", file2);
611 /* If FILE1 and FILE2 are not the same file type, they are unequal. */
612 if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT))
615 /* If FILE1 and FILE2 are symlinks, they are equal if they point to
618 if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
621 buf1 = xreadlink (file1);
622 buf2 = xreadlink (file2);
623 result = (strcmp (buf1, buf2) == 0);
630 /* If FILE1 and FILE2 are devices, they are equal if their device
632 if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
634 #ifdef HAVE_STRUCT_STAT_ST_RDEV
635 if (sb1.st_rdev == sb2.st_rdev)
640 error (1, 0, "cannot compare device files on this system (%s and %s)",
645 if ((fd1 = open (file1, O_RDONLY)) < 0)
646 error (1, errno, "cannot open file %s for comparing", file1);
647 if ((fd2 = open (file2, O_RDONLY)) < 0)
648 error (1, errno, "cannot open file %s for comparing", file2);
650 /* A generic file compare routine might compare st_dev & st_ino here
651 to see if the two files being compared are actually the same file.
652 But that won't happen in CVS, so we won't bother. */
654 if (sb1.st_size != sb2.st_size)
656 else if (sb1.st_size == 0)
660 /* FIXME: compute the optimal buffer size by computing the least
661 common multiple of the files st_blocks field */
662 size_t buf_size = 8 * 1024;
666 buf1 = xmalloc (buf_size);
667 buf2 = xmalloc (buf_size);
671 read1 = block_read (fd1, buf1, buf_size);
672 if (read1 == (size_t)-1)
673 error (1, errno, "cannot read file %s for comparing", file1);
675 read2 = block_read (fd2, buf2, buf_size);
676 if (read2 == (size_t)-1)
677 error (1, errno, "cannot read file %s for comparing", file2);
679 /* assert (read1 == read2); */
681 ret = memcmp(buf1, buf2, read1);
682 } while (ret == 0 && read1 == buf_size);
693 /* Generate a unique temporary filename. Returns a pointer to a newly
694 * malloc'd string containing the name. Returns successfully or not at
697 * THIS FUNCTION IS DEPRECATED!!! USE cvs_temp_file INSTEAD!!!
699 * and yes, I know about the way the rcs commands use temp files. I think
700 * they should be converted too but I don't have time to look into it right
709 fp = cvs_temp_file (&fn);
711 error (1, errno, "Failed to create temporary file");
712 if (fclose (fp) == EOF)
713 error (0, errno, "Failed to close temporary file %s", fn);
717 /* Generate a unique temporary filename and return an open file stream
718 * to the truncated file by that name
721 * filename where to place the pointer to the newly allocated file
725 * filename dereferenced, will point to the newly allocated file
726 * name string. This value is undefined if the function
730 * An open file pointer to a read/write mode empty temporary file with the
731 * unique file name or NULL on failure.
734 * on error, errno will be set to some value either by CVS_FOPEN or
735 * whatever system function is called to generate the temporary file name
737 /* There are at least four functions for generating temporary
738 * filenames. We use mkstemp (BSD 4.3) if possible, else tempnam (SVID 3),
739 * else mktemp (BSD 4.3), and as last resort tmpnam (POSIX). Reason is that
740 * mkstemp, tempnam, and mktemp both allow to specify the directory in which
741 * the temporary file will be created.
743 * And the _correct_ way to use the deprecated functions probably involves
744 * opening file descriptors using O_EXCL & O_CREAT and even doing the annoying
745 * NFS locking thing, but until I hear of more problems, I'm not going to
748 FILE *cvs_temp_file (filename)
754 /* FIXME - I'd like to be returning NULL here in noexec mode, but I think
755 * some of the rcs & diff functions which rely on a temp file run in
759 assert (filename != NULL);
766 fn = xmalloc (strlen (Tmpdir) + 11);
767 sprintf (fn, "%s/%s", Tmpdir, "cvsXXXXXX" );
770 /* a NULL return will be interpreted by callers as an error and
771 * errno should still be set
773 if (fd == -1) fp = NULL;
774 else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL)
776 /* Attempt to close and unlink the file since mkstemp returned
777 * sucessfully and we believe it's been created and opened.
779 int save_errno = errno;
781 error (0, errno, "Failed to close temporary file %s", fn);
783 error (0, errno, "Failed to unlink temporary file %s", fn);
787 if (fp == NULL) free (fn);
788 /* mkstemp is defined to open mode 0600 using glibc 2.0.7+ */
789 /* FIXME - configure can probably tell us which version of glibc we are
790 * linking to and not chmod for 2.0.7+
792 else chmod (fn, 0600);
798 /* tempnam has been deprecated due to under-specification */
800 fn = tempnam (Tmpdir, "cvs");
801 if (fn == NULL) fp = NULL;
802 else if ((fp = CVS_FOPEN (fn, "w+")) == NULL) free (fn);
803 else chmod (fn, 0600);
805 /* tempnam returns a pointer to a newly malloc'd string, so there's
806 * no need for a xstrdup
811 /* mktemp has been deprecated due to the BSD 4.3 specification specifying
812 * that XXXXXX will be replaced by a PID and a letter, creating only 26
813 * possibilities, a security risk, and a race condition.
819 ifn = xmalloc (strlen (Tmpdir) + 11);
820 sprintf (ifn, "%s/%s", Tmpdir, "cvsXXXXXX" );
823 if (fn == NULL) fp = NULL;
824 else fp = CVS_FOPEN (fn, "w+");
826 if (fp == NULL) free (ifn);
827 else chmod (fn, 0600);
831 #else /* use tmpnam if all else fails */
833 /* tmpnam is deprecated */
836 char ifn[L_tmpnam + 1];
840 if (fn == NULL) fp = NULL;
841 else if ((fp = CVS_FOPEN (ifn, "w+")) != NULL)
859 * xreadlink ( const char *link )
861 * Like the X/OPEN and 4.4BSD readlink() function, but allocates and returns
865 * link The original path.
868 * The resolution of the final symbolic link in the path.
871 * This function exits with a fatal error if it fails to read the link for
882 /* Get the name of the file to which `from' is linked.
883 FIXME: what portability issues arise here? Are readlink &
884 ENAMETOOLONG defined on all systems? -twp */
887 file = xrealloc (file, buflen);
889 linklen = readlink (link, file, buflen - 1);
892 while (linklen == -1 && errno == ENAMETOOLONG);
895 error (1, errno, "cannot readlink %s", link);
896 file[linklen] = '\0';
900 #endif /* HAVE_READLINK */
905 * xresolvepath ( const char *path )
907 * Like xreadlink(), but resolve all links in a path.
910 * path The original path.
913 * The path with any symbolic links expanded.
916 * This function exits with a fatal error if it fails to read the link for
920 xresolvepath ( path )
926 assert ( isdir ( path ) );
928 /* FIXME - If HAVE_READLINK is defined, we should probably walk the path
929 * bit by bit calling xreadlink().
933 if ( CVS_CHDIR ( path ) < 0)
934 error ( 1, errno, "cannot chdir to %s", path );
935 if ( ( hardpath = xgetwd() ) == NULL )
936 error (1, errno, "cannot getwd in %s", path);
937 if ( CVS_CHDIR ( owd ) < 0)
938 error ( 1, errno, "cannot chdir to %s", owd );
945 /* Return a pointer into PATH's last component. */
947 last_component (path)
950 const char *last = strrchr (path, '/');
952 if (last && (last != path))
958 /* Return the home directory. Returns a pointer to storage
959 managed by this function or its callees (currently getenv).
960 This function will return the same thing every time it is
961 called. Returns NULL if there is no home directory.
963 Note that for a pserver server, this may return root's home
964 directory. What typically happens is that upon being started from
965 inetd, before switching users, the code in cvsrc.c calls
966 get_homedir which remembers root's home directory in the static
967 variable. Then the switch happens and get_homedir might return a
968 directory that we don't even have read or execute permissions for
969 (which is bad, when various parts of CVS try to read there). One
970 fix would be to make the value returned by get_homedir only good
971 until the next call (which would free the old value). Another fix
972 would be to just always malloc our answer, and let the caller free
973 it (that is best, because some day we may need to be reentrant).
975 The workaround is to put -f in inetd.conf which means that
976 get_homedir won't get called until after the switch in user ID.
978 The whole concept of a "home directory" on the server is pretty
979 iffy, although I suppose some people probably are relying on it for
980 .cvsrc and such, in the cases where it works. */
984 static char *home = NULL;
992 #ifdef SERVER_SUPPORT
995 (env = getenv ("HOME")) != NULL)
997 else if ((pw = (struct passwd *) getpwuid (getuid ()))
999 home = xstrdup (pw->pw_dir);
1006 /* Compose a path to a file in the home directory. This is necessary because
1007 * of different behavior on UNIX and VMS. See the notes in vms/filesubr.c.
1009 * A more clean solution would be something more along the lines of a
1010 * "join a directory to a filename" kind of thing which was not specific to
1011 * the homedir. This should aid portability between UNIX, Mac, Windows, VMS,
1012 * and possibly others. This is already handled by Perl - it might be
1013 * interesting to see how much of the code was written in C since Perl is under
1014 * the GPL and the Artistic license - we might be able to use it.
1017 strcat_filename_onto_homedir (dir, file)
1021 char *path = xmalloc (strlen (dir) + 1 + strlen(file) + 1);
1022 sprintf (path, "%s/%s", dir, file);
1026 /* See cvs.h for description. On unix this does nothing, because the
1027 shell expands the wildcards. */
1029 expand_wild (argc, argv, pargc, pargv)
1036 if (size_overflow_p (xtimes (argc, sizeof (char *)))) {
1039 error (0, 0, "expand_wild: too many arguments");
1043 *pargv = xmalloc (xtimes (argc, sizeof (char *)));
1044 for (i = 0; i < argc; ++i)
1045 (*pargv)[i] = xstrdup (argv[i]);
1050 #ifdef SERVER_SUPPORT
1051 /* Case-insensitive string compare. I know that some systems
1052 have such a routine, but I'm not sure I see any reasons for
1053 dealing with the hair of figuring out whether they do (I haven't
1054 looked into whether this is a performance bottleneck; I would guess
1057 cvs_casecmp (str1, str2)
1067 while ((pqdiff = tolower (*p) - tolower (*q)) == 0)
1076 #endif /* SERVER_SUPPORT */