From 868488b518706a7eba8e380eeb51d71066a73df8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 17 Nov 2000 14:03:58 +0000 Subject: memory leak cleanup campaign --- lib/highlevel.c | 2 +- lib/http.c | 3 +- lib/url.c | 65 +++++--- src/main.c | 506 ++++++++++++++++++++++++++++++-------------------------- 4 files changed, 322 insertions(+), 254 deletions(-) diff --git a/lib/highlevel.c b/lib/highlevel.c index fbdde4bff..0e6ac8e27 100644 --- a/lib/highlevel.c +++ b/lib/highlevel.c @@ -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); diff --git a/lib/http.c b/lib/http.c index 70870f7b2..d5241acec 100644 --- a/lib/http.c +++ b/lib/http.c @@ -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; } diff --git a/lib/url.c b/lib/url.c index eea7808ea..057e163a6 100644 --- 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; diff --git a/src/main.c b/src/main.c index 2d1de3df1..f8a2a0422 100644 --- a/src/main.c +++ b/src/main.c @@ -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 : ""); - if (separator) { + if (urlnum > 1) { + fprintf(stderr, "\n[%d/%d]: %s --> %s\n", + i+1, urlnum, url, config.outfile ? config.outfile : ""); + 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) -- cgit v1.2.3