]> granicus.if.org Git - curl/commitdiff
memory leak cleanup campaign
authorDaniel Stenberg <daniel@haxx.se>
Fri, 17 Nov 2000 14:03:58 +0000 (14:03 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 17 Nov 2000 14:03:58 +0000 (14:03 +0000)
lib/highlevel.c
lib/http.c
lib/url.c
src/main.c

index fbdde4bff6b6203eae04f2b43998e1c67e01a848..0e6ac8e27a65a592b2e4030c0b008539bb02a0ae 100644 (file)
@@ -620,7 +620,7 @@ CURLcode curl_transfer(CURL *curl)
 {
   CURLcode res;
   struct UrlData *data = curl;
-  struct connectdata *c_connect;
+  struct connectdata *c_connect=NULL;
 
   pgrsStartNow(data);
 
index 70870f7b211212b8a69a3297b3a0986e8534f13c..d5241acec719656c70087eec667565c1b6485cee 100644 (file)
@@ -390,6 +390,7 @@ CURLcode http(struct connectdata *conn)
 
     if(co) {
       int count=0;
+      struct Cookie *store=co;
       /* now loop through all cookies that matched */
       while(co) {
         if(co->value && strlen(co->value)) {
@@ -405,7 +406,7 @@ CURLcode http(struct connectdata *conn)
       if(count) {
         add_buffer(req_buffer, "\r\n", 2);
       }
-      cookie_freelist(co); /* free the cookie list */
+      cookie_freelist(store); /* free the cookie list */
       co=NULL;
     }
 
index eea7808eabe99e914a954e0e101646fc0cdb5c76..057e163a6d9315b557c2dc43c0e1041eb5a7ec1f 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -685,26 +685,7 @@ CURLcode curl_disconnect(CURLconnect *c_connect)
   return CURLE_OK;
 }
 
-
-/*
- * NAME curl_connect()
- *
- * DESCRIPTION
- *
- * Connects to the peer server and performs the initial setup. This function
- * writes a connect handle to its second argument that is a unique handle for
- * this connect. This allows multiple connects from the same handle returned
- * by curl_open().
- *
- * EXAMPLE
- *
- * CURLCode result;
- * CURL curl;
- * CURLconnect connect;
- * result = curl_connect(curl, &connect);
- */
-
-CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
+static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
 {
   char *tmp;
   char *buf;
@@ -1537,6 +1518,50 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
   return CURLE_OK;
 }
 
+CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
+{
+  CURLcode code;
+  struct connectdata *conn;
+
+  /* call the stuff that needs to be called */
+  code = _connect(curl, in_connect);
+
+  if(CURLE_OK != code) {
+    /* We're not allowed to return failure with memory left allocated
+       in the connectdata struct, free those here */
+    conn = (struct connectdata *)*in_connect;
+    if(conn) {
+      if(conn->hostent_buf)
+        free(conn->hostent_buf);
+      free(conn);
+      *in_connect=NULL;
+    }
+  }
+  return code;
+}
+
+
+/*
+ * NAME curl_connect()
+ *
+ * DESCRIPTION
+ *
+ * Connects to the peer server and performs the initial setup. This function
+ * writes a connect handle to its second argument that is a unique handle for
+ * this connect. This allows multiple connects from the same handle returned
+ * by curl_open().
+ *
+ * EXAMPLE
+ *
+ * CURLCode result;
+ * CURL curl;
+ * CURLconnect connect;
+ * result = curl_connect(curl, &connect);
+ */
+
+
+
+
 CURLcode curl_done(CURLconnect *c_connect)
 {
   struct connectdata *conn = c_connect;
index 2d1de3df1060520b0c286f0856c9593eb2d68165..f8a2a042286d2911c179e8d7898b8cc0723c6928 100644 (file)
@@ -365,6 +365,7 @@ static char *my_get_token(const char *line);
 static void GetStr(char **string,
                   char *value)
 {
+  fprintf(stderr, "called\n");
   if(*string)
     free(*string);
   if(value && *value)
@@ -1278,6 +1279,8 @@ int main(int argc, char *argv[])
   int infilesize=-1; /* -1 means unknown */
   bool stillflags=TRUE;
 
+  bool allocuseragent=FALSE;
+
   CURL *curl;
   int res;
   int i;
@@ -1388,6 +1391,8 @@ int main(int argc, char *argv[])
              CURL_NAME "/" CURL_VERSION " (" OS ") " "%s", curl_version());
     config.useragent= useragent;
   }
+  else
+    allocuseragent = TRUE;
 #if 0
   fprintf(stderr, "URL: %s PROXY: %s\n", url, config.proxy?config.proxy:"none");
 #endif
@@ -1398,7 +1403,9 @@ int main(int argc, char *argv[])
   if(res != CURLE_OK)
     return res;
 
-  outfiles = config.outfile;           /* save outfile pattern befor expansion */
+  /* save outfile pattern befor expansion */
+  outfiles = strdup(config.outfile);
+
   if (!outfiles && !config.remotefile && urlnum > 1) {
 #ifdef CURL_SEPARATORS
     /* multiple files extracted to stdout, insert separators! */
@@ -1412,274 +1419,309 @@ int main(int argc, char *argv[])
 #endif
   }
   for (i = 0; (url = next_url(urls)); ++i) {
-    if (outfiles)
-      config.outfile = strdup(outfiles);
-
-#if 0
-  if(config.outfile && config.infile) {
-    helpf("you can't both upload and download!\n");
-    return CURLE_FAILED_INIT;
-  }
-#endif
+    if (outfiles) {
+      free(config.outfile);
+      config.outfile = outfiles;
+    }
  
-  if (config.outfile || config.remotefile) {
-    /* 
-     * We have specified a file name to store the result in, or we have
-     * decided we want to use the remote file name.
-     */
-
-    if(config.remotefile) {
-      /* Find and get the remote file name */
-      config.outfile=strstr(url, "://");
-      if(config.outfile)
-        config.outfile+=3;
-      else
-        config.outfile=url;
-      config.outfile = strrchr(config.outfile, '/');
-      if(!config.outfile || !strlen(++config.outfile)) {
-        helpf("Remote file name has no length!\n");
-        return CURLE_WRITE_ERROR;
+    if (config.outfile || config.remotefile) {
+      /* 
+       * We have specified a file name to store the result in, or we have
+       * decided we want to use the remote file name.
+       */
+      
+      if(!config.outfile && config.remotefile) {
+        /* Find and get the remote file name */
+        config.outfile=strstr(url, "://");
+        if(config.outfile)
+          config.outfile+=3;
+        else
+          config.outfile=url;
+        config.outfile = strdup(strrchr(config.outfile, '/'));
+        if(!config.outfile || !strlen(++config.outfile)) {
+          helpf("Remote file name has no length!\n");
+          return CURLE_WRITE_ERROR;
+        }
+      }
+      else {
+       /* fill '#1' ... '#9' terms from URL pattern */
+        char *outfile = config.outfile;
+        config.outfile = match_url(config.outfile, *urls);
+        free(outfile);
+      }
+      
+      if((0 == config.resume_from) && config.use_resume) {
+        /* we're told to continue where we are now, then we get the size of the
+           file as it is now and open it for append instead */
+        struct stat fileinfo;
+
+        if(0 == stat(config.outfile, &fileinfo)) {
+          /* set offset to current file size: */
+          config.resume_from = fileinfo.st_size;
+        }
+        /* else let offset remain 0 */
+      }
+      
+      if(config.resume_from) {
+        /* open file for output: */
+        outs.stream=(FILE *) fopen(config.outfile, config.resume_from?"ab":"wb");
+        if (!outs.stream) {
+          helpf("Can't open '%s'!\n", config.outfile);
+          return CURLE_WRITE_ERROR;
+        }
+      }
+      else {
+        outs.filename = config.outfile;
+        outs.stream = NULL; /* open when needed */
       }
     }
-    else       /* fill '#1' ... '#9' terms from URL pattern */
-      config.outfile = match_url(config.outfile, *urls);
-
-    if((0 == config.resume_from) && config.use_resume) {
-      /* we're told to continue where we are now, then we get the size of the
-        file as it is now and open it for append instead */
+    if (config.infile) {
+      /*
+       * We have specified a file to upload
+       */
       struct stat fileinfo;
 
-      if(0 == stat(config.outfile, &fileinfo)) {
-       /* set offset to current file size: */
-       config.resume_from = fileinfo.st_size;
+      /* If no file name part is given in the URL, we add this file name */
+      char *ptr=strstr(url, "://");
+      if(ptr)
+        ptr+=3;
+      else
+        ptr=url;
+      ptr = strrchr(ptr, '/');
+      if(!ptr || !strlen(++ptr)) {
+        /* The URL has no file name part, add the local file name. In order to
+           be able to do so, we have to create a new URL in another buffer.*/
+
+        urlbuffer=(char *)malloc(strlen(url) + strlen(config.infile) + 3);
+        if(!urlbuffer) {
+          helpf("out of memory\n");
+          return CURLE_OUT_OF_MEMORY;
+        }
+        if(ptr)
+          /* there is a trailing slash on the URL */
+          sprintf(urlbuffer, "%s%s", url, config.infile);
+        else
+          /* thers is no trailing slash on the URL */
+          sprintf(urlbuffer, "%s/%s", url, config.infile);
+        
+        url = urlbuffer; /* use our new URL instead! */
       }
-      /* else let offset remain 0 */
-    }
 
-    if(config.resume_from) {
-      /* open file for output: */
-      outs.stream=(FILE *) fopen(config.outfile, config.resume_from?"ab":"wb");
-      if (!outs.stream) {
-        helpf("Can't open '%s'!\n", config.outfile);
-        return CURLE_WRITE_ERROR;
+      infd=(FILE *) fopen(config.infile, "rb");
+      if (!infd || stat(config.infile, &fileinfo)) {
+        helpf("Can't open '%s'!\n", config.infile);
+        return CURLE_READ_ERROR;
       }
+      infilesize=fileinfo.st_size;
+      
     }
-    else {
-      outs.filename = config.outfile;
-      outs.stream = NULL; /* open when needed */
+    if((config.conf&CONF_UPLOAD) &&
+       config.use_resume &&
+       (0==config.resume_from)) {
+      config.resume_from = -1; /* -1 will then force get-it-yourself */
     }
-  }
-  if (config.infile) {
-    /*
-     * We have specified a file to upload
-     */
-    struct stat fileinfo;
-
-    /* If no file name part is given in the URL, we add this file name */
-    char *ptr=strstr(url, "://");
-    if(ptr)
-      ptr+=3;
-    else
-      ptr=url;
-    ptr = strrchr(ptr, '/');
-    if(!ptr || !strlen(++ptr)) {
-      /* The URL has no file name part, add the local file name. In order
-         to be able to do so, we have to create a new URL in another buffer.*/
-      urlbuffer=(char *)malloc(strlen(url) + strlen(config.infile) + 3);
-      if(!urlbuffer) {
-        helpf("out of memory\n");
-        return CURLE_OUT_OF_MEMORY;
+    if(config.headerfile) {
+      /* open file for output: */
+      if(strcmp(config.headerfile,"-")) {
+        heads.filename = config.headerfile;
+        headerfilep=NULL;
       }
-      if(ptr)
-        /* there is a trailing slash on the URL */
-        sprintf(urlbuffer, "%s%s", url, config.infile);
       else
-        /* thers is no trailing slash on the URL */
-        sprintf(urlbuffer, "%s/%s", url, config.infile);
-
-      url = urlbuffer; /* use our new URL instead! */
-    }
-
-    infd=(FILE *) fopen(config.infile, "rb");
-    if (!infd || stat(config.infile, &fileinfo)) {
-      helpf("Can't open '%s'!\n", config.infile);
-      return CURLE_READ_ERROR;
+        headerfilep=stdout;
+      heads.stream = headerfilep;
     }
-    infilesize=fileinfo.st_size;
-
-  }
-  if((config.conf&CONF_UPLOAD) &&
-     config.use_resume &&
-     (0==config.resume_from)) {
-    config.resume_from = -1; /* -1 will then force get-it-yourself */
-  }
-  if(config.headerfile) {
-    /* open file for output: */
-    if(strcmp(config.headerfile,"-"))
-    {
-      heads.filename = config.headerfile;
-      headerfilep=NULL;
-    }
-    else
-      headerfilep=stdout;
-    heads.stream = headerfilep;
-  }
-
-  if(outs.stream && isatty(fileno(outs.stream)) &&
-     !(config.conf&(CONF_UPLOAD|CONF_HTTPPOST)))
-    /* we send the output to a tty and it isn't an upload operation, therefore
-       we switch off the progress meter */
-    config.conf |= CONF_NOPROGRESS;
-
+    
+    if(outs.stream && isatty(fileno(outs.stream)) &&
+       !(config.conf&(CONF_UPLOAD|CONF_HTTPPOST)))
+      /* we send the output to a tty and it isn't an upload operation,
+         therefore we switch off the progress meter */
+      config.conf |= CONF_NOPROGRESS;
+    
 
-  if (urlnum > 1) {
-    fprintf(stderr, "\n[%d/%d]: %s --> %s\n", i+1, urlnum, url, config.outfile ? config.outfile : "<stdout>");
-    if (separator) {
+    if (urlnum > 1) {
+      fprintf(stderr, "\n[%d/%d]: %s --> %s\n",
+              i+1, urlnum, url, config.outfile ? config.outfile : "<stdout>");
+      if (separator) {
 #ifdef CURL_SEPARATORS
-      printf("%s%s\n", CURLseparator, url);
+        printf("%s%s\n", CURLseparator, url);
 #endif
 #ifdef MIME_SEPARATORS
-      printf("--%s\n", MIMEseparator);
-      printf("Content-ID: %s\n\n", url); 
+        printf("--%s\n", MIMEseparator);
+        printf("Content-ID: %s\n\n", url); 
 #endif
+      }
     }
-  }
 
-  if(!config.errors)
-    config.errors = stderr;
+    if(!config.errors)
+      config.errors = stderr;
 
 #ifdef WIN32
-  if(!config.outfile && !(config.conf & CONF_GETTEXT)) {
-    /* We get the output to stdout and we have not got the ASCII/text flag,
-       then set stdout to be binary */
-    setmode( 1, O_BINARY );
-  }
-#endif
-
-
-  main_init();
-
-  /* The new, v7-style easy-interface! */
-  curl = curl_easy_init();
-  if(curl) {
-    curl_easy_setopt(curl, CURLOPT_FILE, (FILE *)&outs);  /* where to store */
-    /* what call to write: */
-    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
-    curl_easy_setopt(curl, CURLOPT_INFILE, infd); /* for uploads */
-    /* size of uploaded file: */
-    curl_easy_setopt(curl, CURLOPT_INFILESIZE, infilesize);
-    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_VERBOSE, config.conf&CONF_VERBOSE);
-    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, config.conf&CONF_UPLOAD);
-    curl_easy_setopt(curl, CURLOPT_POST, config.conf&CONF_POST);
-    curl_easy_setopt(curl, CURLOPT_FTPLISTONLY, config.conf&CONF_FTPLISTONLY);
-    curl_easy_setopt(curl, CURLOPT_FTPAPPEND, config.conf&CONF_FTPAPPEND);
-    curl_easy_setopt(curl, CURLOPT_NETRC, config.conf&CONF_NETRC);
-    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,
-                     config.conf&CONF_FOLLOWLOCATION);
-    curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, config.conf&CONF_GETTEXT);
-    curl_easy_setopt(curl, CURLOPT_PUT, config.conf&CONF_PUT);
-    curl_easy_setopt(curl, CURLOPT_MUTE, config.conf&CONF_MUTE);
-    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);
-    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, config.postfields);
-
-    /* new in libcurl 7.2: */
-    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, config.postfieldsize);
-
-    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_RESUME_FROM,
-                     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_HTTPPOST, config.httppost);
-    curl_easy_setopt(curl, CURLOPT_SSLCERT, config.cert);
-    curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, config.cert_passwd);
-    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_WRITEHEADER, config.headerfile?&heads:NULL);
-    curl_easy_setopt(curl, CURLOPT_COOKIEFILE, config.cookiefile);
-    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);
-
-    /* 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);
-
-    if((config.progressmode == CURL_PROGRESS_BAR) &&
-       !(config.conf&(CONF_NOPROGRESS|CONF_MUTE))) {
-      /* we want the alternative style, then we have to implement it
-         ourselves! */
-      progressbarinit(&progressbar);
-      curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, myprogress);
-      curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar);
+    if(!config.outfile && !(config.conf & CONF_GETTEXT)) {
+      /* We get the output to stdout and we have not got the ASCII/text flag,
+         then set stdout to be binary */
+      setmode( 1, O_BINARY );
     }
+#endif
 
-    res = curl_easy_perform(curl);
 
-    if(config.writeout) {
-      ourWriteOut(curl, config.writeout);
-    }
-
-    /* always cleanup */
-    curl_easy_cleanup(curl);
+    main_init();
+
+    /* The new, v7-style easy-interface! */
+    curl = curl_easy_init();
+    if(curl) {
+      curl_easy_setopt(curl, CURLOPT_FILE, (FILE *)&outs); /* where to store */
+      /* what call to write: */
+      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
+      curl_easy_setopt(curl, CURLOPT_INFILE, infd); /* for uploads */
+      /* size of uploaded file: */
+      curl_easy_setopt(curl, CURLOPT_INFILESIZE, infilesize);
+      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_VERBOSE, config.conf&CONF_VERBOSE);
+      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, config.conf&CONF_UPLOAD);
+      curl_easy_setopt(curl, CURLOPT_POST, config.conf&CONF_POST);
+      curl_easy_setopt(curl, CURLOPT_FTPLISTONLY,
+                       config.conf&CONF_FTPLISTONLY);
+      curl_easy_setopt(curl, CURLOPT_FTPAPPEND, config.conf&CONF_FTPAPPEND);
+      curl_easy_setopt(curl, CURLOPT_NETRC, config.conf&CONF_NETRC);
+      curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,
+                       config.conf&CONF_FOLLOWLOCATION);
+      curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, config.conf&CONF_GETTEXT);
+      curl_easy_setopt(curl, CURLOPT_PUT, config.conf&CONF_PUT);
+      curl_easy_setopt(curl, CURLOPT_MUTE, config.conf&CONF_MUTE);
+      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);
+      curl_easy_setopt(curl, CURLOPT_POSTFIELDS, config.postfields);
+      
+      /* new in libcurl 7.2: */
+      curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, config.postfieldsize);
+
+      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_RESUME_FROM,
+                       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_HTTPPOST, config.httppost);
+      curl_easy_setopt(curl, CURLOPT_SSLCERT, config.cert);
+      curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, config.cert_passwd);
+      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_WRITEHEADER,
+                       config.headerfile?&heads:NULL);
+      curl_easy_setopt(curl, CURLOPT_COOKIEFILE, config.cookiefile);
+      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);
+      
+      /* 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);
+
+      if((config.progressmode == CURL_PROGRESS_BAR) &&
+         !(config.conf&(CONF_NOPROGRESS|CONF_MUTE))) {
+        /* we want the alternative style, then we have to implement it
+           ourselves! */
+        progressbarinit(&progressbar);
+        curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, myprogress);
+        curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar);
+      }
 
-    if((res!=CURLE_OK) && config.showerror)
-      fprintf(config.errors, "curl: (%d) %s\n", res, errorbuffer);
-  }
-  else
-    fprintf(config.errors, "curl: failed to init libcurl!\n");
+      res = curl_easy_perform(curl);
 
-  main_free();
+      if(config.writeout) {
+        ourWriteOut(curl, config.writeout);
+      }
 
-  if((config.errors != stderr) &&
-     (config.errors != stdout))
-    /* it wasn't directed to stdout or stderr so close the file! */
-    fclose(config.errors);
+      /* always cleanup */
+      curl_easy_cleanup(curl);
 
-  if(config.headerfile && !headerfilep && heads.stream)
-    fclose(heads.stream);
+      if((res!=CURLE_OK) && config.showerror)
+        fprintf(config.errors, "curl: (%d) %s\n", res, errorbuffer);
+    }
+    else
+      fprintf(config.errors, "curl: failed to init libcurl!\n");
 
-  if(urlbuffer)
-    free(urlbuffer);
-  if (config.outfile && outs.stream)
-    fclose(outs.stream);
-  if (config.infile)
-    fclose(infd);
-  if(headerfilep)
-    fclose(headerfilep);
+    main_free();
 
-  if(config.url)
-    free(config.url);
+    if((config.errors != stderr) &&
+       (config.errors != stdout))
+      /* it wasn't directed to stdout or stderr so close the file! */
+      fclose(config.errors);
+    
+    if(config.headerfile && !headerfilep && heads.stream)
+      fclose(heads.stream);
+
+    if(urlbuffer)
+      free(urlbuffer);
+    if (config.outfile && outs.stream)
+      fclose(outs.stream);
+    if (config.infile)
+      fclose(infd);
+    if(headerfilep)
+      fclose(headerfilep);
+    
+    if(url)
+      free(url);
 
-  if(url)
-    free(url);
-  if(config.outfile && !config.remotefile)
-    free(config.outfile);
   }
 #ifdef MIME_SEPARATORS
   if (separator)
     printf("--%s--\n", MIMEseparator);
 #endif
 
+  if(config.url)
+    free(config.url);
+  if(config.userpwd)
+    free(config.userpwd);
+  if(config.postfields)
+    free(config.postfields);
+  if(config.proxy)
+    free(config.proxy);
+  if(config.proxyuserpwd)
+    free(config.proxyuserpwd);
+  if(config.cookie)
+    free(config.cookie);
+  if(config.cookiefile)
+    free(config.cookiefile);
+  if(config.krb4level)
+    free(config.krb4level);
+  if(config.headerfile)
+    free(config.headerfile);
+  if(config.outfile)
+    free(config.outfile);
+  if(config.infile)
+    free(config.infile);
+  if(config.range)
+    free(config.range);
+  if(config.customrequest)
+    free(config.customrequest);
+  if(config.writeout)
+    free(config.writeout);
+
+  if(config.httppost)
+    curl_formfree(config.httppost);
+
+  if(allocuseragent)
+    free(config.useragent);
+
   /* cleanup memory used for URL globbing patterns */
   glob_cleanup(urls);
 
@@ -1687,7 +1729,7 @@ int main(int argc, char *argv[])
   curl_slist_free_all(config.postquote); /*  */
   curl_slist_free_all(config.headers); /*  */
 
-  return(res);
+  return res;
 }
 
 static char *my_get_line(FILE *fp)