Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <3D812C51.C17EC79F@pajhome.org.uk> Date: Fri, 13 Sep 2002 01:07:45 +0100 From: Paul Johnston X-Accept-Language: en MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Finding exact case of paths References: Content-Type: multipart/mixed; boundary="------------2BCB8D9710F9ABDECC9B590D" --------------2BCB8D9710F9ABDECC9B590D Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, > Oh, I see, add a modifier similar to '-s', so that it verifies the case of > each element in the path... Yeah, that could work, something like: > -e, --exact-case print exact case of NAME Yep, exactly. Now, cygpath seems to generally not hit the filesystem - cygpath c:/complete/crap gives me /c/complete/crap so using that switch will necessarily involve a performance hit. Given that, I think I'm happy with my solution based on dirent/strcasecmp. I've attached a stand-alone utility that seems to work (just on cygwin paths), although it has the side effect of squishing down multiple slashes ///like////this//path down to /like/this/path. I think it would be ok to restrict --exact-case to cygwin paths. Paul --------------2BCB8D9710F9ABDECC9B590D Content-Type: text/plain; charset=us-ascii; name="exactcase.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="exactcase.c" #include #include #include #include #include #include /* Only needed for test code */ /*** * Main subroutine is just for testing **/ int main(int argc, char *argv[]) { char path[PATH_MAX]; if(argc == 2) { strcpy(path, argv[1]); if(exact_case(path)) printf("OUTPUT: %s\n", path); else printf("ERROR: %s\n", strerror(errno)); } return 0; } /*** * Vague attempt to make code independent of path type **/ #define DLM_STR "/" #define DLM_CHR '/' #define CWD_STR "." #define IS_ABSOLUTE(X) (X[0] == DLM_CHR) /*** * Determine the correct case for a cygwin path, fill-in in place * Returns TRUE/FALSE - success/failure **/ int exact_case(char *path) { char work[PATH_MAX], *part, path_strtok[PATH_MAX]; if(strlen(path) > (PATH_MAX - 1)) /* PATH_MAX allows for the NUL */ { errno = ENAMETOOLONG; return 0; } strcpy(path_strtok, path); part = strtok(path_strtok, DLM_STR); if(IS_ABSOLUTE(path)) { if(!exact_case_part(DLM_STR, part)) return 0; strcpy(work, DLM_STR); strcat(work, part); } else { if(!exact_case_part(CWD_STR, part)) return 0; strcpy(work, part); } while(part = strtok(NULL, DLM_STR)) { if(!exact_case_part(work, part)) return 0; strcat(work, DLM_STR); strcat(work, part); } strcpy(path, work); return 1; } /*** * Search a directory for an entry; fill-in it's correct case * Returns TRUE/FALSE - success/failure **/ int exact_case_part(const char *base, char *part) { struct dirent *de; DIR *dh = opendir(base); if(!dh) return 0; while(de = readdir(dh)) { if(strcasecmp(part, de->d_name) == 0) break; } closedir(dh); if(de) strcpy(part, de->d_name); else errno = ENOENT; return (int) de; } --------------2BCB8D9710F9ABDECC9B590D Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --------------2BCB8D9710F9ABDECC9B590D--