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 */ | |