This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Possible error in cygpath




On Wed, 15 May 2002, Joerg R. Schaible wrote:

> Hi Corinna,
> 
> "Corinna Vinschen" <corinna-cygwin@cygwin.com> schrieb im Newsbeitrag
> 20020515133932.L2671@cygbert.vinschen.de">news:20020515133932.L2671@cygbert.vinschen.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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]