diff --git a/lib/cookie.c b/lib/cookie.c index b9acb944b..f303363d8 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -384,6 +384,8 @@ Curl_cookie_add(struct CookieInfo *c, c->cookies = co; } + c->numcookies++; /* one more cookie in the jar */ + return co; } @@ -584,67 +586,86 @@ void Curl_cookie_cleanup(struct CookieInfo *c) } } -#ifdef COOKIE /* experiemental functions for the upcoming cookie jar stuff */ - /* - * On my Solaris box, this command line builds this test program: + * Curl_cookie_output() * - * gcc -g -o cooktest -DCOOKIE=1 -DHAVE_CONFIG_H -I.. -I../include cookie.c strequal.o getdate.o memdebug.o mprintf.o strtok.o -lnsl -lsocket + * Writes all internally known cookies to the specified file. Specify + * "-" as file name to write to stdout. * + * The function returns non-zero on write failure. */ - -void Curl_cookie_output(struct CookieInfo *c) +int Curl_cookie_output(struct CookieInfo *c, char *dumphere) { struct Cookie *co; - struct Cookie *next; + FILE *out; + bool use_stdout=FALSE; + + if(0 == c->numcookies) + /* If there are no known cookies, we don't write or even create any + destination file */ + return 0; + + if(strequal("-", dumphere)) { + /* use stdout */ + out = stdout; + use_stdout=TRUE; + } + else { + out = fopen(dumphere, "w"); + if(!out) + return 1; /* failure */ + } + if(c) { -#if COOKIE > 1 - if(c->filename) - printf("Got these cookies from: \"%s\"\n", c->filename); -#else - puts("# Netscape HTTP Cookie File\n" - "# http://www.netscape.com/newsref/std/cookie_spec.html\n" - "# This is generated by libcurl! Do not edit.\n"); -#endif - + fputs("# Netscape HTTP Cookie File\n" + "# http://www.netscape.com/newsref/std/cookie_spec.html\n" + "# This is generated by libcurl! Edit on your own risk.\n\n", + out); co = c->cookies; while(co) { -#if COOKIE > 1 - printf("Name: %s\n", co->name?co->name:""); - printf(" Value: %s\n", co->value?co->value:""); - printf(" Domain: %s\n", co->domain?co->domain:""); - printf(" Path: %s\n", co->path?co->path:""); - printf(" Expire: %s\n", co->expirestr?co->expirestr:""); - printf(" Version: %s\n", co->version?co->version:""); - printf(" Max-Age: %s\n\n", co->maxage?co->maxage:""); -#endif - printf("%s\t" /* domain */ - "%s\t" /* field1 */ - "%s\t" /* path */ - "%s\t" /* secure */ - "%d\t" /* expires */ - "%s\t" /* name */ - "%s\n", /* value */ - co->domain, - co->field1==2?"TRUE":"FALSE", - co->path, - co->secure?"TRUE":"FALSE", - co->expires, - co->name, - co->value); + fprintf(out, + "%s\t" /* domain */ + "%s\t" /* field1 */ + "%s\t" /* path */ + "%s\t" /* secure */ + "%u\t" /* expires */ + "%s\t" /* name */ + "%s\n", /* value */ + co->domain, + co->field1==2?"TRUE":"FALSE", + co->path, + co->secure?"TRUE":"FALSE", + (unsigned int)co->expires, + co->name, + co->value); co=co->next; } } + + if(!use_stdout) + fclose(out); + + return 0; } +#ifdef CURL_COOKIE_DEBUG + +/* + * On my Solaris box, this command line builds this test program: + * + * gcc -g -o cooktest -DCURL_COOKIE_DEBUG -DHAVE_CONFIG_H -I.. -I../include cookie.c strequal.o getdate.o memdebug.o mprintf.o strtok.o -lnsl -lsocket + * + */ + int main(int argc, char **argv) { struct CookieInfo *c=NULL; if(argc>1) { c = Curl_cookie_init(argv[1], c); Curl_cookie_add(c, TRUE, "PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/ftgw; secure"); + Curl_cookie_add(c, TRUE, "foobar=yes; domain=.haxx.se; path=/looser;"); c = Curl_cookie_init(argv[1], c); Curl_cookie_output(c); diff --git a/lib/cookie.h b/lib/cookie.h index befd54cc6..34b6fd56a 100644 --- a/lib/cookie.h +++ b/lib/cookie.h @@ -57,6 +57,7 @@ struct CookieInfo { char *filename; /* file we read from/write to */ bool running; /* state info, for cookie adding information */ + long numcookies; /* number of cookies in the "jar" */ }; /* This is the maximum line length we accept for a cookie line */ @@ -72,5 +73,6 @@ struct CookieInfo *Curl_cookie_init(char *, struct CookieInfo *); struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool); void Curl_cookie_freelist(struct Cookie *); void Curl_cookie_cleanup(struct CookieInfo *); +int Curl_cookie_output(struct CookieInfo *, char *); #endif diff --git a/lib/url.c b/lib/url.c index 294a5db9b..20111d0ed 100644 --- a/lib/url.c +++ b/lib/url.c @@ -178,6 +178,10 @@ CURLcode Curl_close(struct UrlData *data) /* the URL is allocated, free it! */ free(data->url); + if(data->cookiejar) + /* we have a "destination" for all the cookies to get dumped to */ + Curl_cookie_output(data->cookies, data->cookiejar); + Curl_cookie_cleanup(data->cookies); /* free the connection cache */ @@ -488,12 +492,19 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) case CURLOPT_COOKIEFILE: /* - * Set cookie file to read and parse. + * Set cookie file to read and parse. Can be used multiple times. */ cookiefile = (char *)va_arg(param, void *); if(cookiefile) data->cookies = Curl_cookie_init(cookiefile, data->cookies); break; + + case CURLOPT_COOKIEJAR: + /* + * Set cookie file name to dump all cookies to when we're done. + */ + data->cookiejar = cookiefile = (char *)va_arg(param, void *); + break; case CURLOPT_WRITEHEADER: /* * Custom pointer to pass the header write callback function diff --git a/lib/urldata.h b/lib/urldata.h index d0e54c7ba..8f155e394 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -541,6 +541,7 @@ struct UrlData { char *cert_passwd; /* plain text certificate password */ struct CookieInfo *cookies; + char *cookiejar; /* dump all cookies to this file */ long crlf; struct curl_slist *quote; /* before the transfer */