diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index f66b93ae..480a1f9e 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -6,7 +6,7 @@ DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = ELinks -PROJECT_NUMBER = 0.13.GIT +PROJECT_NUMBER = @VERSION@ OUTPUT_DIRECTORY = api CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English diff --git a/doc/release.txt b/doc/release.txt index 8eb76f5a..f51f9b9c 100644 --- a/doc/release.txt +++ b/doc/release.txt @@ -15,6 +15,7 @@ When releasing a new version - Change VERSION in the top of configure.in to hold the new version number. - Update the manpages so the will have the new release number by first building the source, followed by making the `update-man' target in doc/. + - Update po files by running `make update-po` in po/`. - Commit these changes. - Create a signed tag having the version ("ELinks X.X.X") as the subject and using the changelog create above as the body. Use something like: diff --git a/src/mime/backend/default.c b/src/mime/backend/default.c index 3e24b137..92fd88eb 100644 --- a/src/mime/backend/default.c +++ b/src/mime/backend/default.c @@ -72,7 +72,8 @@ static struct option_info default_mime_options[] = { "program", 0, "", /* xgettext:no-c-format */ N_("External viewer for this file type. '%' in this string will be\n" - "substituted by a file name.")), + "substituted by a file name.\n" + "Do _not_ put single- or double-quotes around the % sign.")), INIT_OPT_TREE("mime", N_("File extension associations"), diff --git a/src/mime/backend/mailcap.c b/src/mime/backend/mailcap.c index 752c626c..76ea78b9 100644 --- a/src/mime/backend/mailcap.c +++ b/src/mime/backend/mailcap.c @@ -498,13 +498,24 @@ format_command(unsigned char *command, unsigned char *type, int copiousoutput) while (*command) { unsigned char *start = command; - while (*command && *command != '%' && *command != '\\') + while (*command && *command != '%' && *command != '\\' && *command != '\'') command++; if (start < command) add_bytes_to_string(&cmd, start, command - start); - if (*command == '%') { + switch (*command) { + case '\'': /* Debian's '%s' */ + command++; + if (!strncmp(command, "%s'", 3)) { + command += 3; + add_char_to_string(&cmd, '%'); + } else { + add_char_to_string(&cmd, '\''); + } + break; + + case '%': command++; if (!*command) { done_string(&cmd); @@ -522,13 +533,16 @@ format_command(unsigned char *command, unsigned char *type, int copiousoutput) add_to_string(&cmd, type); } command++; + break; - } else if (*command == '\\') { + case '\\': command++; if (*command) { add_char_to_string(&cmd, *command); command++; } + default: + break; } } #if 0 diff --git a/src/protocol/smb/smb2.c b/src/protocol/smb/smb2.c index cae5f3f4..5cd7def6 100644 --- a/src/protocol/smb/smb2.c +++ b/src/protocol/smb/smb2.c @@ -62,6 +62,8 @@ struct module smb_protocol_module = struct_module( /* done: */ NULL ); +static FILE *header_out, *data_out; + /* The child process generally does not bother to free the memory it * allocates. When the process exits, the operating system will free * the memory anyway. There is no point in changing this, because the @@ -71,8 +73,8 @@ struct module smb_protocol_module = struct_module( static void smb_error(int error) { - fprintf(stderr, "text/x-error"); - printf("%d\n", error); + fputs("text/x-error", header_out); + fprintf(data_out, "%d\n", error); exit(1); } @@ -168,7 +170,8 @@ display_entry(const struct smbc_dirent *entry, const unsigned char dircolor[]) /* unknown type */ break; } - puts(string.source); + fputs(string.source, data_out); + fputc('\n', data_out); done_string(&string); } @@ -253,10 +256,11 @@ smb_directory(int dir, struct uri *uri) smb_error(-S_OUT_OF_MEM); } - fprintf(stderr, "text/html"); - fclose(stderr); + fputs("text/html", header_out); + fclose(header_out); - puts(buf.source); + fputs(buf.source, data_out); + fputc('\n', data_out); if (get_opt_bool("document.browse.links.color_dirs", NULL)) { color_to_string(get_opt_color("document.colors.dirs", NULL), @@ -264,7 +268,7 @@ smb_directory(int dir, struct uri *uri) } sort_and_display_entries(dir, dircolor); - puts("
"); + fputs("
\n", data_out); smbc_closedir(dir); exit(0); } @@ -329,7 +333,7 @@ do_smb(struct connection *conn) const int errno_from_opendir = errno; char buf[READ_SIZE]; struct stat sb; - int r, res; + int r, res, fdout; int file = smbc_open(url, O_RDONLY, 0); if (file < 0) { @@ -349,12 +353,13 @@ do_smb(struct connection *conn) smb_error(res); } /* filesize */ - fprintf(stderr, "%" OFF_PRINT_FORMAT, + fprintf(header_out, "%" OFF_PRINT_FORMAT, (off_print_T) sb.st_size); - fclose(stderr); + fclose(header_out); + fdout = fileno(data_out); while ((r = smbc_read(file, buf, READ_SIZE)) > 0) { - if (safe_write(STDOUT_FILENO, buf, r) <= 0) + if (safe_write(fdout, buf, r) <= 0) break; } smbc_close(file); @@ -498,6 +503,24 @@ smb_got_header(struct socket *socket, struct read_buffer *rb) } } +static void +close_all_fds_but_two(int header, int data) +{ + int n; + int max = 1024; +#ifdef RLIMIT_NOFILE + struct rlimit lim; + + if (!getrlimit(RLIMIT_NOFILE, &lim)) + max = lim.rlim_max; +#endif + for (n = 3; n < max; n++) { + if (n != header && n != data) close(n); + } +} + + + void smb_protocol_handler(struct connection *conn) { @@ -532,9 +555,14 @@ smb_protocol_handler(struct connection *conn) } if (!cpid) { - dup2(smb_pipe[1], 1); dup2(open("/dev/null", O_RDONLY), 0); - dup2(header_pipe[1], 2); + close(1); + close(2); + data_out = fdopen(smb_pipe[1], "w"); + header_out = fdopen(header_pipe[1], "w"); + + if (!data_out || !header_out) exit(1); + close(smb_pipe[0]); close(header_pipe[0]); @@ -549,7 +577,8 @@ smb_protocol_handler(struct connection *conn) * before exit(), then stdio may attempt to write the * buffers to the wrong files. This might happen for * example if libsmbclient calls syslog(). */ - close_all_non_term_fd(); + + close_all_fds_but_two(smb_pipe[1], header_pipe[1]); do_smb(conn); } else { diff --git a/src/session/download.c b/src/session/download.c index 196109aa..b1e04454 100644 --- a/src/session/download.c +++ b/src/session/download.c @@ -808,7 +808,7 @@ subst_file(unsigned char *prog, unsigned char *file) cygwin_conv_to_full_win32_path(file, new_path); add_to_string(&name, new_path); #else - add_to_string(&name, file); + add_shell_quoted_to_string(&name, file, strlen(file)); #endif prog++; } @@ -1086,29 +1086,6 @@ tp_open(struct type_query *type_query) return; } - if (type_query->uri->protocol == PROTOCOL_FILE) { - unsigned char *file = get_uri_string(type_query->uri, URI_PATH); - unsigned char *handler = NULL; - - if (file) { - handler = subst_file(type_query->external_handler, file); - mem_free(file); - } - - if (handler) { - if (type_query->copiousoutput) - read_from_popen(type_query->ses, handler, NULL); - else - exec_on_terminal(type_query->ses->tab->term, - handler, "", - type_query->block ? TERM_EXEC_FG : TERM_EXEC_BG); - mem_free(handler); - } - - done_type_query(type_query); - return; - } - continue_download(type_query, ""); }