Deleted Added
full compact
filesubr.c (107487) filesubr.c (128269)
1/* filesubr.c --- subroutines for dealing with files
2 Jim Blandy <jimb@cyclic.com>
3
4 This file is part of GNU CVS.
5
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

--- 4 unchanged lines hidden (view full) ---

13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details. */
15
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. */
19
20/*
1/* filesubr.c --- subroutines for dealing with files
2 Jim Blandy <jimb@cyclic.com>
3
4 This file is part of GNU CVS.
5
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

--- 4 unchanged lines hidden (view full) ---

13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details. */
15
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. */
19
20/*
21 * $FreeBSD: head/contrib/cvs/src/filesubr.c 107487 2002-12-02 03:17:49Z peter $
21 * $FreeBSD: head/contrib/cvs/src/filesubr.c 128269 2004-04-15 01:17:28Z peter $
22 */
23
24#include <assert.h>
25#include "cvs.h"
26
27static int deep_remove_dir PROTO((const char *path));
28
29/*

--- 296 unchanged lines hidden (view full) ---

326 (void) mkdir (name, 0777);
327}
328
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
331 existed. */
332int
333mkdir_if_needed (name)
22 */
23
24#include <assert.h>
25#include "cvs.h"
26
27static int deep_remove_dir PROTO((const char *path));
28
29/*

--- 296 unchanged lines hidden (view full) ---

326 (void) mkdir (name, 0777);
327}
328
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
331 existed. */
332int
333mkdir_if_needed (name)
334 char *name;
334 const char *name;
335{
336 if (mkdir (name, 0777) < 0)
337 {
335{
336 if (mkdir (name, 0777) < 0)
337 {
338 if (errno != EEXIST && !isdir (name))
339 error (1, errno, "cannot make directory %s", name);
338 int save_errno = errno;
339 if (save_errno != EEXIST && !isdir (name))
340 error (1, save_errno, "cannot make directory %s", name);
340 return 1;
341 }
342 return 0;
343}
344
345/*
346 * Change the mode of a file, either adding write permissions, or removing
347 * all write permissions. Either change honors the current umask setting.
348 *
349 * Don't do anything if PreservePermissions is set to `yes'. This may
350 * have unexpected consequences for some uses of xchmod.
351 */
352void
353xchmod (fname, writable)
341 return 1;
342 }
343 return 0;
344}
345
346/*
347 * Change the mode of a file, either adding write permissions, or removing
348 * all write permissions. Either change honors the current umask setting.
349 *
350 * Don't do anything if PreservePermissions is set to `yes'. This may
351 * have unexpected consequences for some uses of xchmod.
352 */
353void
354xchmod (fname, writable)
354 char *fname;
355 const char *fname;
355 int writable;
356{
357 struct stat sb;
358 mode_t mode, oumask;
359
360 if (preserve_perms)
361 return;
362

--- 245 unchanged lines hidden (view full) ---

608 error (1, errno, "cannot lstat %s", file2);
609
610 /* If FILE1 and FILE2 are not the same file type, they are unequal. */
611 if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT))
612 return 1;
613
614 /* If FILE1 and FILE2 are symlinks, they are equal if they point to
615 the same thing. */
356 int writable;
357{
358 struct stat sb;
359 mode_t mode, oumask;
360
361 if (preserve_perms)
362 return;
363

--- 245 unchanged lines hidden (view full) ---

609 error (1, errno, "cannot lstat %s", file2);
610
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))
613 return 1;
614
615 /* If FILE1 and FILE2 are symlinks, they are equal if they point to
616 the same thing. */
617#ifdef S_ISLNK
616 if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
617 {
618 int result;
619 buf1 = xreadlink (file1);
620 buf2 = xreadlink (file2);
621 result = (strcmp (buf1, buf2) == 0);
622 free (buf1);
623 free (buf2);
624 return result;
625 }
618 if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
619 {
620 int result;
621 buf1 = xreadlink (file1);
622 buf2 = xreadlink (file2);
623 result = (strcmp (buf1, buf2) == 0);
624 free (buf1);
625 free (buf2);
626 return result;
627 }
628#endif
626
627 /* If FILE1 and FILE2 are devices, they are equal if their device
628 numbers match. */
629 if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
630 {
631#ifdef HAVE_STRUCT_STAT_ST_RDEV
632 if (sb1.st_rdev == sb2.st_rdev)
633 return 0;

--- 131 unchanged lines hidden (view full) ---

765 fd = mkstemp (fn);
766
767 /* a NULL return will be interpreted by callers as an error and
768 * errno should still be set
769 */
770 if (fd == -1) fp = NULL;
771 else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL)
772 {
629
630 /* If FILE1 and FILE2 are devices, they are equal if their device
631 numbers match. */
632 if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
633 {
634#ifdef HAVE_STRUCT_STAT_ST_RDEV
635 if (sb1.st_rdev == sb2.st_rdev)
636 return 0;

--- 131 unchanged lines hidden (view full) ---

768 fd = mkstemp (fn);
769
770 /* a NULL return will be interpreted by callers as an error and
771 * errno should still be set
772 */
773 if (fd == -1) fp = NULL;
774 else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL)
775 {
773 /* attempt to close and unlink the file since mkstemp returned sucessfully and
774 * we believe it's been created and opened
776 /* Attempt to close and unlink the file since mkstemp returned
777 * sucessfully and we believe it's been created and opened.
775 */
776 int save_errno = errno;
777 if (close (fd))
778 error (0, errno, "Failed to close temporary file %s", fn);
779 if (CVS_UNLINK (fn))
780 error (0, errno, "Failed to unlink temporary file %s", fn);
781 errno = save_errno;
782 }

--- 61 unchanged lines hidden (view full) ---

844 }
845
846#endif
847
848 *filename = fn;
849 return fp;
850}
851
778 */
779 int save_errno = errno;
780 if (close (fd))
781 error (0, errno, "Failed to close temporary file %s", fn);
782 if (CVS_UNLINK (fn))
783 error (0, errno, "Failed to unlink temporary file %s", fn);
784 errno = save_errno;
785 }

--- 61 unchanged lines hidden (view full) ---

847 }
848
849#endif
850
851 *filename = fn;
852 return fp;
853}
854
852/* Return non-zero iff FILENAME is absolute.
853 Trivial under Unix, but more complicated under other systems. */
854int
855isabsolute (filename)
856 const char *filename;
857{
858 return filename[0] == '/';
859}
860
855
861/*
862 * Return a string (dynamically allocated) with the name of the file to which
863 * LINK is symlinked.
856
857#ifdef HAVE_READLINK
858/* char *
859 * xreadlink ( const char *link )
860 *
861 * Like the X/OPEN and 4.4BSD readlink() function, but allocates and returns
862 * its own buf.
863 *
864 * INPUTS
865 * link The original path.
866 *
867 * RETURNS
868 * The resolution of the final symbolic link in the path.
869 *
870 * ERRORS
871 * This function exits with a fatal error if it fails to read the link for
872 * any reason.
864 */
865char *
866xreadlink (link)
867 const char *link;
868{
869 char *file = NULL;
873 */
874char *
875xreadlink (link)
876 const char *link;
877{
878 char *file = NULL;
870 char *tfile;
871 int buflen = BUFSIZ;
872 int linklen;
873
879 int buflen = BUFSIZ;
880 int linklen;
881
874 if (!islink (link))
875 return NULL;
876
877 /* Get the name of the file to which `from' is linked.
878 FIXME: what portability issues arise here? Are readlink &
879 ENAMETOOLONG defined on all systems? -twp */
880 do
881 {
882 file = xrealloc (file, buflen);
883 errno = 0;
884 linklen = readlink (link, file, buflen - 1);
885 buflen *= 2;
886 }
887 while (linklen == -1 && errno == ENAMETOOLONG);
888
889 if (linklen == -1)
890 error (1, errno, "cannot readlink %s", link);
891 file[linklen] = '\0';
892
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 */
885 do
886 {
887 file = xrealloc (file, buflen);
888 errno = 0;
889 linklen = readlink (link, file, buflen - 1);
890 buflen *= 2;
891 }
892 while (linklen == -1 && errno == ENAMETOOLONG);
893
894 if (linklen == -1)
895 error (1, errno, "cannot readlink %s", link);
896 file[linklen] = '\0';
897
893 tfile = xstrdup (file);
894 free (file);
898 return file;
899}
900#endif /* HAVE_READLINK */
895
901
896 return tfile;
902
903
904/* char *
905 * xresolvepath ( const char *path )
906 *
907 * Like xreadlink(), but resolve all links in a path.
908 *
909 * INPUTS
910 * path The original path.
911 *
912 * RETURNS
913 * The path with any symbolic links expanded.
914 *
915 * ERRORS
916 * This function exits with a fatal error if it fails to read the link for
917 * any reason.
918 */
919char *
920xresolvepath ( path )
921 const char *path;
922{
923 char *hardpath;
924 char *owd;
925
926 assert ( isdir ( path ) );
927
928 /* FIXME - If HAVE_READLINK is defined, we should probably walk the path
929 * bit by bit calling xreadlink().
930 */
931
932 owd = xgetwd();
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 );
939 free (owd);
940 return hardpath;
897}
898
899
941}
942
943
944
900/* Return a pointer into PATH's last component. */
945/* Return a pointer into PATH's last component. */
901char *
946const char *
902last_component (path)
947last_component (path)
903 char *path;
948 const char *path;
904{
949{
905 char *last = strrchr (path, '/');
950 const char *last = strrchr (path, '/');
906
907 if (last && (last != path))
908 return last + 1;
909 else
910 return path;
911}
912
913/* Return the home directory. Returns a pointer to storage

--- 75 unchanged lines hidden (view full) ---

989{
990 int i;
991 *pargc = argc;
992 *pargv = (char **) xmalloc (argc * sizeof (char *));
993 for (i = 0; i < argc; ++i)
994 (*pargv)[i] = xstrdup (argv[i]);
995}
996
951
952 if (last && (last != path))
953 return last + 1;
954 else
955 return path;
956}
957
958/* Return the home directory. Returns a pointer to storage

--- 75 unchanged lines hidden (view full) ---

1034{
1035 int i;
1036 *pargc = argc;
1037 *pargv = (char **) xmalloc (argc * sizeof (char *));
1038 for (i = 0; i < argc; ++i)
1039 (*pargv)[i] = xstrdup (argv[i]);
1040}
1041
1042
1043
997#ifdef SERVER_SUPPORT
998/* Case-insensitive string compare. I know that some systems
999 have such a routine, but I'm not sure I see any reasons for
1000 dealing with the hair of figuring out whether they do (I haven't
1001 looked into whether this is a performance bottleneck; I would guess
1002 not). */
1003int
1004cvs_casecmp (str1, str2)
1044#ifdef SERVER_SUPPORT
1045/* Case-insensitive string compare. I know that some systems
1046 have such a routine, but I'm not sure I see any reasons for
1047 dealing with the hair of figuring out whether they do (I haven't
1048 looked into whether this is a performance bottleneck; I would guess
1049 not). */
1050int
1051cvs_casecmp (str1, str2)
1005 char *str1;
1006 char *str2;
1052 const char *str1;
1053 const char *str2;
1007{
1054{
1008 char *p;
1009 char *q;
1055 const char *p;
1056 const char *q;
1010 int pqdiff;
1011
1012 p = str1;
1013 q = str2;
1014 while ((pqdiff = tolower (*p) - tolower (*q)) == 0)
1015 {
1016 if (*p == '\0')
1017 return 0;
1018 ++p;
1019 ++q;
1020 }
1021 return pqdiff;
1022}
1057 int pqdiff;
1058
1059 p = str1;
1060 q = str2;
1061 while ((pqdiff = tolower (*p) - tolower (*q)) == 0)
1062 {
1063 if (*p == '\0')
1064 return 0;
1065 ++p;
1066 ++q;
1067 }
1068 return pqdiff;
1069}
1023
1024/* Case-insensitive file open. As you can see, this is an expensive
1025 call. We don't regard it as our main strategy for dealing with
1026 case-insensitivity. Returns errno code or 0 for success. Puts the
1027 new file in *FP. NAME and MODE are as for fopen. If PATHP is not
1028 NULL, then put a malloc'd string containing the pathname as found
1029 into *PATHP. *PATHP is only set if the return value is 0.
1030
1031 Might be cleaner to separate the file finding (which just gives
1032 *PATHP) from the file opening (which the caller can do). For one
1033 thing, might make it easier to know whether to put NAME or *PATHP
1034 into error messages. */
1035int
1036fopen_case (name, mode, fp, pathp)
1037 char *name;
1038 char *mode;
1039 FILE **fp;
1040 char **pathp;
1041{
1042 struct dirent *dp;
1043 DIR *dirp;
1044 char *dir;
1045 char *fname;
1046 char *found_name;
1047 int retval;
1048
1049 /* Separate NAME into directory DIR and filename within the directory
1050 FNAME. */
1051 dir = xstrdup (name);
1052 fname = strrchr (dir, '/');
1053 if (fname == NULL)
1054 error (1, 0, "internal error: relative pathname in fopen_case");
1055 *fname++ = '\0';
1056
1057 found_name = NULL;
1058 dirp = CVS_OPENDIR (dir);
1059 if (dirp == NULL)
1060 {
1061 if (existence_error (errno))
1062 {
1063 /* This can happen if we are looking in the Attic and the Attic
1064 directory does not exist. Return the error to the caller;
1065 they know what to do with it. */
1066 retval = errno;
1067 goto out;
1068 }
1069 else
1070 {
1071 /* Give a fatal error; that way the error message can be
1072 more specific than if we returned the error to the caller. */
1073 error (1, errno, "cannot read directory %s", dir);
1074 }
1075 }
1076 errno = 0;
1077 while ((dp = CVS_READDIR (dirp)) != NULL)
1078 {
1079 if (cvs_casecmp (dp->d_name, fname) == 0)
1080 {
1081 if (found_name != NULL)
1082 error (1, 0, "%s is ambiguous; could mean %s or %s",
1083 fname, dp->d_name, found_name);
1084 found_name = xstrdup (dp->d_name);
1085 }
1086 }
1087 if (errno != 0)
1088 error (1, errno, "cannot read directory %s", dir);
1089 CVS_CLOSEDIR (dirp);
1090
1091 if (found_name == NULL)
1092 {
1093 *fp = NULL;
1094 retval = ENOENT;
1095 }
1096 else
1097 {
1098 char *p;
1099
1100 /* Copy the found name back into DIR. We are assuming that
1101 found_name is the same length as fname, which is true as
1102 long as the above code is just ignoring case and not other
1103 aspects of filename syntax. */
1104 p = dir + strlen (dir);
1105 *p++ = '/';
1106 strcpy (p, found_name);
1107 *fp = fopen (dir, mode);
1108 if (*fp == NULL)
1109 retval = errno;
1110 else
1111 retval = 0;
1112 }
1113
1114 if (pathp == NULL)
1115 free (dir);
1116 else if (retval != 0)
1117 free (dir);
1118 else
1119 *pathp = dir;
1120 free (found_name);
1121 out:
1122 return retval;
1123}
1124#endif /* SERVER_SUPPORT */
1070#endif /* SERVER_SUPPORT */
1125/* vim:tabstop=8:shiftwidth=4
1126 */