diff --git a/curl-7.19.7-content-disposition.patch b/curl-7.19.7-content-disposition.patch new file mode 100644 index 0000000..27f1aa1 --- /dev/null +++ b/curl-7.19.7-content-disposition.patch @@ -0,0 +1,224 @@ +diff --git a/docs/curl.1 b/docs/curl.1 +index e4f5a00..7b7d549 100644 +--- a/docs/curl.1 ++++ b/docs/curl.1 +@@ -598,6 +598,9 @@ time only. + make it discard all "session cookies". This will basically have the same effect + as if a new session is started. Typical browsers always discard session + cookies when they're closed down. ++.IP "-J/--remote-header-name" ++(HTTP) This option tells the -O/--remote-name option to use the server-specified ++Content-Disposition filename instead of extracting a filename from the URL. + .IP "-k/--insecure" + (SSL) This option explicitly allows curl to perform "insecure" SSL connections + and transfers. All SSL connections are attempted to be made secure by using +diff --git a/src/main.c b/src/main.c +index dae96ee..84ed7d2 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -612,6 +612,7 @@ struct Configurable { + bool post302; + bool nokeepalive; /* for keepalive needs */ + long alivetime; ++ bool content_disposition; /* use Content-disposition filename */ + + int default_node_flags; /* default flags to seach for each 'node', which is + basically each given URL to transfer */ +@@ -817,6 +818,7 @@ static void help(void) + " --krb Enable Kerberos with specified security level (F)", + " --libcurl Dump libcurl equivalent code of this command line", + " --limit-rate Limit transfer speed to this rate", ++ " -J/--remote-header-name Use the header-provided filename (H)", + " -l/--list-only List only names of an FTP directory (F)", + " --local-port [-num] Force use of these local port numbers", + " -L/--location Follow Location: hints (H)", +@@ -1777,6 +1779,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ + {"i", "include", FALSE}, + {"I", "head", FALSE}, + {"j", "junk-session-cookies", FALSE}, ++ {"J", "remote-header-name", FALSE}, + {"k", "insecure", FALSE}, + {"K", "config", TRUE}, + {"l", "list-only", FALSE}, +@@ -2634,6 +2637,14 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ + &config->httpreq)) + return PARAM_BAD_USE; + break; ++ case 'J': /* --remote-header-name */ ++ if (config->include_headers) { ++ warnf(config, ++ "--include and --remote-header-name cannot be combined.\n"); ++ return PARAM_BAD_USE; ++ } ++ config->content_disposition = toggle; ++ break; + case 'k': /* allow insecure SSL connects */ + config->insecure_ok = toggle; + break; +@@ -3288,19 +3299,37 @@ static size_t my_fwrite(void *buffer, size_t sz, size_t nmemb, void *stream) + struct OutStruct *out=(struct OutStruct *)stream; + struct Configurable *config = out->config; + ++ /* ++ * Once that libcurl has called back my_fwrite() the returned value ++ * is checked against the amount that was intended to be written, if ++ * it does not match then it fails with CURLE_WRITE_ERROR. So at this ++ * point returning a value different from sz*nmemb indicates failure. ++ */ ++ const size_t err_rc = (sz * nmemb) ? 0 : 1; ++ + if(!out->stream) { ++ if (!out->filename) { ++ warnf(config, "Remote filename has no length!\n"); ++ return err_rc; /* Failure */ ++ } ++ ++ if (config->content_disposition) { ++ /* don't overwrite existing files */ ++ FILE* f = fopen(out->filename, "r"); ++ if (f) { ++ fclose(f); ++ warnf(config, "Refusing to overwrite %s: %s\n", out->filename, ++ strerror(EEXIST)); ++ return err_rc; /* Failure */ ++ } ++ } ++ + /* open file for writing */ + out->stream=fopen(out->filename, "wb"); + if(!out->stream) { +- warnf(config, "Failed to create the file %s\n", out->filename); +- /* +- * Once that libcurl has called back my_fwrite() the returned value +- * is checked against the amount that was intended to be written, if +- * it does not match then it fails with CURLE_WRITE_ERROR. So at this +- * point returning a value different from sz*nmemb indicates failure. +- */ +- rc = (0 == (sz * nmemb)) ? 1 : 0; +- return rc; /* failure */ ++ warnf(config, "Failed to create the file %s: %s\n", out->filename, ++ strerror(errno)); ++ return err_rc; /* failure */ + } + } + +@@ -4011,6 +4040,87 @@ static bool stdin_upload(const char *uploadfile) + return curlx_strequal(uploadfile, "-") || curlx_strequal(uploadfile, "."); + } + ++static char* ++parse_filename(char *ptr, int len) ++{ ++ char* copy; ++ char* p; ++ char* q; ++ char quote = 0; ++ ++ /* simple implementation of strndup() */ ++ copy = malloc(len+1); ++ if (!copy) ++ return NULL; ++ strncpy(copy, ptr, len); ++ copy[len] = 0; ++ ++ p = copy; ++ if (*p == '\'' || *p == '"') { ++ /* store the starting quote */ ++ quote = *p; ++ p++; ++ } ++ ++ /* if the filename contains a path, only use filename portion */ ++ q = strrchr(copy, '/'); ++ if (q) { ++ p=q+1; ++ if (!*p) { ++ free(copy); ++ return NULL; ++ } ++ } ++ ++ q = strrchr(p, quote); ++ if (q) ++ *q = 0; ++ ++ if (copy!=p) ++ memmove(copy, p, strlen(p)+1); ++ ++ return copy; ++} ++ ++static size_t ++header_callback(void *ptr, size_t size, size_t nmemb, void *stream) ++{ ++ struct OutStruct* outs = (struct OutStruct*)stream; ++ const char* str = (char*)ptr; ++ const size_t cb = size*nmemb; ++ const char* end = (char*)ptr + cb; ++ ++ if (cb > 20 && curlx_strnequal(str, "Content-disposition:", 20)) { ++ char *p = (char*)str + 20; ++ ++ /* look for the 'filename=' parameter ++ (encoded filenames (*=) are not supported) */ ++ while (1) { ++ char *filename; ++ ++ while (p < end && !isalpha(*p)) ++ p++; ++ if (p > end-9) ++ break; ++ ++ if (memcmp(p, "filename=", 9)) { ++ /* no match, find next parameter */ ++ while ((p < end) && (*p != ';')) ++ p++; ++ continue; ++ } ++ p+=9; ++ filename = parse_filename(p, cb - (p - str)); ++ if (filename) { ++ outs->filename = filename; ++ break; ++ } ++ } ++ } ++ ++ return cb; ++} ++ + static int + operate(struct Configurable *config, int argc, argv_item_t argv[]) + { +@@ -4393,7 +4503,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[]) + pc++; + outfile = *pc ? strdup(pc): NULL; + } +- if(!outfile || !*outfile) { ++ if((!outfile || !*outfile) && !config->content_disposition) { + helpf(config->errors, "Remote file name has no length!\n"); + res = CURLE_WRITE_ERROR; + free(url); +@@ -4994,6 +5104,12 @@ operate(struct Configurable *config, int argc, argv_item_t argv[]) + my_setopt(curl, CURLOPT_POSTREDIR, config->post301 | + (config->post302 ? CURL_REDIR_POST_302 : FALSE)); + ++ if ((urlnode->flags & GETOUT_USEREMOTE) ++ && config->content_disposition) { ++ my_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); ++ my_setopt(curl, CURLOPT_HEADERDATA, &outs); ++ } ++ + retry_numretries = config->req_retry; + + retrystart = cutil_tvnow(); +@@ -5005,6 +5121,9 @@ operate(struct Configurable *config, int argc, argv_item_t argv[]) + break; + } + ++ if (config->content_disposition && outs.stream && !config->mute) ++ printf("curl: Saved to filename '%s'\n", outs.filename); ++ + /* if retry-max-time is non-zero, make sure we haven't exceeded the + time */ + if(retry_numretries && diff --git a/curl-7.19.7-nss-i686.patch b/curl-7.19.7-nss-i686.patch deleted file mode 100644 index 3f6ddaf..0000000 --- a/curl-7.19.7-nss-i686.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/lib/nss.c b/lib/nss.c -index 637663e..f439735 100644 ---- a/lib/nss.c -+++ b/lib/nss.c -@@ -1047,7 +1047,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) - } - else { - char *certpath = PR_smprintf("%s%s", -- NSS_VersionCheck("3.12.0") ? "sql:" : "", -+ /*NSS_VersionCheck("3.12.0") ? "sql:" :*/ "", - certDir); - rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY); - PR_smprintf_free(certpath); diff --git a/curl.spec b/curl.spec index d4b6e8a..ca802fe 100644 --- a/curl.spec +++ b/curl.spec @@ -1,7 +1,7 @@ Summary: A utility for getting files from remote servers (FTP, HTTP, and others) Name: curl Version: 7.19.7 -Release: 10%{?dist} +Release: 11%{?dist} License: MIT Group: Applications/Internet Source: http://curl.haxx.se/download/%{name}-%{version}.tar.lzma @@ -10,7 +10,7 @@ Patch1: curl-7.19.7-nss-nonblock.patch Patch2: curl-7.19.7-ssl-retry.patch Patch3: curl-7.19.7-modelfree.patch Patch4: curl-7.19.7-nss-warning.patch -Patch5: curl-7.19.7-nss-i686.patch +Patch5: curl-7.19.7-content-disposition.patch Patch101: curl-7.15.3-multilib.patch Patch102: curl-7.16.0-privlibs.patch Patch103: curl-7.19.4-debug.patch @@ -86,9 +86,9 @@ use cURL's capabilities internally. %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 # Fedora patches -%patch5 -p1 %patch101 -p1 %patch102 -p1 %patch103 -p1 @@ -196,6 +196,10 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/aclocal/libcurl.m4 %changelog +* Fri Jan 29 2010 Kamil Dudka 7.19.7-11 +- upstream patch adding a new option -J/--remote-header-name +- dropped temporary workaround for #545779 + * Thu Jan 14 2010 Chris Weyl 7.19.7-10 - bump for libssh2 rebuild