diff options
Diffstat (limited to 'gnu/usr.bin/cvs/macintosh/filesubr.c')
-rw-r--r-- | gnu/usr.bin/cvs/macintosh/filesubr.c | 707 |
1 files changed, 0 insertions, 707 deletions
diff --git a/gnu/usr.bin/cvs/macintosh/filesubr.c b/gnu/usr.bin/cvs/macintosh/filesubr.c deleted file mode 100644 index 5ec82998b69..00000000000 --- a/gnu/usr.bin/cvs/macintosh/filesubr.c +++ /dev/null @@ -1,707 +0,0 @@ -/* filesubr.c --- subroutines for dealing with files - Jim Blandy <jimb@cyclic.com> - - This file is part of GNU CVS. - - GNU CVS is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* These functions were moved out of subr.c because they need different - definitions under operating systems (like, say, Windows NT) with different - file system semantics. */ - -#include "mac_config.h" -#include "cvs.h" - -/* - * I don't know of a convenient way to test this at configure time, or else - * I'd certainly do it there. - */ -#if defined(NeXT) -#define LOSING_TMPNAM_FUNCTION -#endif - -static int deep_remove_dir PROTO((const char *path)); - -/* - * Copies "from" to "to". - */ -void -copy_file (from, to) - const char *from; - const char *to; -{ - struct stat sb; - struct utimbuf t; - int fdin, fdout; - - if (trace) -#ifdef SERVER_SUPPORT - (void) fprintf (stderr, "%c-> copy(%s,%s)\n", - (server_active) ? 'S' : ' ', from, to); -#else - (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to); -#endif - if (noexec) - return; - - if ((fdin = CVS_OPEN (from, O_RDONLY)) < 0) - error (1, errno, "cannot open %s for copying", from); - if (fstat (fdin, &sb) < 0) - error (1, errno, "cannot fstat %s", from); - if ((fdout = CVS_CREAT (to, (int) sb.st_mode & 07777)) < 0) - error (1, errno, "cannot create %s for copying", to); - if (sb.st_size > 0) - { - char buf[BUFSIZ]; - int n; - - for (;;) - { - n = read (fdin, buf, sizeof(buf)); - if (n == -1) - { -#ifdef EINTR - if (errno == EINTR) - continue; -#endif - error (1, errno, "cannot read file %s for copying", from); - } - else if (n == 0) - break; - - if (write(fdout, buf, n) != n) { - error (1, errno, "cannot write file %s for copying", to); - } - } - -#ifdef HAVE_FSYNC - if (fsync (fdout)) - error (1, errno, "cannot fsync file %s after copying", to); -#endif - } - - if (close (fdin) < 0) - error (0, errno, "cannot close %s", from); - if (close (fdout) < 0) - error (1, errno, "cannot close %s", to); - - /* now, set the times for the copied file to match those of the original */ - memset ((char *) &t, 0, sizeof (t)); - t.actime = sb.st_atime; - t.modtime = sb.st_mtime; - (void) utime (to, &t); -} - -/* FIXME-krp: these functions would benefit from caching the char * & - stat buf. */ - -/* - * Returns non-zero if the argument file is a directory, or is a symbolic - * link which points to a directory. - */ -int -isdir (file) - const char *file; -{ - struct stat sb; - - if ( CVS_STAT (file, &sb) < 0) - return (0); - return (S_ISDIR (sb.st_mode)); -} - -/* - * Returns non-zero if the argument file is a symbolic link. - */ -int -islink (file) - const char *file; -{ -#ifdef S_ISLNK - struct stat sb; - - if (lstat (file, &sb) < 0) - return (0); - return (S_ISLNK (sb.st_mode)); -#else - return (0); -#endif -} - -/* - * Returns non-zero if the argument file exists. - */ -int -isfile (file) - const char *file; -{ - return isaccessible(file, F_OK); -} - -/* - * Returns non-zero if the argument file is readable. - */ -int -isreadable (file) - const char *file; -{ - return isaccessible(file, R_OK); -} - -/* - * Returns non-zero if the argument file is writable. - */ -int -iswritable (file) - const char *file; -{ - return isaccessible(file, W_OK); -} - -/* - * Returns non-zero if the argument file is accessable according to - * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid - * bits set. - */ -int -isaccessible (file, mode) - const char *file; - const int mode; -{ -#ifdef SETXID_SUPPORT - struct stat sb; - int umask = 0; - int gmask = 0; - int omask = 0; - int uid; - - if ( CVS_STAT (file, &sb) == -1) - return 0; - if (mode == F_OK) - return 1; - - uid = geteuid(); - if (uid == 0) /* superuser */ - { - if (mode & X_OK) - return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH); - else - return 1; - } - - if (mode & R_OK) - { - umask |= S_IRUSR; - gmask |= S_IRGRP; - omask |= S_IROTH; - } - if (mode & W_OK) - { - umask |= S_IWUSR; - gmask |= S_IWGRP; - omask |= S_IWOTH; - } - if (mode & X_OK) - { - umask |= S_IXUSR; - gmask |= S_IXGRP; - omask |= S_IXOTH; - } - - if (sb.st_uid == uid) - return (sb.st_mode & umask) == umask; - else if (sb.st_gid == getegid()) - return (sb.st_mode & gmask) == gmask; - else - return (sb.st_mode & omask) == omask; -#else - return CVS_ACCESS (file, mode) == 0; -#endif -} - -/* - * Open a file and die if it fails - */ -FILE * -open_file (name, mode) - const char *name; - const char *mode; -{ - FILE *fp; - - if ((fp = CVS_FOPEN (name, mode)) == NULL) - error (1, errno, "cannot open %s", name); - return (fp); -} - -/* - * Make a directory and die if it fails - */ -void -make_directory (name) - const char *name; -{ - struct stat sb; - - if ( CVS_STAT (name, &sb) == 0 && (!S_ISDIR (sb.st_mode))) - error (0, 0, "%s already exists but is not a directory", name); - if (!noexec && CVS_MKDIR (name, 0777) < 0) - error (1, errno, "cannot make directory %s", name); -} - -/* - * Make a path to the argument directory, printing a message if something - * goes wrong. - */ -void -make_directories (name) - const char *name; -{ - char *cp; - - if (noexec) - return; - - if ( CVS_MKDIR (name, 0777) == 0 || errno == EEXIST) - return; - if (! existence_error (errno)) - { - error (0, errno, "cannot make path to %s", name); - return; - } - if ((cp = strrchr (name, '/')) == NULL) - return; - *cp = '\0'; - make_directories (name); - *cp++ = '/'; - if (*cp == '\0') - return; - (void) CVS_MKDIR (name, 0777); -} - -/* Create directory NAME if it does not already exist; fatal error for - other errors. Returns 0 if directory was created; 1 if it already - existed. */ -int -mkdir_if_needed (name) - char *name; -{ - if (CVS_MKDIR (name, 0777) < 0) - { - if (errno != EEXIST -#ifdef EACCESS - /* This was copied over from the OS/2 code; I would guess it - isn't needed here but that has not been verified. */ - && errno != EACCESS -#endif - ) - error (1, errno, "cannot make directory %s", name); - return 1; - } - return 0; -} - -/* - * Change the mode of a file, either adding write permissions, or removing - * all write permissions. Either change honors the current umask setting. - */ -void -xchmod (fname, writable) - char *fname; - int writable; -{ - struct stat sb; - mode_t mode, oumask; - - if ( CVS_STAT (fname, &sb) < 0) - { - if (!noexec) - error (0, errno, "cannot stat %s", fname); - return; - } - oumask = umask (0); - (void) umask (oumask); - if (writable) - { - mode = sb.st_mode | (~oumask - & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0) - | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0) - | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0))); - } - else - { - mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask; - } - - if (trace) -#ifdef SERVER_SUPPORT - (void) fprintf (stderr, "%c-> chmod(%s,%o)\n", - (server_active) ? 'S' : ' ', fname, - (unsigned int) mode); -#else - (void) fprintf (stderr, "-> chmod(%s,%o)\n", fname, - (unsigned int) mode); -#endif - if (noexec) - return; - - if (chmod (fname, mode) < 0) - error (0, errno, "cannot change mode of file %s", fname); -} - -/* - * Rename a file and die if it fails - */ -void -rename_file (from, to) - const char *from; - const char *to; -{ - if (trace) -#ifdef SERVER_SUPPORT - (void) fprintf (stderr, "%c-> rename(%s,%s)\n", - (server_active) ? 'S' : ' ', from, to); -#else - (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to); -#endif - if (noexec) - return; - - if ( CVS_RENAME (from, to) < 0) - error (1, errno, "cannot rename file %s to %s", from, to); -} - -/* - * link a file, if possible. Warning: the Windows NT version of this - * function just copies the file, so only use this function in ways - * that can deal with either a link or a copy. - */ -int -link_file (from, to) - const char *from; - const char *to; -{ - if (trace) -#ifdef SERVER_SUPPORT - (void) fprintf (stderr, "%c-> link(%s,%s)\n", - (server_active) ? 'S' : ' ', from, to); -#else - (void) fprintf (stderr, "-> link(%s,%s)\n", from, to); -#endif - if (noexec) - return (0); - -#ifdef macintosh - return (symlink ( (char *)macos_fixpath(from), (char *)macos_fixpath(to))); -#else - return (link (from, to)); -#endif -} - -/* - * unlink a file, if possible. - */ -int -unlink_file (f) - const char *f; -{ - if (trace) -#ifdef SERVER_SUPPORT - (void) fprintf (stderr, "%c-> unlink(%s)\n", - (server_active) ? 'S' : ' ', f); -#else - (void) fprintf (stderr, "-> unlink(%s)\n", f); -#endif - if (noexec) - return (0); - - return ( CVS_UNLINK (f)); -} - -/* - * Unlink a file or dir, if possible. If it is a directory do a deep - * removal of all of the files in the directory. Return -1 on error - * (in which case errno is set). - */ -int -unlink_file_dir (f) - const char *f; -{ - if (trace) -#ifdef SERVER_SUPPORT - (void) fprintf (stderr, "%c-> unlink_file_dir(%s)\n", - (server_active) ? 'S' : ' ', f); -#else - (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f); -#endif - if (noexec) - return (0); - - /* For at least some unices, if root tries to unlink() a directory, - instead of doing something rational like returning EISDIR, - the system will gleefully go ahead and corrupt the filesystem. - So we first call isdir() to see if it is OK to call unlink(). This - doesn't quite work--if someone creates a directory between the - call to isdir() and the call to unlink(), we'll still corrupt - the filesystem. Where is the Unix Haters Handbook when you need - it? */ - if (isdir(f)) - return deep_remove_dir(f); - else - { - if ( CVS_UNLINK (f) != 0) - return -1; - } - /* We were able to remove the file from the disk */ - return 0; -} - -/* Remove a directory and everything it contains. Returns 0 for - * success, -1 for failure (in which case errno is set). - */ - -static int -deep_remove_dir (path) - const char *path; -{ - DIR *dirp; - struct dirent *dp; - char buf[PATH_MAX]; - - if (CVS_RMDIR (path) != 0 && (errno == ENOTEMPTY || errno == EEXIST)) - { - if ((dirp = CVS_OPENDIR (path)) == NULL) - /* If unable to open the directory return - * an error - */ - return -1; - - while ((dp = readdir (dirp)) != NULL) - { - if (strcmp (dp->d_name, ".") == 0 || - strcmp (dp->d_name, "..") == 0) - continue; - - sprintf (buf, "%s/%s", path, dp->d_name); - - /* See comment in unlink_file_dir explanation of why we use - isdir instead of just calling unlink and checking the - status. */ - if (isdir(buf)) - { - if (deep_remove_dir(buf)) - { - closedir(dirp); - return -1; - } - } - else - { - if (CVS_UNLINK (buf) != 0) - { - closedir(dirp); - return -1; - } - } - } - closedir (dirp); - return CVS_RMDIR (path); - } - - /* Was able to remove the directory return 0 */ - return 0; -} - -/* Read NCHARS bytes from descriptor FD into BUF. - Return the number of characters successfully read. - The number returned is always NCHARS unless end-of-file or error. */ -static size_t -block_read (fd, buf, nchars) - int fd; - char *buf; - size_t nchars; -{ - char *bp = buf; - size_t nread; - - do - { - nread = read (fd, bp, nchars); - if (nread == (size_t)-1) - { -#ifdef EINTR - if (errno == EINTR) - continue; -#endif - return (size_t)-1; - } - - if (nread == 0) - break; - - bp += nread; - nchars -= nread; - } while (nchars != 0); - - return bp - buf; -} - - -/* - * Compare "file1" to "file2". Return non-zero if they don't compare exactly. - */ -int -xcmp (file1, file2) - const char *file1; - const char *file2; -{ - char *buf1, *buf2; - struct stat sb1, sb2; - int fd1, fd2; - int ret; - - if ((fd1 = CVS_OPEN (file1, O_RDONLY)) < 0) - error (1, errno, "cannot open file %s for comparing", file1); - if ((fd2 = CVS_OPEN (file2, O_RDONLY)) < 0) - error (1, errno, "cannot open file %s for comparing", file2); - if (fstat (fd1, &sb1) < 0) - error (1, errno, "cannot fstat %s", file1); - if (fstat (fd2, &sb2) < 0) - error (1, errno, "cannot fstat %s", file2); - - /* A generic file compare routine might compare st_dev & st_ino here - to see if the two files being compared are actually the same file. - But that won't happen in CVS, so we won't bother. */ - - if (sb1.st_size != sb2.st_size) - ret = 1; - else if (sb1.st_size == 0) - ret = 0; - else - { - /* FIXME: compute the optimal buffer size by computing the least - common multiple of the files st_blocks field */ - size_t buf_size = 8 * 1024; - size_t read1; - size_t read2; - - buf1 = xmalloc (buf_size); - buf2 = xmalloc (buf_size); - - do - { - read1 = block_read (fd1, buf1, buf_size); - if (read1 == (size_t)-1) - error (1, errno, "cannot read file %s for comparing", file1); - - read2 = block_read (fd2, buf2, buf_size); - if (read2 == (size_t)-1) - error (1, errno, "cannot read file %s for comparing", file2); - - /* assert (read1 == read2); */ - - ret = memcmp(buf1, buf2, read1); - } while (ret == 0 && read1 == buf_size); - - free (buf1); - free (buf2); - } - - (void) close (fd1); - (void) close (fd2); - return (ret); -} - -/* Just in case this implementation does not define this. */ -#ifndef L_tmpnam -#define L_tmpnam 50 -#endif - -#ifdef LOSING_TMPNAM_FUNCTION -char * -cvs_temp_name () -{ - char value[L_tmpnam + 1]; - - /* FIXME: Should be using TMPDIR. */ - strcpy (value, "/tmp/cvsXXXXXX"); - mktemp (value); - return xstrdup (value); -} -#else -/* Generate a unique temporary filename. Returns a pointer to a newly - malloc'd string containing the name. Returns successfully or not at - all. */ -char * -cvs_temp_name () -{ - char value[L_tmpnam + 1]; - char *retval; - - /* FIXME: should be using TMPDIR, perhaps by using tempnam on systems - which have it. */ - retval = tmpnam (value); - if (retval == NULL) - error (1, errno, "cannot generate temporary filename"); - return xstrdup (retval); -} -#endif - -/* Return non-zero iff FILENAME is absolute. - Trivial under Unix, but more complicated under other systems. */ -int -isabsolute (filename) - const char *filename; -{ - return filename[0] == '/'; -} - - -/* Return a pointer into PATH's last component. */ -char * -last_component (path) - char *path; -{ - char *last = strrchr (path, '/'); - - if (last) - return last + 1; - else - return path; -} - -/* Return the home directory. Returns a pointer to storage - managed by this function or its callees (currently getenv). */ -char * -get_homedir () -{ - return getenv ("HOME"); -} - -/* See cvs.h for description. On unix this does nothing, because the - shell expands the wildcards. */ -void -expand_wild (argc, argv, pargc, pargv) - int argc; - char **argv; - int *pargc; - char ***pargv; -{ - int i; - *pargc = argc; - *pargv = (char **) xmalloc (argc * sizeof (char *)); - for (i = 0; i < argc; ++i) - (*pargv)[i] = xstrdup (argv[i]); -} |