X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Furl.c;fp=src%2Furl.c;h=4a1c9f101278cadba3e08cf5d5f777e0dee6508d;hp=e44dfcd2313282426d68e5b5e8591682d7296df7;hb=67e6027ea130d06aeff365adfbc83f34d019b968;hpb=e9845d281316215eb25cd88052e2f1ec3309083c diff --git a/src/url.c b/src/url.c index e44dfcd2..4a1c9f10 100644 --- a/src/url.c +++ b/src/url.c @@ -1361,6 +1361,7 @@ UWC, C, C, C, C, C, C, C, /* NUL SOH STX ETX EOT ENQ ACK BEL */ query, normally '?'. Since Windows cannot handle '?' as part of file name, we use '@' instead there. */ #define FN_QUERY_SEP (opt.restrict_files_os != restrict_windows ? '?' : '@') +#define FN_QUERY_SEP_STR (opt.restrict_files_os != restrict_windows ? "?" : "@") /* Quote path element, characters in [b, e), as file name, and append the quoted string to DEST. Each character is quoted as per @@ -1494,22 +1495,28 @@ append_dir_structure (const struct url *u, struct growable *dest) } } -/* Return a unique file name that matches the given URL as good as +/* Return a unique file name that matches the given URL as well as possible. Does not create directories on the file system. */ char * url_file_name (const struct url *u, char *replaced_filename) { struct growable fnres; /* stands for "file name result" */ + struct growable temp_fnres; const char *u_file; - char *fname, *unique; + char *fname, *unique, *fname_len_check; const char *index_filename = "index.html"; /* The default index file is index.html */ + size_t max_length; fnres.base = NULL; fnres.size = 0; fnres.tail = 0; + temp_fnres.base = NULL; + temp_fnres.size = 0; + temp_fnres.tail = 0; + /* If an alternative index file was defined, change index_filename */ if (opt.default_page) index_filename = opt.default_page; @@ -1555,33 +1562,60 @@ url_file_name (const struct url *u, char *replaced_filename) if (!replaced_filename) { - /* Add the file name. */ - if (fnres.tail) - append_char ('/', &fnres); + /* Create the filename. */ u_file = *u->file ? u->file : index_filename; - append_uri_pathel (u_file, u_file + strlen (u_file), false, &fnres); - /* Append "?query" to the file name, even if empty */ + /* Append "?query" to the file name, even if empty, + * and create fname_len_check. */ if (u->query) - { - append_char (FN_QUERY_SEP, &fnres); - append_uri_pathel (u->query, u->query + strlen (u->query), - true, &fnres); - } + fname_len_check = concat_strings (u_file, FN_QUERY_SEP_STR, u->query, NULL); + else + fname_len_check = strdupdelim (u_file, u_file + strlen (u_file)); } else { - if (fnres.tail) - append_char ('/', &fnres); u_file = replaced_filename; - append_uri_pathel (u_file, u_file + strlen (u_file), false, &fnres); + fname_len_check = strdupdelim (u_file, u_file + strlen (u_file)); } + append_uri_pathel (fname_len_check, + fname_len_check + strlen (fname_len_check), false, &temp_fnres); + + /* Zero-terminate the temporary file name. */ + append_char ('\0', &temp_fnres); + + /* Check that the length of the file name is acceptable. */ + max_length = get_max_length (fnres.base, fnres.tail, _PC_NAME_MAX) - CHOMP_BUFFER; + if (max_length > 0 && strlen (temp_fnres.base) > max_length) + { + logprintf (LOG_NOTQUIET, "The name is too long, %lu chars total.\n", + (unsigned long) strlen (temp_fnres.base)); + logprintf (LOG_NOTQUIET, "Trying to shorten...\n"); + + /* Shorten the file name. */ + temp_fnres.base[max_length] = '\0'; + + logprintf (LOG_NOTQUIET, "New name is %s.\n", temp_fnres.base); + } + + free (fname_len_check); + + /* The filename has already been 'cleaned' by append_uri_pathel() above. So, + * just append it. */ + if (fnres.tail) + append_char ('/', &fnres); + append_string (temp_fnres.base, &fnres); + /* Zero-terminate the file name. */ append_char ('\0', &fnres); fname = fnres.base; + /* Make a final check that the path length is acceptable? */ + /* TODO: check fnres.base for path length problem */ + + free (temp_fnres.base); + /* Check the cases in which the unique extensions are not used: 1) Clobbering is turned off (-nc). 2) Retrieval with regetting.