Discussion:
Handling FTP servers that indicate backslash as CWD
John Coffey
2015-02-11 05:38:00 UTC
Permalink
Does anyone know of a way to avoid the automatic CWD command in libCurl,
as I am connecting to an FTP server that indicates "\" is current working
directory. I am only uploading files to this server, so I do not need to
know the current working directory.

This is a very old windows based embedded server that I cannot modify.
Normally such a system would result in a "SYST" command being issued (see
snippet of code from libCurl's ftp.c below) under the covers in order to
identify the system. Unfortunately this very old server does not support
that command either. As a toying with making some kind of hack to at least
bypass the problem with dir[0] below but I don't fully know the
ramifications of this. At least the change below allows the default CWD
response from the FTP server to keep libCurl happy. If this problem has
been encountered and worked abound before, it would be great to know


John

/* If the path name does not look like an absolute path
(i.e.: it does not start with a '/'), we probably need
some server-dependent adjustments. For example, this is
the case when connecting to an OS400 FTP server: this
server supports two name syntaxes, the default one being
incompatible with standard pathes. In addition, this
server switches automatically to the regular path syntax
when one is encountered in a command: this results in
having an entrypath in the wrong syntax when later used in CWD.
The method used here is to check the server OS: we do it only
if the path name looks strange to minimize overhead on other
systems. */

if(!ftpc->server_os && dir[0] != '/' dir[0] != '\\' ) { //
ADD THE EXTRA TEST FOR BACKSLASH

result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
if(result) {
free(dir);
return result;
}
Curl_safefree(ftpc->entrypath);
ftpc->entrypath = dir; /* remember this */
infof(data, "Entry path is '%s'\n", ftpc->entrypath);
/* also save it where getinfo can access it: */
data->state.most_recent_ftp_entrypath = ftpc->entrypath;
state(conn, FTP_SYST);
break;
}
Dan Fandrich
2015-02-11 08:14:58 UTC
Permalink
Does anyone know of a way to avoid the automatic CWD command in libCurl,  as I
am connecting to an FTP server that indicates "\" is current working
directory.  I am only uploading files to this server, so I do not need to know
the current working directory.   
The CURLOPT_FTP_FILEMETHOD option has a CURLFTPMETHOD_NOCWD that does this.
Dan
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl
John Coffey
2015-02-11 13:21:55 UTC
Permalink
Dan, I already use this option, however it does not appear to prevent the
automatic CWD when I first login. That option appears to only be used for
traversing directories when already logged in.


My default curl options are set as follows:

. . .
auto res = curl_easy_setopt(pCurl, CURLOPT_FTP_USE_EPSV, 0L);
res = curl_easy_setopt(pCurl, CURLOPT_FTP_USE_EPRT, 0L);
res = curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1L);

// do not perform CWD when traversing the pseudo directories
res = curl_easy_setopt(pCurl, CURLOPT_FTP_FILEMETHOD,
CURLFTPMETHOD_NOCWD);
res = curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT,
getConnectTimeoutSecs());

if (!isPASVMode()) {
res = curl_easy_setopt(pCurl, CURLOPT_FTPPORT, "-");
}
// used to capture header traffic
if (mHeaderCallback) {
res = curl_easy_setopt(pCurl, CURLOPT_WRITEHEADER, mpHeaderStream);
res = curl_easy_setopt(pCurl, CURLOPT_HEADERFUNCTION,
mHeaderCallback);
}
// for FTP GET operations
if (mWriteDataCallback) {
res = curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &mScratchBuffer);
res = curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION,
mWriteDataCallback);
}
// for FTP PUT operations
if (mReadFileCallback) {
res = curl_easy_setopt(pCurl, CURLOPT_READFUNCTION,
mReadFileCallback);
}

// progress callback used to track upload progress only
if (mProgressCallback) {
res = curl_easy_setopt(pCurl, CURLOPT_XFERINFOFUNCTION,
mProgressCallback);
res = curl_easy_setopt(pCurl, CURLOPT_XFERINFODATA, nullptr);
res = curl_easy_setopt(pCurl, CURLOPT_NOPROGRESS, 0L);
}

// verbose logging
if (mDebuggingCallback) {
res = curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1L);
res = curl_easy_setopt(pCurl, CURLOPT_DEBUGFUNCTION,
mDebuggingCallback);
res = curl_easy_setopt(pCurl, CURLOPT_DEBUGDATA, nullptr);
} else {
res = curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 0L);
res = curl_easy_setopt(pCurl, CURLOPT_DEBUGDATA, nullptr);
}

// disable Nagle algorithm - to fix slowdown in bulk transfers
// with large data files @JC not necessary
//res = curl_easy_setopt(pCurl, CURLOPT_TCP_NODELAY, 1L);
if (mSocketOptionCallback) {
res = curl_easy_setopt(pCurl, CURLOPT_SOCKOPTDATA, nullptr);
res = curl_easy_setopt(pCurl, CURLOPT_SOCKOPTFUNCTION,
mSocketOptionCallback);
}
. . .


John

---------- Forwarded message ----------
From: Dan Fandrich <***@coneharvesters.com>
Date: Wed, Feb 11, 2015 at 3:14 AM
Subject: Re: Handling FTP servers that indicate backslash as CWD
Post by John Coffey
Does anyone know of a way to avoid the automatic CWD command in libCurl,
as I
Post by John Coffey
am connecting to an FTP server that indicates "\" is current working
directory. I am only uploading files to this server, so I do not need to
know
Post by John Coffey
the current working directory.
The CURLOPT_FTP_FILEMETHOD option has a CURLFTPMETHOD_NOCWD that does this.
Post by John Coffey
Dan
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Daniel Stenberg
2015-02-11 13:28:57 UTC
Permalink
Post by John Coffey
Dan, I already use this option, however it does not appear to prevent the
automatic CWD when I first login. That option appears to only be used for
traversing directories when already logged in.
The first? So where does that CWD take you? Aren't you talking about the PWD?

Can you show us a verbose output to show what curl does (wrongly) in your
case?
--
/ daniel.haxx.se
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:
John Coffey
2015-02-11 14:55:14 UTC
Permalink
Dan,

Thank you for the correction, my mistake, yes, I meant that libCurl issued
an automatic PWD under the covers.

Below is my wireshark stream capture from the initial login. As you can
see, given that the initial path separator is not "/", libCurl attempts to
determine if this is an "OS/400" per the code block from ftp.c line 2976
(libcurl 7.40) below by issuing a SYST command (which is not supported by
the FTP server, if so it issues the special "SITE NAMEFMT 1" command.

220 CMC FTP server ready.
USER anonymous
331 User allowed.
PASS ***@example.com
230-Welcome to CMC
Central Maintenance Computer
EWF STATE: [EWF_RAM_REG] ENABLED '\Device\HarddiskVolume1' (C:) 4.86 MB
BIOS Date: 02/09/2007 (TT7036180-301)
hw-descriptor:p7034055-1901^:mA^:u00000053^
230
PWD
257 "\" is current directory
SYST
502 Command not implemented
PORT 192,168,200,2,141,93
250 PORT command successful
QUIT
221 Goodbye


John

/* Check for special servers here. */

if(strequal(os, "OS/400")) {
/* Force OS400 name format 1. */
result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
if(result) {
free(os);
return result;
}
/* remember target server OS */
Curl_safefree(ftpc->server_os);
ftpc->server_os = os;
state(conn, FTP_NAMEFMT);
break;
}
else {
/* Nothing special for the target server. */
/* remember target server OS */
Curl_safefree(ftpc->server_os);
ftpc->server_os = os;
}
Post by John Coffey
Dan, I already use this option, however it does not appear to prevent the
Post by John Coffey
automatic CWD when I first login. That option appears to only be used for
traversing directories when already logged in.
The first? So where does that CWD take you? Aren't you talking about the PWD?
Can you show us a verbose output to show what curl does (wrongly) in your
case?
--
/ daniel.haxx.se
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Patrick Monnerat
2015-02-11 17:28:25 UTC
Permalink
Post by John Coffey
PWD
257 "\" is current directory
SYST
502 Command not implemented
PORT 192,168,200,2,141,93
The PORT command has been sent, so the SYST command failure did not
abort your transfer request. The problem is not here.
Post by John Coffey
250 PORT command successful
The problem is here: the response to the PORT command is expected to be
"200" (Command Okay), not "250" (Requested file action okay, completed).
This is why no transfer occurs and the dialog aborts. This is a deviant
response (see RFC 959, top of page 51). May be we can check this code
Post by John Coffey
QUIT
221 Goodbye
BTW: use "curl --verbose" or CURLOPT_VERBOSE to obtain a dialog dump:
this gives more details than a wireshark capture.

Patrick

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/
Daniel Stenberg
2015-02-11 17:40:45 UTC
Permalink
Post by Patrick Monnerat
Post by John Coffey
250 PORT command successful
The problem is here: the response to the PORT command is expected to be
"200" (Command Okay), not "250" (Requested file action okay, completed).
This is why no transfer occurs and the dialog aborts. This is a deviant
response (see RFC 959, top of page 51). May be we can check this code for
Yes I believe so. We have no particular reason to be very picky about that so
ftpcode/100 == 2 is probably a better check there...
--
/ daniel.haxx.se
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.
Patrick Monnerat
2015-02-11 18:57:03 UTC
Permalink
Post by Daniel Stenberg
This is a deviant response (see RFC 959, top of page 51). May be we
Yes I believe so. We have no particular reason to be very picky about
that so ftpcode/100 == 2 is probably a better check there...

Pushed :-)

Patrick

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx

Loading...