Ian Ford asked about support for the FTP command ACCT, and I discovered it is
authorDaniel Stenberg <daniel@haxx.se>
Tue, 25 Jan 2005 22:13:12 +0000 (22:13 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 25 Jan 2005 22:13:12 +0000 (22:13 +0000)
present in RFC959... so now (lib)curl supports it as well. --ftp-account and
CURLOPT_FTP_ACCOUNT set the account string. (The server may ask for an account
string after PASS have been sent away. The client responds with "ACCT [account
string]".) Added test case 228 and 229 to verify the functionality. Updated
the test FTP server to support ACCT somewhat.

12 files changed:
CHANGES
RELEASE-NOTES
docs/curl.1
docs/libcurl/curl_easy_setopt.3
include/curl/curl.h
lib/ftp.c
lib/url.c
lib/urldata.h
src/main.c
tests/data/Makefile.am
tests/data/test228 [new file with mode: 0644]
tests/data/test229 [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index fd824be9686b8f5d47b18b266cf4496e1758c149..77b770f712d6773795720e1573ce430d55ae6fad 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,13 @@
                                   Changelog
 
 Daniel (25 January 2005)
+- Ian Ford asked about support for the FTP command ACCT, and I discovered it
+  is present in RFC959... so now (lib)curl supports it as well. --ftp-account
+  and CURLOPT_FTP_ACCOUNT set the account string. (The server may ask for an
+  account string after PASS have been sent away. The client responds
+  with "ACCT [account string]".) Added test case 228 and 229 to verify the
+  functionality. Updated the test FTP server to support ACCT somewhat.
+
 - David Shaw contributed a fairly complete and detailed autoconf test you can
   use to detect libcurl and setup variables for the protocols the installed
   libcurl supports: docs/libcurl/libcurl.m4
index de34cbb5222ea3036725c9d7f9a6bf0a36a2eef4..5e57b22314b7d9bc13fad7b59632685e3fb17897 100644 (file)
@@ -2,14 +2,15 @@ Curl and libcurl 7.13.0
 
  Public curl release number:               85
  Releases counted from the very beginning: 112
- Available command line options:           103
- Available curl_easy_setopt() options:     121
+ Available command line options:           104
+ Available curl_easy_setopt() options:     122
  Number of public functions in libcurl:    46
  Amount of public web site mirrors:        15
  Number of known libcurl bindings:         29
 
 This release includes the following changes:
 
+ o added --ftp-account and CURLOPT_FTP_ACCOUNT
  o added CURLOPT_SOURCE_URL and CURLOPT_SOURCE_QUOTE
  o obsoleted CURLOPT_SOURCE_HOST, CURLOPT_SOURCE_PATH, CURLOPT_SOURCE_PORT
    and CURLOPT_PASV_HOST
@@ -49,6 +50,6 @@ advice from friends like these:
  Werner Koch, Gisle Vanem, Alex Neblett, Kai Sommerfeld, Marty Kuhrt,
  Hzhijun, Pavel Orehov, Bruce Mitchener, Cyrill Osterwalder, Dan Torop,
  Martijn Koster, Alex aka WindEagle, Cody Jones, Samuel Díaz García,
- Stephan Bergmann, Philippe Hameau
+ Stephan Bergmann, Philippe Hameau, Ian Ford
 
         Thanks! (and sorry if I forgot to mention someone)
index 3556d1ce6ba11daf75fae6bcc75879b30c67772c..4dc8f0425a446af6750e1bc23f24701609c8f9a0 100644 (file)
@@ -21,7 +21,7 @@
 .\" * $Id$
 .\" **************************************************************************
 .\"
-.TH curl 1 "20 Jan 2005" "Curl 7.13.0" "Curl Manual"
+.TH curl 1 "25 Jan 2005" "Curl 7.13.0" "Curl Manual"
 .SH NAME
 curl \- transfer a URL
 .SH SYNOPSIS
@@ -330,6 +330,12 @@ document stating so (which often also describes why and more). This flag will
 prevent curl from outputting that and fail silently instead.
 
 If this option is used twice, the second will again disable silent failure.
+.IP "--ftp-account [data]"
+(FTP) When an FTP server asks for "account data" after user name and password
+has been provided, this data is sent off using the ACCT command. (Added in
+7.13.0)
+
+If this option is used twice, the second will override the previous use.
 .IP "--ftp-create-dirs"
 (FTP) When an FTP URL/operation uses a path that doesn't currently exist on
 the server, the standard behavior of curl is to fail. Using this option, curl
index 776e3da9000e24821161d9c12a416edd4b38d310..84e5c1b8036222802b6c832b02ad682d7e5b2d35 100644 (file)
@@ -21,7 +21,7 @@
 .\" * $Id$
 .\" **************************************************************************
 .\"
-.TH curl_easy_setopt 3 "20 Jan 2005" "libcurl 7.12.4" "libcurl Manual"
+.TH curl_easy_setopt 3 "25 Jan 2005" "libcurl 7.13.0" "libcurl Manual"
 .SH NAME
 curl_easy_setopt - set options for a curl easy handle
 .SH SYNOPSIS
@@ -763,6 +763,10 @@ Exactly like \fICURLOPT_QUOTE\fP, but for the source host.
 Exactly like \fICURLOPT_PREQUOTE\fP, but for the source host.
 .IP CURLOPT_SOURCE_POSTQUOTE
 Exactly like \fICURLOPT_POSTQUOTE\fP, but for the source host.
+.IP CURLOPT_FTP_ACCOUNT
+Pass a pointer to a zero-terminated string (or NULL to disable). When an FTP
+server asks for "account data" after user name and password has been provided,
+this data is sent off using the ACCT command. (Added in 7.13.0)
 .SH PROTOCOL OPTIONS
 .IP CURLOPT_TRANSFERTEXT
 A non-zero parameter tells the library to use ASCII mode for ftp transfers,
index 07c028b3bf10941632fc273147b6497e1df57a55..019ef08a08b2a2fc6a20601e7c48af21ee47dbe7 100644 (file)
@@ -882,6 +882,10 @@ typedef enum {
      commands with this */
   CINIT(SOURCE_QUOTE, OBJECTPOINT, 133),
 
+  /* zero terminated string for pass on to the FTP server when asked for
+     "account" info */
+  CINIT(FTP_ACCOUNT, OBJECTPOINT, 134),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
index 3f4b23fe781225e9bcef1c98d58c1e02cd068d44..caca95e953d754a847df9197da4e034952687bad 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -621,6 +621,23 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
 
       infof(data, "We have successfully logged in\n");
     }
+    else if(ftpcode == 332) {
+      /* 332 Please provide account info */
+      if(data->set.ftp_account) {
+        FTPSENDF(conn, "ACCT %s", data->set.ftp_account);
+        result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+        if(!result && (ftpcode != 230)) {
+          failf(data, "ACCT rejected by server: %03d", ftpcode);
+          result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */
+        }
+      }
+      else {
+        failf(data, "ACCT requested by none available");
+        result = CURLE_FTP_WEIRD_PASS_REPLY;
+      }
+      if(result)
+        return result;
+    }
     else {
       failf(data, "Odd return code after PASS");
       return CURLE_FTP_WEIRD_PASS_REPLY;
index 8b433f606e6a7a6d17d06ff02f4fe713dd3f252e..f5fc82be4fda9ed4b66a23d9300da5cf3f219cb2 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -1396,6 +1396,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
     data->set.source_postquote = va_arg(param, struct curl_slist *);
     break;
 
+  case CURLOPT_FTP_ACCOUNT:
+    data->set.ftp_account = va_arg(param, char *);
+    break;
+
   default:
     /* unknown tag and its companion, just ignore: */
     result = CURLE_FAILED_INIT; /* correct this */
index 70045de7967e85e0edab8e8ba6cae752e5babb1d..76de457572b02bcda385271bbeef774004bc0296 100644 (file)
@@ -862,6 +862,7 @@ struct UserDefined {
   char *cookiejar;      /* dump all cookies to this file */
   bool cookiesession;   /* new cookie session? */
   bool crlf;            /* convert crlf on ftp upload(?) */
+  char *ftp_account;    /* ftp account data */
   struct curl_slist *quote;     /* after connection is established */
   struct curl_slist *postquote; /* after the transfer */
   struct curl_slist *prequote; /* before the transfer, after type */
index 708b8124d1b6b540a7be5dae334bbe895f0f4feb..14f34fac12959292db9b7fc27f358fa73e9a2f0d 100644 (file)
@@ -548,7 +548,7 @@ struct Configurable {
   struct curl_slist *tp_quote;
   struct curl_slist *tp_postquote;
   struct curl_slist *tp_prequote;
-
+  char *ftp_account; /* for ACCT */
 };
 
 /* global variable to hold info about libcurl */
@@ -1249,10 +1249,10 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
     {"$g", "retry",      TRUE},
     {"$h", "retry-delay", TRUE},
     {"$i", "retry-max-time", TRUE},
-
     {"$j", "3p-url", TRUE},
     {"$k", "3p-user", TRUE},
     {"$l", "3p-quote", TRUE},
+    {"$m", "ftp-account", TRUE},
 
     {"0", "http1.0",     FALSE},
     {"1", "tlsv1",       FALSE},
@@ -1631,6 +1631,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
 
         break;
         /* break */
+      case 'm': /* --ftp-account */
+        GetStr(&config->ftp_account, nextarg);
+        break;
       }
       break;
     case '#': /* added 19990617 larsa */
@@ -2830,6 +2833,8 @@ static void free_config_fields(struct Configurable *config)
     free(config->tp_url);
   if(config->tp_user)
     free(config->tp_user);
+  if(config->ftp_account)
+    free(config->ftp_account);
 
   curl_slist_free_all(config->quote); /* checks for config->quote == NULL */
   curl_slist_free_all(config->prequote);
@@ -3655,12 +3660,13 @@ operate(struct Configurable *config, int argc, char *argv[])
           curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
         }
 
-        /* curl 7.12.4 */
+        /* curl 7.13.0 */
         curl_easy_setopt(curl, CURLOPT_SOURCE_URL, config->tp_url);
         curl_easy_setopt(curl, CURLOPT_SOURCE_USERPWD, config->tp_user);
         curl_easy_setopt(curl, CURLOPT_SOURCE_PREQUOTE, config->tp_prequote);
         curl_easy_setopt(curl, CURLOPT_SOURCE_POSTQUOTE, config->tp_postquote);
         curl_easy_setopt(curl, CURLOPT_SOURCE_QUOTE, config->tp_quote);
+        curl_easy_setopt(curl, CURLOPT_FTP_ACCOUNT, config->ftp_account);
 
         retry_numretries = config->req_retry;
 
index 7fe4a1818f23dd083637bef6ada1e27dd9da8812..ebbfdab0b95edef9da601555c8cd91b34c8407ff 100644 (file)
@@ -31,7 +31,8 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46        \
  test517 test518 test210 test211 test212 test220 test221 test222       \
  test223 test224 test206 test207 test208 test209 test213 test240       \
  test241 test242 test519 test214 test215 test216 test217 test218       \
- test199 test225 test226 test227 test230 test231 test232
+ test199 test225 test226 test227 test230 test231 test232 test228       \
+ test229
 
 # The following tests have been removed from the dist since they no longer
 # work. We need to fix the test suite's FTPS server first, then bring them
diff --git a/tests/data/test228 b/tests/data/test228
new file mode 100644 (file)
index 0000000..85f7989
--- /dev/null
@@ -0,0 +1,44 @@
+# Server-side
+<reply>
+<data>
+data
+    to
+      see
+that FTP
+works
+  so does it?
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP RETR with ACCT
+ </name>
+ <command>
+ftp://%HOSTIP:%FTPPORT/228 --ftp-account "one count"
+</command>
+<file name="log/ftpserver.cmd">
+REPLY PASS 332 please provide account name
+REPLY ACCT 230 thank you
+</file>
+</client>
+
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous\r
+PASS curl_by_daniel@haxx.se\r
+ACCT one count\r
+PWD\r
+EPSV\r
+TYPE I\r
+SIZE 228\r
+RETR 228\r
+QUIT\r
+</protocol>
+</verify>
diff --git a/tests/data/test229 b/tests/data/test229
new file mode 100644 (file)
index 0000000..ea8ceb5
--- /dev/null
@@ -0,0 +1,32 @@
+# Server-side
+<reply>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP RETR with bad ACCT
+ </name>
+ <command>
+ftp://%HOSTIP:%FTPPORT/229 --ftp-account "one count"
+</command>
+<file name="log/ftpserver.cmd">
+REPLY PASS 332 please provide account name
+REPLY ACCT 532 bluah!
+</file>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous\r
+PASS curl_by_daniel@haxx.se\r
+ACCT one count\r
+</protocol>
+<errorcode>
+11
+</errorcode>
+</verify>