1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-09-28 03:06:20 -04:00

Handle mailcap's copiousoutput without an external pager.

I tested it only on local PDFs.
I don't know if temporary files are deleted or not.
This commit is contained in:
Witold Filipczyk 2010-07-24 17:07:18 +02:00 committed by Witold Filipczyk
parent 19bf7cada2
commit 7dfb20d11f
8 changed files with 112 additions and 27 deletions

View File

@ -547,24 +547,6 @@ format_command(unsigned char *command, unsigned char *type, int copiousoutput)
break;
}
}
if (copiousoutput) {
unsigned char *pager = getenv("PAGER");
if (!pager && file_exists(DEFAULT_PAGER_PATH)) {
pager = DEFAULT_PAGER_PATH;
} else if (!pager && file_exists(DEFAULT_LESS_PATH)) {
pager = DEFAULT_LESS_PATH;
} else if (!pager && file_exists(DEFAULT_MORE_PATH)) {
pager = DEFAULT_MORE_PATH;
}
if (pager) {
add_char_to_string(&cmd, '|');
add_to_string(&cmd, pager);
}
}
return cmd.source;
}
@ -772,6 +754,7 @@ get_mime_handler_mailcap(unsigned char *type, int xwin)
get_mailcap_ask(), block);
mem_free(program);
handler->copiousoutput = entry->copiousoutput;
return handler;
}

View File

@ -11,6 +11,7 @@ struct mime_handler {
unsigned char *backend_name;
unsigned int ask:1;
unsigned int block:1;
unsigned int copiousoutput:1;
unsigned char program[1]; /* XXX: Keep last! */
};

View File

@ -3,6 +3,6 @@ include $(top_builddir)/Makefile.config
OBJS-$(CONFIG_CGI) += cgi.o
OBJS = file.o
OBJS = file.o mailcap.o
include $(top_srcdir)/Makefile.lib

View File

@ -9,6 +9,7 @@
#include "elinks.h"
#include "protocol/http/blacklist.h"
#include "protocol/protocol.h"
#include "protocol/uri.h"
#include "util/lists.h"
#include "util/memory.h"
@ -30,8 +31,10 @@ get_blacklist_entry(struct uri *uri)
{
struct blacklist_entry *entry;
assert(uri && uri->hostlen > 0);
if_assert_failed return NULL;
if (uri->protocol != PROTOCOL_MAILCAP) {
assert(uri && uri->hostlen > 0);
if_assert_failed return NULL;
}
foreach (entry, blacklist)
if (!c_strlcasecmp(entry->host, -1, uri->host, uri->hostlen))

View File

@ -32,6 +32,7 @@
#include "protocol/data.h"
#include "protocol/file/cgi.h"
#include "protocol/file/file.h"
#include "protocol/file/mailcap.h"
#include "protocol/finger/finger.h"
#include "protocol/fsp/fsp.h"
#include "protocol/ftp/ftp.h"
@ -68,6 +69,7 @@ static const struct protocol_backend protocol_backends[] = {
{ "http", 80, http_protocol_handler, 1, 1, 0, 0, 1 },
{ "https", 443, https_protocol_handler, 1, 1, 0, 1, 1 },
{ "javascript", 0, NULL, 0, 0, 1, 0, 1 },
{ "mailcap", 0, execute_mailcap, 0, 0, 1, 0, 0 },
{ "news", 0, news_protocol_handler, 0, 0, 1, 0, 1 },
{ "nntp", 119, nntp_protocol_handler, 1, 1, 0, 0, 0 },
{ "nntps", 563, nntp_protocol_handler, 1, 1, 0, 1, 0 },

View File

@ -21,6 +21,7 @@ enum protocol {
PROTOCOL_HTTP,
PROTOCOL_HTTPS,
PROTOCOL_JAVASCRIPT,
PROTOCOL_MAILCAP,
PROTOCOL_NEWS,
PROTOCOL_NNTP,
PROTOCOL_NNTPS,

View File

@ -32,6 +32,7 @@
#include "dialogs/menu.h"
#include "intl/gettext/libintl.h"
#include "main/object.h"
#include "main/select.h"
#include "mime/mime.h"
#include "network/connection.h"
#include "network/progress.h"
@ -326,6 +327,83 @@ abort_download_and_beep(struct file_download *file_download, struct terminal *te
abort_download(file_download);
}
struct exec_mailcap {
struct session *ses;
unsigned char *command;
unsigned char *file;
};
static void
do_follow_url_mailcap(struct session *ses, struct uri *uri)
{
if (!uri) {
print_error_dialog(ses, connection_state(S_BAD_URL), uri, PRI_CANCEL);
return;
}
ses->reloadlevel = CACHE_MODE_NORMAL;
if (ses->task.type == TASK_FORWARD) {
if (compare_uri(ses->loading_uri, uri, 0)) {
/* We're already loading the URL. */
return;
}
}
abort_loading(ses, 0);
ses_goto(ses, uri, NULL, NULL, CACHE_MODE_NORMAL, TASK_FORWARD, 0);
}
static void
exec_mailcap_command(void *data)
{
struct exec_mailcap *exec_mailcap = data;
if (exec_mailcap) {
if (exec_mailcap->command) {
int length = strlen(exec_mailcap->command)
+ sizeof("mailcap:");
unsigned char *buf = malloc(length);
if (buf) {
struct uri *ref = get_uri("mailcap:elmailcap", 0);
struct uri *uri;
struct session *ses = exec_mailcap->ses;
memcpy(buf, "mailcap:", 8);
memcpy(buf + 8, exec_mailcap->command, length - 9);
buf[length - 1] = '\0';
uri = get_uri(buf, 0);
mem_free(buf);
set_session_referrer(ses, ref);
if (ref) done_uri(ref);
do_follow_url_mailcap(ses, uri);
if (uri) done_uri(uri);
}
mem_free(exec_mailcap->command);
}
mem_free_if(exec_mailcap->file);
mem_free(exec_mailcap);
}
}
static void
exec_later(struct session *ses, unsigned char *handler, unsigned char *file)
{
struct exec_mailcap *exec_mailcap = calloc(1, sizeof(*exec_mailcap));
if (exec_mailcap) {
exec_mailcap->ses = ses;
exec_mailcap->command = null_or_stracpy(handler);
exec_mailcap->file = null_or_stracpy(file);
register_bottom_half(exec_mailcap_command, exec_mailcap);
}
}
static void
download_data_store(struct download *download, struct file_download *file_download)
{
@ -377,9 +455,15 @@ download_data_store(struct download *download, struct file_download *file_downlo
prealloc_truncate(file_download->handle, file_download->seek);
close(file_download->handle);
file_download->handle = -1;
exec_on_terminal(term, file_download->external_handler,
file_download->file,
file_download->block ? TERM_EXEC_FG : TERM_EXEC_BG);
if (file_download->copiousoutput) {
exec_later(file_download->ses,
file_download->external_handler, NULL);
} else {
exec_on_terminal(term, file_download->external_handler,
file_download->file,
file_download->block ? TERM_EXEC_FG :
TERM_EXEC_BG);
}
file_download->delete = 0;
abort_download_and_beep(file_download, term);
return;
@ -1157,6 +1241,7 @@ continue_download_do(struct terminal *term, int fd, void *data,
file_download->external_handler = subst_file(type_query->external_handler,
codw_hop->file);
file_download->delete = 1;
file_download->copiousoutput = type_query->copiousoutput;
mem_free(codw_hop->file);
mem_free_set(&type_query->external_handler, NULL);
}
@ -1407,9 +1492,13 @@ tp_open(struct type_query *type_query)
}
if (handler) {
exec_on_terminal(type_query->ses->tab->term,
handler, "",
type_query->block ? TERM_EXEC_FG : TERM_EXEC_BG);
if (type_query->copiousoutput) {
exec_later(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);
}
@ -1448,6 +1537,7 @@ do_type_query(struct type_query *type_query, unsigned char *ct, struct mime_hand
if (handler) {
type_query->block = handler->block;
type_query->copiousoutput = handler->copiousoutput;
if (!handler->ask) {
type_query->external_handler = stracpy(handler->program);
tp_open(type_query);

View File

@ -111,6 +111,8 @@ struct type_query {
* Elinks need not copy the file. */
unsigned int cgi:1;
/** mailcap entry with copiousoutput */
unsigned int copiousoutput:1;
/* int frame; */
};
@ -148,6 +150,9 @@ struct file_download {
/** Whether to block the terminal when running the external handler. */
unsigned int block:1;
/** Mailcap entry with copiousoutput */
unsigned int copiousoutput:1;
/** The current dialog for this download. Can be NULL. */
struct dialog_data *dlg_data;
struct listbox_item *box_item;