... thanks ... this email is kind of long.  I did a little poking in
fileio.c and did some testes.  I describe as far as I got, including an
excerpt of fileio.c that may be part of the problem, and my test showing
why I think so.

I think I've uncovered either a bug in NTemacs, or a bug in rcp.el's
assumptions.  I prefer to believe it's a bug in NTemacs.

Daniel Pittman wrote:
> 
> Well, I can't speak for GNU Emacs, but on XEmacs 21.2, the following
> snippet from 'src/fileio.c' might have the answer to why RCP paths don't
> work quite right...
> 
>       /* Only recognize colon as part of drive specifier if there is a
>          single alphabetic character preceding the colon (and if the
>          character before the drive letter, if present, is a directory
>          separator); this is to support the remote system syntax used by
>          ange-ftp, and the "po:username" syntax for POP mailboxes. */
> 
> It looks like the /r: syntax is interpreted as a drive letter rather
> than as a path by 'expand-file-name' - something that is called by most
> of the file handling code...

well, if I change rcp.el to instead expect /rf: as the prefix, it still
fails in the same way.  so does /rf@scp: prefix.

----------------------------------------

for those that don't know, NT allows paths like the following

    c:\foo                ; standared for NT, emacs accepts
    c:/foo                ; emacs also accepts this
    //machine_name/foo    ; standard for NT, emacs accepts
    \\machine_name\foo    ; emacs also accepts this

and, it appears, some other form I'm not familiar with.  The way the
strings are parsed in fileio.c doesn't look very robust to extra colons
in the string.  They are parsed from right-to-left, looking for colon or
slash characters.  I don't know the utility functions well enough to
figure out what happens with rcp-type filenames, but there is a
potential for the string to get broken up incorrectly.

so, I did a little test.

(setq f "/r@scp:juliano@capefear:.emacs")
"/r@scp:juliano@capefear:.emacs"

(file-name-directory f)          ; why is "scp:" both here
"/r@scp:"

(file-name-nondirectory f)       ; and here?
"r@scp:juliano@capefear:.emacs"

(expand-file-name f)
;; when rcp.el not loaded, ange-ftp asks for password
;; when rcp.el loaded, ssh seg faults

(setq f "c:/home/juliano/.emacs")
"c:/home/juliano/.emacs"

(file-name-directory f)
"c:/home/juliano/"

(file-name-nondirectory f)
".emacs"

(expand-file-name f)
"c:/home/juliano/.emacs"


Not sure exactly why "r@scp:" is in both directory and non-directory,
but I believe it after looking at fileio.c.  Is this a bug in NT emacs,
or incorrect use of file-name-(non)directory?  what do you get with
xemacs?

here's the important parts of file-name-(non)directory.  Notice the "beg
+ 2" and "beg + 4" tricks.  The while loop goes from right to left. 
IS_DIRECTORY_SEP returns true if the pointed-to character is '/' or '\'.

-------------- From file-name-nondirectory ----------------

  beg = XSTRING (filename)->data;
  end = p = beg + STRING_BYTES (XSTRING (filename));

  while (p != beg && !IS_DIRECTORY_SEP (p[-1])
#ifdef VMS
         && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
#endif /* VMS */
#ifdef DOS_NT
         /* only recognise drive specifier at beginning */
         && !(p[-1] == ':'
              /* handle the "/:d:foo" case correctly  */
              && (p == beg + 2 || (p == beg + 4 && IS_DIRECTORY_SEP (*beg))))
#endif
         )
    p--;

  if (STRING_MULTIBYTE (filename))
    return make_string (p, end - p);
  return make_unibyte_string (p, end - p);

-------------- From file-name-directory ----------------

  p = beg + STRING_BYTES (XSTRING (filename));

  while (p != beg && !IS_DIRECTORY_SEP (p[-1])
#ifdef VMS
         && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
#endif /* VMS */
#ifdef DOS_NT
         /* only recognise drive specifier at the beginning */
         && !(p[-1] == ':'
              /* handle the "/:d:foo" and "/:foo" cases correctly  */
              && ((p == beg + 2 && !IS_DIRECTORY_SEP (*beg))
                  || (p == beg + 4 && IS_DIRECTORY_SEP (*beg))))
#endif
         ) p--;

  if (p == beg)
    return Qnil;
#ifdef DOS_NT
  /* Expansion of "c:" to drive and default directory.  */
  if (p[-1] == ':')
    {
      /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. 
*/
      unsigned char *res = alloca (MAXPATHLEN + 1);
      unsigned char *r = res;

      if (p == beg + 4 && IS_DIRECTORY_SEP (*beg) && beg[1] == ':')
        {
          strncpy (res, beg, 2);
          beg += 2;
          r += 2;
        }

      if (getdefdir (toupper (*beg) - 'A' + 1, r))
        {
          if (!IS_DIRECTORY_SEP (res[strlen (res) - 1]))
            strcat (res, "/");
          beg = res;
          p = beg + strlen (beg);
        }
    }
  CORRECT_DIR_SEPS (beg);
#endif /* DOS_NT */

----------------------------------------

I'm (almost) completely lost looking through fileio.c.  From the bit I
figured out of how emacs handles NT as a special case, I'd be surprised
if /r: is ever going to work. (the way fileio.c is written in this
version of emacs)  AFAIK, /rf@scp: stands a better chance.  but, if the
"/" prefix causes the special-case code not to be executed (which might
be the case), then it shouldn't matter.  need someone more knowlegable
than me to assess this.

either way, /r@scp: should not have the potential problems of /r:, AFAIK


thanks,

-jeff

Reply via email to