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 Date: Thu, 16 May 2002 17:10:31 -0400 (EDT) From: Mark Blackburn To: "Joerg R. Schaible" cc: cygwin AT cygwin DOT com Subject: Re: Possible error in cygpath In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII On Wed, 15 May 2002, Joerg R. Schaible wrote: > Hi Corinna, > > "Corinna Vinschen" schrieb im Newsbeitrag > news:20020515133932 DOT L2671 AT cygbert DOT vinschen DOT de... > > On Wed, May 15, 2002 at 11:44:51AM +0200, Schaible, Jorg wrote: > > > The reason why I just implemented -s (in 1999) was that GetLongPathName > is > > > not available for Win95. If we have to be Win95-compatible still, you > will > > > have to load the function yourself directly form the DLL and use > > > FindFirstFile (as mensioned in the MSDN docs for *GetShortPathName*) for > > > every part of the path if the function is not available. > > > > Are you interested in implementing that functionality anyway? > > No, not me! I just want to remember Mark, that it is not done just by > calling GetLongPathName. Mark, do you still want to implement this ? I didn't know about GetLongPathName, I used GetFullPathName and FindFirstFile. You mentioned using FindFirstFile on every part of the path, I hadn't thought of that, I was just trying to solve the problem of running gunzip on an 8.3 filename ie foo.c.gz (FOOC~1.GZ) turns to FOOC~1 and you lose the "inside" .c extension. Here's my patch but it its kinda half-assed (I don't think it restores 8.3 directories in the path, just the file) and flaky (it sometimes truncates the filename). Oh and sorry about the extraneous fprintf(stderr,...)'s. --- cygpath.cc.orig 2002-05-14 13:41:46.000000000 -0400 +++ cygpath.cc 2002-05-14 13:58:46.000000000 -0400 @@ -27,7 +27,7 @@ static char *file_arg; static char *close_arg; static int path_flag, unix_flag, windows_flag, absolute_flag; -static int shortname_flag, ignore_flag, allusers_flag, output_flag; +static int longname_flag, shortname_flag, ignore_flag, allusers_flag, output_flag; static struct option long_options[] = { {(char *) "help", no_argument, NULL, 'h'}, @@ -40,6 +40,7 @@ {(char *) "version", no_argument, NULL, 'v'}, {(char *) "windows", no_argument, NULL, 'w'}, {(char *) "short-name", no_argument, NULL, 's'}, + {(char *) "long-name", no_argument, NULL, 'l'}, {(char *) "windir", no_argument, NULL, 'W'}, {(char *) "sysdir", no_argument, NULL, 'S'}, {(char *) "ignore", no_argument, NULL, 'i'}, @@ -61,6 +62,7 @@ -i|--ignore ignore missing argument\n\ -p|--path filename argument is a path\n\ -s|--short-name print Windows short form of filename\n\ + -l|--long-name print Windows/Unix long form of filename\n\ -u|--unix print Unix form of filename\n\ -v|--version output version information and exit\n\ -w|--windows print Windows form of filename\n\ @@ -150,6 +152,57 @@ return sbuf; } +static char * +get_long_name (const char *filename) +{ + char *sbuf; + HANDLE ffh; + WIN32_FIND_DATA w32_fd; + char *pfname; + int fname_offset; + + fprintf(stderr, "get_long_name (%s)\n", filename); + fflush(stderr); + + DWORD len = GetFullPathName(filename,0,NULL,NULL); + + if (len == 0) + { + fprintf (stderr, "%s: cannot create long name of %s\n", prog_name, + filename); + exit (2); + } + + sbuf = (char*)malloc(len); + if (sbuf == NULL) + { + fprintf (stderr, "%s: out of memory\n", prog_name); + exit (1); + } + len = GetFullPathName(filename,len,sbuf,&pfname); + fname_offset = pfname - sbuf; + if (len == 0) + { + fprintf (stderr, "%s: cannot create long name of %s\n", prog_name, + filename); + exit (2); + } + ffh = FindFirstFile(filename, &w32_fd); + if (ffh == INVALID_HANDLE_VALUE) + { + fprintf (stderr, "%s: cannot create long name of %s\n", prog_name, + filename); + exit (2); + } + fprintf(stderr, "w32_fd.cFileName = %s\n", w32_fd.cFileName); + sbuf = (char*)realloc(sbuf, len - fname_offset + strlen(w32_fd.cFileName) + 1); + + strcpy(sbuf+fname_offset, w32_fd.cFileName); + fprintf(stderr, "get_long_name (%s) = %s\n", filename, sbuf); + fprintf(stderr, "sbuf (%p)\n", sbuf); + return sbuf; +} + static void doit (char *filename) { @@ -209,6 +262,12 @@ cygwin_posix_to_win32_path_list (filename, buf); if (shortname_flag) buf = get_short_paths (buf); + else if (longname_flag) + { + fprintf(stderr, "Line: %i\n", __LINE__); + fflush(stderr); + buf = get_long_name (buf); + } } } else @@ -228,6 +287,12 @@ } if (!unix_flag && shortname_flag) buf = get_short_name (buf); + else if (!unix_flag && longname_flag) + { + fprintf(stderr, "Line: %i\n", __LINE__); + fflush(stderr); + buf = get_long_name (buf); + } } puts (buf); @@ -277,12 +342,13 @@ unix_flag = 0; windows_flag = 0; shortname_flag = 0; + longname_flag = 0; ignore_flag = 0; options_from_file_flag = 0; allusers_flag = 0; output_flag = 0; while ((c = - getopt_long (argc, argv, (char *) "hac:f:opsSuvwWiDPA", + getopt_long (argc, argv, (char *) "hac:f:opsSuvwWiDPAl", long_options, (int *) NULL)) != EOF) { switch (c) @@ -320,11 +386,21 @@ break; case 's': + if (longname_flag) + usage (stderr, 1); if (unix_flag) usage (stderr, 1); shortname_flag = 1; break; + case 'l': + if (shortname_flag) + usage (stderr, 1); + if (unix_flag) + usage (stderr, 1); + longname_flag = 1; + break; + case 'A': allusers_flag = 1; break;7~ -- 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/