- Added the --libcurl [file] option to curl. Append this option to any
authorDaniel Stenberg <daniel@haxx.se>
Thu, 25 Jan 2007 15:58:00 +0000 (15:58 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 25 Jan 2007 15:58:00 +0000 (15:58 +0000)
  ordinary curl command line, and you will get a libcurl-using source code
  written to the file that does the equivalent operation of what your command
  line operation does!

CHANGES
RELEASE-NOTES
docs/curl.1
src/main.c

diff --git a/CHANGES b/CHANGES
index 888b417..5271bd0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,12 @@
 
                                   Changelog
 
+Daniel (25 January 2007)
+- Added the --libcurl [file] option to curl. Append this option to any
+  ordinary curl command line, and you will get a libcurl-using source code
+  written to the file that does the equivalent operation of what your command
+  line operation does!
+
 Dan F (24 January 2007)
 - Fixed a dangling pointer problem that prevented the http_proxy environment
   variable from being properly used in many cases (and caused test case 63
index 6edc169..b051279 100644 (file)
@@ -2,7 +2,7 @@ Curl and libcurl 7.16.1
 
  Public curl release number:               97
  Releases counted from the very beginning: 124
- Available command line options:           114
+ Available command line options:           115
  Available curl_easy_setopt() options:     137
  Number of public functions in libcurl:    54
  Amount of public web site mirrors:        39
@@ -15,6 +15,7 @@ This release includes the following changes:
  o CURLOPT_CLOSEPOLICY is now deprecated
  o --ftp-ssl-ccc and CURLOPT_FTP_SSL_CCC were added
  o HTTP support for non-ASCII platforms
+ o --libcurl was added
 
 This release includes the following bugfixes:
 
index 4830179..021f950 100644 (file)
@@ -599,7 +599,7 @@ line. So, it could look similar to this:
 
 url = "http://curl.haxx.se/docs/"
 
-This option can be used multiple times.
+This option can be used multiple times to load multiple config files.
 
 When curl is invoked, it always (unless \fI-q\fP is used) checks for a default
 config file and uses it if found. The default config file is checked for in
@@ -614,6 +614,12 @@ resort the '%USERPROFILE%\Application Data'.
 2) On windows, if there is no _curlrc file in the home dir, it checks for one
 in the same dir the executable curl is placed. On unix-like systems, it will
 simply try to load .curlrc from the determined home dir.
+.IP "--libcurl <file>"
+Append this option to any ordinary curl command line, and you will get a
+libcurl-using source code written to the file that does the equivalent
+operation of what your command line operation does!
+
+If this option is used several times, the last given file name will be used.
 .IP "--limit-rate <speed>"
 Specify the maximum transfer rate you want curl to use. This feature is useful
 if you have a limited pipe and you'd like your transfer not use your entire
index 1994f0f..bee010c 100644 (file)
@@ -366,6 +366,8 @@ struct Configurable {
   bool ignorecl; /* --ignore-content-length */
   bool disable_sessionid;
 
+  char *libcurl; /* output libcurl code to this file name */
+
   struct OutStruct *outs;
 };
 
@@ -549,6 +551,7 @@ static void help(void)
     "    --krb4 <level>  Enable krb4 with specified security level (F)",
     " -k/--insecure      Allow connections to SSL sites without certs (H)",
     " -K/--config        Specify which config file to read",
+    "    --libcurl <file> Dump libcurl equivalent code of this command line",
     " -l/--list-only     List only names of an FTP directory (F)",
     "    --limit-rate <rate> Limit transfer speed to this rate",
     "    --local-port <num>[-num] Force use of these local port numbers\n",
@@ -1362,6 +1365,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
     {"$w", "no-sessionid", FALSE},
     {"$x", "ftp-ssl-control", FALSE},
     {"$y", "ftp-ssl-ccc", FALSE},
+    {"$z", "libcurl",    TRUE},
 
     {"0", "http1.0",     FALSE},
     {"1", "tlsv1",       FALSE},
@@ -1789,6 +1793,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
       case 'y': /* --ftp-ssl-ccc */
         config->ftp_ssl_ccc ^= TRUE;
         break;
+      case 'z': /* --libcurl */
+        GetStr(&config->libcurl, nextarg);
+        break;
       }
       break;
     case '#': /* --progress-bar */
@@ -2711,12 +2718,6 @@ static size_t my_fread(void *buffer, size_t sz, size_t nmemb, void *userp)
   struct InStruct *in=(struct InStruct *)userp;
 
   rc = fread(buffer, sz, nmemb, in->stream);
-#if 0
-  if (sizeof(rc) > sizeof(unsigned int))
-    fprintf(stderr, "CALLBACK returning %lu bytes data\n", rc);
-  else
-    fprintf(stderr, "CALLBACK returning %u bytes data\n", rc);
-#endif
   return rc;
 }
 
@@ -3201,6 +3202,129 @@ output_expected(char* url, char* uploadfile)
   return FALSE; /* non-HTTP upload, probably no output should be expected */
 }
 
+#define my_setopt(x,y,z) _my_setopt(x, #y, y, z)
+
+static struct curl_slist *easycode;
+
+CURLcode _my_setopt(CURL *curl, const char *name, CURLoption tag, ...);
+
+CURLcode _my_setopt(CURL *curl, const char *name, CURLoption tag, ...)
+{
+  va_list arg;
+  CURLcode ret;
+  char buffer[128];
+  char value[256];
+  bool remark=FALSE;
+
+  va_start(arg, tag);
+
+  if(tag < CURLOPTTYPE_OBJECTPOINT) {
+    long lval = va_arg(arg, long);
+    snprintf(value, sizeof(value), "%ld", lval);
+    ret = curl_easy_setopt(curl, tag, lval);
+
+  }
+  else if(tag < CURLOPTTYPE_OFF_T) {
+    /* we treat both object and function pointers like this */
+    void *pval = va_arg(arg, void *);
+    unsigned char *ptr = (unsigned char *)pval;
+
+    /* attempt to figure out if it is a string (since the tag numerical doesn't
+       offer this info) and then output it as a string if so */
+    if(pval && isgraph(ptr[0]) && isgraph(ptr[1]))
+      snprintf(value, sizeof(value), "\"%s\"", (char *)ptr);
+    else if(pval) {
+      snprintf(value, sizeof(value), "%p", pval);
+      remark = TRUE;
+    }
+    else {
+      strcpy(value, "NULL"); /* value fits more than 5 bytes */
+    }
+    ret = curl_easy_setopt(curl, tag, pval);
+
+  }
+  else {
+    curl_off_t oval = va_arg(arg, curl_off_t);
+    snprintf(value, sizeof(value), "(curl_off_t)"CURL_FORMAT_OFF_T, oval);
+    ret = curl_easy_setopt(curl, tag, oval);
+  }
+
+  sprintf(buffer, "%scurl_easy_setopt(hnd, %s, %s);%s",
+          remark?"/* ":"",
+          name, value,
+          remark?" [REMARK] */":"");
+
+  easycode = curl_slist_append(easycode, buffer);
+
+  va_end(arg);
+
+  return ret;
+}
+
+static const char *srchead[]={
+  "/********* Sample code generated by the curl command line tool **********",
+  " * Lines with [REMARK] below might need to be modified to make this code ",
+  " * usable. Add appropriate error code checking  where appropriate.",
+  " * Compile this with a suitable header include path. Then link with ",
+  " * libcurl.",
+  " * If you use any *_LARGE options, make sure your compiler figure",
+  " * out the correct size for the curl_off_t variable.",
+  " ************************************************************************/",
+  "[m]",
+  "#include <curl/curl.h>",
+  "",
+  "int main(int argc, char *argv[])",
+  "{",
+  "  CURLcode ret;",
+  NULL
+};
+
+static void dumpeasycode(struct Configurable *config)
+{
+  struct curl_slist *ptr = easycode;
+  char *o = config->libcurl;
+
+  if(o) {
+    FILE *out;
+    bool fopened = FALSE;
+    if(strcmp(o, "-")) {
+      out = fopen(o, "wt");
+      fopened = TRUE;
+    }
+    else
+      out= stdout;
+    if(!out)
+      warnf(config, "Failed to open %s to write libcurl code!\n", o);
+    else {
+      int i;
+      const char *c;
+
+      for(i=0; (c = srchead[i]); i++) {
+        if(!memcmp((char *)c, "[m]", 3)) {
+#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS > 32)
+          fprintf(out, "#define _FILE_OFFSET_BITS %d "
+                  "/* for curl_off_t magic */\n",
+                  _FILE_OFFSET_BITS);
+#endif
+        }
+        else
+          fprintf(out, "%s\n", c);
+      }
+
+      while(ptr) {
+        fprintf(out, "  %s\n", ptr->data);
+        ptr = ptr->next;
+      }
+      fprintf(out,
+              "}\n"
+              "/* */\n");
+      if(fopened)
+        fclose(out);
+    }
+  }
+  curl_slist_free_all(easycode);
+}
+
 static int
 operate(struct Configurable *config, int argc, char *argv[])
 {
@@ -3433,7 +3557,7 @@ operate(struct Configurable *config, int argc, char *argv[])
     clean_getout(config);
     return CURLE_FAILED_INIT;
   }
-
+  easycode = curl_slist_append(easycode, "CURL *hnd = curl_easy_init();");
 
   if (config->list_engines) {
     struct curl_slist *engines = NULL;
@@ -3781,272 +3905,271 @@ operate(struct Configurable *config, int argc, char *argv[])
 #endif
 
         if(1 == config->tcp_nodelay)
-          curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
+          my_setopt(curl, CURLOPT_TCP_NODELAY, 1);
 
         /* where to store */
-        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (FILE *)&outs);
+        my_setopt(curl, CURLOPT_WRITEDATA, (FILE *)&outs);
         /* what call to write */
-        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
+        my_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
 
         /* for uploads */
         input.stream = infd;
         input.config = config;
-        curl_easy_setopt(curl, CURLOPT_READDATA, &input);
+        my_setopt(curl, CURLOPT_READDATA, &input);
         /* what call to read */
-        curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_fread);
+        my_setopt(curl, CURLOPT_READFUNCTION, my_fread);
 
         /* libcurl 7.12.3 business: */
-        curl_easy_setopt(curl, CURLOPT_IOCTLDATA, &input);
-        curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
+        my_setopt(curl, CURLOPT_IOCTLDATA, &input);
+        my_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
 
         if(config->recvpersecond)
           /* tell libcurl to use a smaller sized buffer as it allows us to
              make better sleeps! 7.9.9 stuff! */
-          curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, config->recvpersecond);
+          my_setopt(curl, CURLOPT_BUFFERSIZE, config->recvpersecond);
 
         /* size of uploaded file: */
-        curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, uploadfilesize);
-        curl_easy_setopt(curl, CURLOPT_URL, url);     /* what to fetch */
-        curl_easy_setopt(curl, CURLOPT_PROXY, config->proxy); /* proxy to use */
-        curl_easy_setopt(curl, CURLOPT_HEADER, config->conf&CONF_HEADER);
-        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, config->conf&CONF_NOPROGRESS);
-        curl_easy_setopt(curl, CURLOPT_NOBODY, config->conf&CONF_NOBODY);
-        curl_easy_setopt(curl, CURLOPT_FAILONERROR,
-                         config->conf&CONF_FAILONERROR);
-        curl_easy_setopt(curl, CURLOPT_UPLOAD, uploadfile?TRUE:FALSE);
-        curl_easy_setopt(curl, CURLOPT_FTPLISTONLY,
-                         config->conf&CONF_FTPLISTONLY);
-        curl_easy_setopt(curl, CURLOPT_FTPAPPEND, config->conf&CONF_FTPAPPEND);
+        my_setopt(curl, CURLOPT_INFILESIZE_LARGE, uploadfilesize);
+        my_setopt(curl, CURLOPT_URL, url);     /* what to fetch */
+        my_setopt(curl, CURLOPT_PROXY, config->proxy); /* proxy to use */
+        my_setopt(curl, CURLOPT_HEADER, config->conf&CONF_HEADER);
+        my_setopt(curl, CURLOPT_NOPROGRESS, config->conf&CONF_NOPROGRESS);
+        my_setopt(curl, CURLOPT_NOBODY, config->conf&CONF_NOBODY);
+        my_setopt(curl, CURLOPT_FAILONERROR,
+                  config->conf&CONF_FAILONERROR);
+        my_setopt(curl, CURLOPT_UPLOAD, uploadfile?TRUE:FALSE);
+        my_setopt(curl, CURLOPT_FTPLISTONLY,
+                  config->conf&CONF_FTPLISTONLY);
+        my_setopt(curl, CURLOPT_FTPAPPEND, config->conf&CONF_FTPAPPEND);
 
         if (config->conf&CONF_NETRC_OPT)
-          curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
+          my_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
         else if (config->conf&CONF_NETRC)
-          curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_REQUIRED);
+          my_setopt(curl, CURLOPT_NETRC, CURL_NETRC_REQUIRED);
         else
-          curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_IGNORED);
-
-        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,
-                         config->conf&CONF_FOLLOWLOCATION);
-        curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH,
-                         config->conf&CONF_UNRESTRICTED_AUTH);
-        curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, config->conf&CONF_GETTEXT);
-        curl_easy_setopt(curl, CURLOPT_USERPWD, config->userpwd);
-        curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, config->proxyuserpwd);
-        curl_easy_setopt(curl, CURLOPT_RANGE, config->range);
-        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
-        curl_easy_setopt(curl, CURLOPT_TIMEOUT, config->timeout);
+          my_setopt(curl, CURLOPT_NETRC, CURL_NETRC_IGNORED);
+
+        my_setopt(curl, CURLOPT_FOLLOWLOCATION,
+                  config->conf&CONF_FOLLOWLOCATION);
+        my_setopt(curl, CURLOPT_UNRESTRICTED_AUTH,
+                  config->conf&CONF_UNRESTRICTED_AUTH);
+        my_setopt(curl, CURLOPT_TRANSFERTEXT, config->conf&CONF_GETTEXT);
+        my_setopt(curl, CURLOPT_USERPWD, config->userpwd);
+        my_setopt(curl, CURLOPT_PROXYUSERPWD, config->proxyuserpwd);
+        my_setopt(curl, CURLOPT_RANGE, config->range);
+        my_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
+        my_setopt(curl, CURLOPT_TIMEOUT, config->timeout);
 
         switch(config->httpreq) {
         case HTTPREQ_SIMPLEPOST:
-          curl_easy_setopt(curl, CURLOPT_POSTFIELDS, config->postfields);
-          curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, config->postfieldsize);
+          my_setopt(curl, CURLOPT_POSTFIELDS, config->postfields);
+          my_setopt(curl, CURLOPT_POSTFIELDSIZE, config->postfieldsize);
           break;
         case HTTPREQ_POST:
-          curl_easy_setopt(curl, CURLOPT_HTTPPOST, config->httppost);
+          my_setopt(curl, CURLOPT_HTTPPOST, config->httppost);
           break;
         default:
           break;
         }
-        curl_easy_setopt(curl, CURLOPT_REFERER, config->referer);
-        curl_easy_setopt(curl, CURLOPT_AUTOREFERER,
-                         config->conf&CONF_AUTO_REFERER);
-        curl_easy_setopt(curl, CURLOPT_USERAGENT, config->useragent);
-        curl_easy_setopt(curl, CURLOPT_FTPPORT, config->ftpport);
-        curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT,
-                         config->low_speed_limit);
-        curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, config->low_speed_time);
-        curl_easy_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE,
-                         config->sendpersecond);
-        curl_easy_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE,
-                         config->recvpersecond);
-
-        curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE,
-                         config->use_resume?config->resume_from:0);
-        curl_easy_setopt(curl, CURLOPT_COOKIE, config->cookie);
-        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, config->headers);
-        curl_easy_setopt(curl, CURLOPT_SSLCERT, config->cert);
-        curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
-        curl_easy_setopt(curl, CURLOPT_SSLKEY, config->key);
-        curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, config->key_type);
-        curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, config->key_passwd);
+        my_setopt(curl, CURLOPT_REFERER, config->referer);
+        my_setopt(curl, CURLOPT_AUTOREFERER,
+                  config->conf&CONF_AUTO_REFERER);
+        my_setopt(curl, CURLOPT_USERAGENT, config->useragent);
+        my_setopt(curl, CURLOPT_FTPPORT, config->ftpport);
+        my_setopt(curl, CURLOPT_LOW_SPEED_LIMIT,
+                  config->low_speed_limit);
+        my_setopt(curl, CURLOPT_LOW_SPEED_TIME, config->low_speed_time);
+        my_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE,
+                  config->sendpersecond);
+        my_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE,
+                  config->recvpersecond);
+        my_setopt(curl, CURLOPT_RESUME_FROM_LARGE,
+                  config->use_resume?config->resume_from:0);
+        my_setopt(curl, CURLOPT_COOKIE, config->cookie);
+        my_setopt(curl, CURLOPT_HTTPHEADER, config->headers);
+        my_setopt(curl, CURLOPT_SSLCERT, config->cert);
+        my_setopt(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
+        my_setopt(curl, CURLOPT_SSLKEY, config->key);
+        my_setopt(curl, CURLOPT_SSLKEYTYPE, config->key_type);
+        my_setopt(curl, CURLOPT_SSLKEYPASSWD, config->key_passwd);
 
         /* default to strict verifyhost */
-        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
+        my_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
         if(config->cacert || config->capath) {
           if (config->cacert)
-            curl_easy_setopt(curl, CURLOPT_CAINFO, config->cacert);
+            my_setopt(curl, CURLOPT_CAINFO, config->cacert);
 
           if (config->capath)
-            curl_easy_setopt(curl, CURLOPT_CAPATH, config->capath);
-          curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE);
+            my_setopt(curl, CURLOPT_CAPATH, config->capath);
+          my_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE);
         }
         if(config->insecure_ok) {
           /* new stuff needed for libcurl 7.10 */
-          curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
-          curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);
+          my_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+          my_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);
         }
 
         if((config->conf&CONF_NOBODY) ||
            config->remote_time) {
           /* no body or use remote time */
-          curl_easy_setopt(curl, CURLOPT_FILETIME, TRUE);
+          my_setopt(curl, CURLOPT_FILETIME, TRUE);
         }
 
-        curl_easy_setopt(curl, CURLOPT_MAXREDIRS, config->maxredirs);
-        curl_easy_setopt(curl, CURLOPT_CRLF, config->crlf);
-        curl_easy_setopt(curl, CURLOPT_QUOTE, config->quote);
-        curl_easy_setopt(curl, CURLOPT_POSTQUOTE, config->postquote);
-        curl_easy_setopt(curl, CURLOPT_PREQUOTE, config->prequote);
-        curl_easy_setopt(curl, CURLOPT_WRITEHEADER,
-                         config->headerfile?&heads:NULL);
-        curl_easy_setopt(curl, CURLOPT_COOKIEFILE, config->cookiefile);
+        my_setopt(curl, CURLOPT_MAXREDIRS, config->maxredirs);
+        my_setopt(curl, CURLOPT_CRLF, config->crlf);
+        my_setopt(curl, CURLOPT_QUOTE, config->quote);
+        my_setopt(curl, CURLOPT_POSTQUOTE, config->postquote);
+        my_setopt(curl, CURLOPT_PREQUOTE, config->prequote);
+        my_setopt(curl, CURLOPT_WRITEHEADER,
+                  config->headerfile?&heads:NULL);
+        my_setopt(curl, CURLOPT_COOKIEFILE, config->cookiefile);
         /* cookie jar was added in 7.9 */
         if(config->cookiejar)
-          curl_easy_setopt(curl, CURLOPT_COOKIEJAR, config->cookiejar);
+          my_setopt(curl, CURLOPT_COOKIEJAR, config->cookiejar);
         /* cookie session added in 7.9.7 */
-        curl_easy_setopt(curl, CURLOPT_COOKIESESSION, config->cookiesession);
+        my_setopt(curl, CURLOPT_COOKIESESSION, config->cookiesession);
 
-        curl_easy_setopt(curl, CURLOPT_SSLVERSION, config->ssl_version);
-        curl_easy_setopt(curl, CURLOPT_TIMECONDITION, config->timecond);
-        curl_easy_setopt(curl, CURLOPT_TIMEVALUE, config->condtime);
-        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
-        curl_easy_setopt(curl, CURLOPT_STDERR, config->errors);
+        my_setopt(curl, CURLOPT_SSLVERSION, config->ssl_version);
+        my_setopt(curl, CURLOPT_TIMECONDITION, config->timecond);
+        my_setopt(curl, CURLOPT_TIMEVALUE, config->condtime);
+        my_setopt(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
+        my_setopt(curl, CURLOPT_STDERR, config->errors);
 
         /* three new ones in libcurl 7.3: */
-        curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, config->proxytunnel);
-        curl_easy_setopt(curl, CURLOPT_INTERFACE, config->iface);
-        curl_easy_setopt(curl, CURLOPT_KRB4LEVEL, config->krb4level);
+        my_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, config->proxytunnel);
+        my_setopt(curl, CURLOPT_INTERFACE, config->iface);
+        my_setopt(curl, CURLOPT_KRB4LEVEL, config->krb4level);
 
         progressbarinit(&progressbar, config);
         if((config->progressmode == CURL_PROGRESS_BAR) &&
            !(config->conf&(CONF_NOPROGRESS|CONF_MUTE))) {
           /* we want the alternative style, then we have to implement it
              ourselves! */
-          curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, myprogress);
-          curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar);
+          my_setopt(curl, CURLOPT_PROGRESSFUNCTION, myprogress);
+          my_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar);
         }
 
         /* new in libcurl 7.6.2: */
-        curl_easy_setopt(curl, CURLOPT_TELNETOPTIONS, config->telnet_options);
+        my_setopt(curl, CURLOPT_TELNETOPTIONS, config->telnet_options);
 
         /* new in libcurl 7.7: */
-        curl_easy_setopt(curl, CURLOPT_RANDOM_FILE, config->random_file);
-        curl_easy_setopt(curl, CURLOPT_EGDSOCKET, config->egd_file);
-        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, config->connecttimeout);
+        my_setopt(curl, CURLOPT_RANDOM_FILE, config->random_file);
+        my_setopt(curl, CURLOPT_EGDSOCKET, config->egd_file);
+        my_setopt(curl, CURLOPT_CONNECTTIMEOUT, config->connecttimeout);
 
         if(config->cipher_list)
-          curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list);
+          my_setopt(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list);
 
         if(config->httpversion)
-          curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, config->httpversion);
+          my_setopt(curl, CURLOPT_HTTP_VERSION, config->httpversion);
 
         /* new in libcurl 7.9.2: */
         if(config->disable_epsv)
           /* disable it */
-          curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, FALSE);
+          my_setopt(curl, CURLOPT_FTP_USE_EPSV, FALSE);
 
         /* new in libcurl 7.10.5 */
         if(config->disable_eprt)
           /* disable it */
-          curl_easy_setopt(curl, CURLOPT_FTP_USE_EPRT, FALSE);
+          my_setopt(curl, CURLOPT_FTP_USE_EPRT, FALSE);
 
         /* new in libcurl 7.10.6 (default is Basic) */
         if(config->authtype)
-          curl_easy_setopt(curl, CURLOPT_HTTPAUTH, config->authtype);
+          my_setopt(curl, CURLOPT_HTTPAUTH, config->authtype);
 
         /* new in curl 7.9.7 */
         if(config->trace_dump) {
-          curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
-          curl_easy_setopt(curl, CURLOPT_DEBUGDATA, config);
-          curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE);
+          my_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
+          my_setopt(curl, CURLOPT_DEBUGDATA, config);
+          my_setopt(curl, CURLOPT_VERBOSE, TRUE);
         }
 
         res = CURLE_OK;
 
         /* new in curl ?? */
         if (config->engine) {
-          res = curl_easy_setopt(curl, CURLOPT_SSLENGINE, config->engine);
-          curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1);
+          res = my_setopt(curl, CURLOPT_SSLENGINE, config->engine);
+          my_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1);
         }
 
         if (res != CURLE_OK)
            goto show_error;
 
         /* new in curl 7.10 */
-        curl_easy_setopt(curl, CURLOPT_ENCODING,
+        my_setopt(curl, CURLOPT_ENCODING,
                          (config->encoding) ? "" : NULL);
 
         /* new in curl 7.10.7 */
-        curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS,
+        my_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS,
                          config->ftp_create_dirs);
         if(config->proxyanyauth)
-          curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
+          my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
         else if(config->proxyntlm)
-          curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
+          my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
         else if(config->proxydigest)
-          curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
+          my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
         else if(config->proxybasic)
-          curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
+          my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
 
         /* new in curl 7.10.8 */
         if(config->max_filesize)
-          curl_easy_setopt(curl, CURLOPT_MAXFILESIZE_LARGE,
+          my_setopt(curl, CURLOPT_MAXFILESIZE_LARGE,
                            config->max_filesize);
 
         if(4 == config->ip_version)
-          curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+          my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
         else if(6 == config->ip_version)
-          curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
+          my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
         else
-          curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER);
+          my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER);
 
         /* new in curl 7.15.5 */
         if(config->ftp_ssl_reqd)
-          curl_easy_setopt(curl, CURLOPT_FTP_SSL, CURLFTPSSL_ALL);
+          my_setopt(curl, CURLOPT_FTP_SSL, CURLFTPSSL_ALL);
 
         /* new in curl 7.11.0 */
         else if(config->ftp_ssl)
-          curl_easy_setopt(curl, CURLOPT_FTP_SSL, CURLFTPSSL_TRY);
+          my_setopt(curl, CURLOPT_FTP_SSL, CURLFTPSSL_TRY);
 
         /* new in curl 7.16.0 */
         else if(config->ftp_ssl_control)
-          curl_easy_setopt(curl, CURLOPT_FTP_SSL, CURLFTPSSL_CONTROL);
+          my_setopt(curl, CURLOPT_FTP_SSL, CURLFTPSSL_CONTROL);
 
         /* new in curl 7.16.1 */
         if(config->ftp_ssl_ccc)
-          curl_easy_setopt(curl, CURLOPT_FTP_SSL_CCC, TRUE);
+          my_setopt(curl, CURLOPT_FTP_SSL_CCC, TRUE);
 
         /* new in curl 7.11.1, modified in 7.15.2 */
         if(config->socksproxy) {
-          curl_easy_setopt(curl, CURLOPT_PROXY, config->socksproxy);
-          curl_easy_setopt(curl, CURLOPT_PROXYTYPE, config->socksver);
+          my_setopt(curl, CURLOPT_PROXY, config->socksproxy);
+          my_setopt(curl, CURLOPT_PROXYTYPE, config->socksver);
         }
 
         /* curl 7.13.0 */
-        curl_easy_setopt(curl, CURLOPT_FTP_ACCOUNT, config->ftp_account);
+        my_setopt(curl, CURLOPT_FTP_ACCOUNT, config->ftp_account);
 
-        curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, config->ignorecl);
+        my_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, config->ignorecl);
 
         /* curl 7.14.2 */
-        curl_easy_setopt(curl, CURLOPT_FTP_SKIP_PASV_IP, config->ftp_skip_ip);
+        my_setopt(curl, CURLOPT_FTP_SKIP_PASV_IP, config->ftp_skip_ip);
 
         /* curl 7.15.1 */
-        curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, config->ftp_filemethod);
+        my_setopt(curl, CURLOPT_FTP_FILEMETHOD, config->ftp_filemethod);
 
         /* curl 7.15.2 */
         if(config->localport) {
-          curl_easy_setopt(curl, CURLOPT_LOCALPORT, config->localport);
-          curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE,
-                           config->localportrange);
+          my_setopt(curl, CURLOPT_LOCALPORT, config->localport);
+          my_setopt(curl, CURLOPT_LOCALPORTRANGE,
+                    config->localportrange);
         }
 
         /* curl 7.15.5 */
-        curl_easy_setopt(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER,
-                         config->ftp_alternative_to_user);
+        my_setopt(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER,
+                  config->ftp_alternative_to_user);
 
         /* curl 7.16.0 */
-        curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE,
-                         !config->disable_sessionid);
+        my_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE,
+                  !config->disable_sessionid);
 
         retry_numretries = config->req_retry;
 
@@ -4054,6 +4177,8 @@ operate(struct Configurable *config, int argc, char *argv[])
 
         do {
           res = curl_easy_perform(curl);
+          easycode = curl_slist_append(easycode,
+                                       "ret = curl_easy_perform(hnd);");
 
           /* if retry-max-time is non-zero, make sure we haven't exceeded the
              time */
@@ -4295,6 +4420,7 @@ quit_curl:
 
   /* cleanup the curl handle! */
   curl_easy_cleanup(curl);
+  easycode = curl_slist_append(easycode, "curl_easy_cleanup(hnd);");
 
   if(config->headerfile && !headerfilep && heads.stream)
     fclose(heads.stream);
@@ -4310,6 +4436,8 @@ quit_curl:
 
   main_free(); /* cleanup */
 
+  dumpeasycode(config);
+
   return res;
 }