diff options
Diffstat (limited to 'contrib/cvs/src/filesubr.c')
-rw-r--r-- | contrib/cvs/src/filesubr.c | 212 |
1 files changed, 78 insertions, 134 deletions
diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c index 381945dd9e871..57511f419220e 100644 --- a/contrib/cvs/src/filesubr.c +++ b/contrib/cvs/src/filesubr.c @@ -327,12 +327,13 @@ make_directories (name) existed. */ int mkdir_if_needed (name) - char *name; + const char *name; { if (mkdir (name, 0777) < 0) { - if (errno != EEXIST && !isdir (name)) - error (1, errno, "cannot make directory %s", name); + int save_errno = errno; + if (save_errno != EEXIST && !isdir (name)) + error (1, save_errno, "cannot make directory %s", name); return 1; } return 0; @@ -347,7 +348,7 @@ mkdir_if_needed (name) */ void xchmod (fname, writable) - char *fname; + const char *fname; int writable; { struct stat sb; @@ -609,6 +610,7 @@ xcmp (file1, file2) /* If FILE1 and FILE2 are symlinks, they are equal if they point to the same thing. */ +#ifdef S_ISLNK if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode)) { int result; @@ -619,6 +621,7 @@ xcmp (file1, file2) free (buf2); return result; } +#endif /* If FILE1 and FILE2 are devices, they are equal if their device numbers match. */ @@ -766,8 +769,8 @@ FILE *cvs_temp_file (filename) if (fd == -1) fp = NULL; else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL) { - /* attempt to close and unlink the file since mkstemp returned sucessfully and - * we believe it's been created and opened + /* Attempt to close and unlink the file since mkstemp returned + * sucessfully and we believe it's been created and opened. */ int save_errno = errno; if (close (fd)) @@ -845,31 +848,33 @@ FILE *cvs_temp_file (filename) return fp; } -/* 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 string (dynamically allocated) with the name of the file to which - * LINK is symlinked. + +#ifdef HAVE_READLINK +/* char * + * xreadlink ( const char *link ) + * + * Like the X/OPEN and 4.4BSD readlink() function, but allocates and returns + * its own buf. + * + * INPUTS + * link The original path. + * + * RETURNS + * The resolution of the final symbolic link in the path. + * + * ERRORS + * This function exits with a fatal error if it fails to read the link for + * any reason. */ char * xreadlink (link) const char *link; { char *file = NULL; - char *tfile; int buflen = 128; int link_name_len; - if (!islink (link)) - return NULL; - /* Get the name of the file to which `from' is linked. FIXME: what portability issues arise here? Are readlink & ENAMETOOLONG defined on all systems? -twp */ @@ -886,19 +891,59 @@ xreadlink (link) file[link_name_len] = '\0'; - tfile = xstrdup (file); - free (file); + return file; +} +#endif /* HAVE_READLINK */ + - return tfile; + +/* char * + * xresolvepath ( const char *path ) + * + * Like xreadlink(), but resolve all links in a path. + * + * INPUTS + * path The original path. + * + * RETURNS + * The path with any symbolic links expanded. + * + * ERRORS + * This function exits with a fatal error if it fails to read the link for + * any reason. + */ +char * +xresolvepath ( path ) + const char *path; +{ + char *hardpath; + char *owd; + + assert ( isdir ( path ) ); + + /* FIXME - If HAVE_READLINK is defined, we should probably walk the path + * bit by bit calling xreadlink(). + */ + + owd = xgetwd(); + if ( CVS_CHDIR ( path ) < 0) + error ( 1, errno, "cannot chdir to %s", path ); + if ( ( hardpath = xgetwd() ) == NULL ) + error (1, errno, "cannot getwd in %s", path); + if ( CVS_CHDIR ( owd ) < 0) + error ( 1, errno, "cannot chdir to %s", owd ); + free (owd); + return hardpath; } + /* Return a pointer into PATH's last component. */ -char * +const char * last_component (path) - char *path; + const char *path; { - char *last = strrchr (path, '/'); + const char *last = strrchr (path, '/'); if (last && (last != path)) return last + 1; @@ -990,6 +1035,8 @@ expand_wild (argc, argv, pargc, pargv) (*pargv)[i] = xstrdup (argv[i]); } + + #ifdef SERVER_SUPPORT /* Case-insensitive string compare. I know that some systems have such a routine, but I'm not sure I see any reasons for @@ -998,11 +1045,11 @@ expand_wild (argc, argv, pargc, pargv) not). */ int cvs_casecmp (str1, str2) - char *str1; - char *str2; + const char *str1; + const char *str2; { - char *p; - char *q; + const char *p; + const char *q; int pqdiff; p = str1; @@ -1016,107 +1063,4 @@ cvs_casecmp (str1, str2) } return pqdiff; } - -/* Case-insensitive file open. As you can see, this is an expensive - call. We don't regard it as our main strategy for dealing with - case-insensitivity. Returns errno code or 0 for success. Puts the - new file in *FP. NAME and MODE are as for fopen. If PATHP is not - NULL, then put a malloc'd string containing the pathname as found - into *PATHP. *PATHP is only set if the return value is 0. - - Might be cleaner to separate the file finding (which just gives - *PATHP) from the file opening (which the caller can do). For one - thing, might make it easier to know whether to put NAME or *PATHP - into error messages. */ -int -fopen_case (name, mode, fp, pathp) - char *name; - char *mode; - FILE **fp; - char **pathp; -{ - struct dirent *dp; - DIR *dirp; - char *dir; - char *fname; - char *found_name; - int retval; - - /* Separate NAME into directory DIR and filename within the directory - FNAME. */ - dir = xstrdup (name); - fname = strrchr (dir, '/'); - if (fname == NULL) - error (1, 0, "internal error: relative pathname in fopen_case"); - *fname++ = '\0'; - - found_name = NULL; - dirp = CVS_OPENDIR (dir); - if (dirp == NULL) - { - if (existence_error (errno)) - { - /* This can happen if we are looking in the Attic and the Attic - directory does not exist. Return the error to the caller; - they know what to do with it. */ - retval = errno; - goto out; - } - else - { - /* Give a fatal error; that way the error message can be - more specific than if we returned the error to the caller. */ - error (1, errno, "cannot read directory %s", dir); - } - } - errno = 0; - while ((dp = CVS_READDIR (dirp)) != NULL) - { - if (cvs_casecmp (dp->d_name, fname) == 0) - { - if (found_name != NULL) - error (1, 0, "%s is ambiguous; could mean %s or %s", - fname, dp->d_name, found_name); - found_name = xstrdup (dp->d_name); - } - } - if (errno != 0) - error (1, errno, "cannot read directory %s", dir); - CVS_CLOSEDIR (dirp); - - if (found_name == NULL) - { - *fp = NULL; - retval = ENOENT; - } - else - { - char *p; - - /* Copy the found name back into DIR. We are assuming that - found_name is the same length as fname, which is true as - long as the above code is just ignoring case and not other - aspects of filename syntax. */ - p = dir + strlen (dir); - *p++ = '/'; - strcpy (p, found_name); - *fp = fopen (dir, mode); - if (*fp == NULL) - retval = errno; - else - retval = 0; - } - - if (pathp == NULL) - free (dir); - else if (retval != 0) - free (dir); - else - *pathp = dir; - free (found_name); - out: - return retval; -} #endif /* SERVER_SUPPORT */ -/* vim:tabstop=8:shiftwidth=4 - */ |