mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
[dgi] Experimental DGI support.
Dos Gateway Interface was introduced by Arachne browser. I tested two cases: file/cdplayer.dgi |[7]$ecdplayer.exe $s application/pdf pdf>txt|$epdftotext $1 $2
This commit is contained in:
parent
24c5295a28
commit
443d42608d
@ -1,6 +1,7 @@
|
|||||||
top_builddir=../../..
|
top_builddir=../../..
|
||||||
include $(top_builddir)/Makefile.config
|
include $(top_builddir)/Makefile.config
|
||||||
|
|
||||||
|
OBJS-$(CONFIG_DGI) += dgi.o
|
||||||
OBJS-$(CONFIG_MAILCAP) += mailcap.o
|
OBJS-$(CONFIG_MAILCAP) += mailcap.o
|
||||||
OBJS-$(CONFIG_MIMETYPES) += mimetypes.o
|
OBJS-$(CONFIG_MIMETYPES) += mimetypes.o
|
||||||
|
|
||||||
|
@ -21,11 +21,15 @@
|
|||||||
/* Backends dynamic area: */
|
/* Backends dynamic area: */
|
||||||
|
|
||||||
#include "mime/backend/default.h"
|
#include "mime/backend/default.h"
|
||||||
|
#include "mime/backend/dgi.h"
|
||||||
#include "mime/backend/mailcap.h"
|
#include "mime/backend/mailcap.h"
|
||||||
#include "mime/backend/mimetypes.h"
|
#include "mime/backend/mimetypes.h"
|
||||||
|
|
||||||
static const struct mime_backend *const mime_backends[] = {
|
static const struct mime_backend *const mime_backends[] = {
|
||||||
&default_mime_backend,
|
&default_mime_backend,
|
||||||
|
#ifdef CONFIG_DGI
|
||||||
|
&dgi_mime_backend,
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_MAILCAP
|
#ifdef CONFIG_MAILCAP
|
||||||
&mailcap_mime_backend,
|
&mailcap_mime_backend,
|
||||||
#endif
|
#endif
|
||||||
|
460
src/mime/backend/dgi.c
Normal file
460
src/mime/backend/dgi.c
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "elinks.h"
|
||||||
|
|
||||||
|
#include "config/options.h"
|
||||||
|
#include "intl/libintl.h"
|
||||||
|
#include "main/module.h"
|
||||||
|
#include "mime/backend/common.h"
|
||||||
|
#include "mime/backend/dgi.h"
|
||||||
|
#include "mime/mime.h"
|
||||||
|
#include "osdep/osdep.h" /* For exe() */
|
||||||
|
#include "session/session.h"
|
||||||
|
#include "util/file.h"
|
||||||
|
#include "util/hash.h"
|
||||||
|
#include "util/lists.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
|
||||||
|
struct dgi_hash_item {
|
||||||
|
/* The entries associated with the type */
|
||||||
|
LIST_OF(struct dgi_entry) entries;
|
||||||
|
|
||||||
|
/* The content type of all @entries. Must be last! */
|
||||||
|
char type[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dgi_entry {
|
||||||
|
LIST_HEAD(struct dgi_entry);
|
||||||
|
|
||||||
|
char *type;
|
||||||
|
char *inpext;
|
||||||
|
char *outext;
|
||||||
|
|
||||||
|
/* The 'raw' unformatted (view)command from the dgi files. */
|
||||||
|
char command[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* State variables */
|
||||||
|
static struct hash *dgi_map = NULL;
|
||||||
|
|
||||||
|
enum dgi_option {
|
||||||
|
DGI_TREE,
|
||||||
|
|
||||||
|
DGI_ENABLE,
|
||||||
|
DGI_MIME_CFG,
|
||||||
|
DGI_ASK
|
||||||
|
};
|
||||||
|
|
||||||
|
static union option_info dgi_options[] = {
|
||||||
|
INIT_OPT_TREE("mime", N_("DGI"),
|
||||||
|
"dgi", OPT_ZERO,
|
||||||
|
N_("Dos gateway interface specific options.")),
|
||||||
|
|
||||||
|
INIT_OPT_BOOL("mime.dgi", N_("Enable"),
|
||||||
|
"enable", OPT_ZERO, 1,
|
||||||
|
N_("Enable DGI support.")),
|
||||||
|
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Config filename"),
|
||||||
|
"mime_cfg", OPT_ZERO, "mime.cfg",
|
||||||
|
N_("Filename and location of config file for DGI.")),
|
||||||
|
|
||||||
|
INIT_OPT_BOOL("mime.dgi", N_("Ask before opening"),
|
||||||
|
"ask", OPT_ZERO, 0,
|
||||||
|
N_("Ask before using the handlers defined by DGI.")),
|
||||||
|
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $a"),
|
||||||
|
"a", OPT_ZERO, "",
|
||||||
|
N_("Path to cache.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $b"),
|
||||||
|
"b", OPT_ZERO, "",
|
||||||
|
N_("Full name of bookmarks.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $c"),
|
||||||
|
"c", OPT_ZERO, "",
|
||||||
|
N_("Full name of cache index.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $d"),
|
||||||
|
"d", OPT_ZERO, "",
|
||||||
|
N_("Document name.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $e"),
|
||||||
|
"e", OPT_ZERO, "",
|
||||||
|
N_("Path to executable files.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $f"),
|
||||||
|
"f", OPT_ZERO, "",
|
||||||
|
N_("File browser arguments.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $g"),
|
||||||
|
"g", OPT_ZERO, "",
|
||||||
|
N_("IP address of 1st gateway.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $h"),
|
||||||
|
"h", OPT_ZERO, "",
|
||||||
|
N_("Full name of History file.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $i"),
|
||||||
|
"i", OPT_ZERO, "",
|
||||||
|
N_("Your IP address.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $j"),
|
||||||
|
"j", OPT_ZERO, "",
|
||||||
|
N_("DJPEG arguments.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $l"),
|
||||||
|
"l", OPT_ZERO, "",
|
||||||
|
N_("Last visited document.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $m"),
|
||||||
|
"m", OPT_ZERO, "",
|
||||||
|
N_("Path to mail.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $n"),
|
||||||
|
"n", OPT_ZERO, "",
|
||||||
|
N_("IP address of 1st nameserver.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $p"),
|
||||||
|
"p", OPT_ZERO, "",
|
||||||
|
N_("Host.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $q"),
|
||||||
|
"q", OPT_ZERO, "",
|
||||||
|
N_("Filename of query string (file created only "
|
||||||
|
"when using this macro).")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $r"),
|
||||||
|
"r", OPT_ZERO, "",
|
||||||
|
N_("Horizontal resolution of screen.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $s"),
|
||||||
|
"s", OPT_ZERO, "",
|
||||||
|
N_("CGI compatible query string.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $t"),
|
||||||
|
"t", OPT_ZERO, "",
|
||||||
|
N_("Path for temporary files.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $u"),
|
||||||
|
"u", OPT_ZERO, "",
|
||||||
|
N_("URL of document.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $w"),
|
||||||
|
"w", OPT_ZERO, "",
|
||||||
|
N_("Download path.")),
|
||||||
|
INIT_OPT_STRING("mime.dgi", N_("Path $x"),
|
||||||
|
"x", OPT_ZERO, "",
|
||||||
|
N_("Netmask.")),
|
||||||
|
NULL_OPTION_INFO,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define get_opt_dgi(which) dgi_options[(which)].option
|
||||||
|
#define get_dgi(which) get_opt_dgi(which).value
|
||||||
|
#define get_dgi_ask() get_dgi(DGI_ASK).number
|
||||||
|
#define get_dgi_enable() get_dgi(DGI_ENABLE).number
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
done_dgi_entry(struct dgi_entry *entry)
|
||||||
|
{
|
||||||
|
if (!entry) return;
|
||||||
|
mem_free_if(entry->type);
|
||||||
|
mem_free_if(entry->inpext);
|
||||||
|
mem_free_if(entry->outext);
|
||||||
|
mem_free(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Takes care of all initialization of dgi entries.
|
||||||
|
* Clear memory to make freeing it safer later and we get. */
|
||||||
|
static inline struct dgi_entry *
|
||||||
|
init_dgi_entry(char *type, char *inpext, char *outext, char *command)
|
||||||
|
{
|
||||||
|
struct dgi_entry *entry;
|
||||||
|
int commandlen = strlen(command);
|
||||||
|
|
||||||
|
entry = (struct dgi_entry *)mem_calloc(1, sizeof(*entry) + commandlen);
|
||||||
|
if (!entry) return NULL;
|
||||||
|
|
||||||
|
memcpy(entry->command, command, commandlen);
|
||||||
|
entry->type = stracpy(type);
|
||||||
|
|
||||||
|
if (inpext) {
|
||||||
|
entry->inpext = straconcat(".", inpext, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outext) {
|
||||||
|
entry->outext = straconcat(".", outext, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
add_dgi_entry(struct dgi_entry *entry, char *type, int typelen)
|
||||||
|
{
|
||||||
|
struct dgi_hash_item *mitem;
|
||||||
|
struct hash_item *item;
|
||||||
|
|
||||||
|
/* Time to get the entry into the dgi_map */
|
||||||
|
/* First check if the type is already checked in */
|
||||||
|
item = get_hash_item(dgi_map, type, typelen);
|
||||||
|
if (!item) {
|
||||||
|
mitem = (struct dgi_hash_item *)mem_alloc(sizeof(*mitem) + typelen);
|
||||||
|
if (!mitem) {
|
||||||
|
done_dgi_entry(entry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
safe_strncpy(mitem->type, type, typelen + 1);
|
||||||
|
|
||||||
|
init_list(mitem->entries);
|
||||||
|
|
||||||
|
item = add_hash_item(dgi_map, mitem->type, typelen, mitem);
|
||||||
|
if (!item) {
|
||||||
|
mem_free(mitem);
|
||||||
|
done_dgi_entry(entry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (item->value) {
|
||||||
|
mitem = (struct dgi_hash_item *)item->value;
|
||||||
|
} else {
|
||||||
|
done_dgi_entry(entry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_to_list_end(mitem->entries, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parses whole mime_cfg file line-by-line adding entries to the map */
|
||||||
|
static void
|
||||||
|
parse_dgi_file(char *filename)
|
||||||
|
{
|
||||||
|
FILE *file = fopen(filename, "rb");
|
||||||
|
char *line = NULL;
|
||||||
|
size_t linelen = MAX_STR_LEN;
|
||||||
|
int lineno = 1;
|
||||||
|
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
while ((line = file_read_line(line, &linelen, file, &lineno))) {
|
||||||
|
struct dgi_entry *entry;
|
||||||
|
char *linepos;
|
||||||
|
char *command;
|
||||||
|
char *basetypeend;
|
||||||
|
char *type;
|
||||||
|
char *inpext, *outext;
|
||||||
|
char *pipe, *greater, *space;
|
||||||
|
int typelen;
|
||||||
|
|
||||||
|
/* Ignore comments */
|
||||||
|
if (*line == ';' || *line == '[') continue;
|
||||||
|
|
||||||
|
linepos = line;
|
||||||
|
|
||||||
|
pipe = strchr(linepos, '|');
|
||||||
|
if (!pipe) continue;
|
||||||
|
|
||||||
|
*pipe = '\0';
|
||||||
|
command = pipe + 1;
|
||||||
|
|
||||||
|
greater = strchr(linepos, '>');
|
||||||
|
|
||||||
|
if (!greater) {
|
||||||
|
outext = NULL;
|
||||||
|
} else {
|
||||||
|
*greater = '\0';
|
||||||
|
outext = greater + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
space = strrchr(linepos, ' ');
|
||||||
|
if (!space) {
|
||||||
|
inpext = NULL;
|
||||||
|
} else {
|
||||||
|
inpext = space + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
space = strchr(linepos, ' ');
|
||||||
|
if (!space) continue;
|
||||||
|
*space = '\0';
|
||||||
|
|
||||||
|
type = linepos;
|
||||||
|
if (!*type) continue;
|
||||||
|
|
||||||
|
entry = init_dgi_entry(type, inpext, outext, command);
|
||||||
|
if (!entry) continue;
|
||||||
|
|
||||||
|
basetypeend = strchr(type, '/');
|
||||||
|
typelen = strlen(type);
|
||||||
|
|
||||||
|
if (!basetypeend) {
|
||||||
|
char implicitwild[64];
|
||||||
|
|
||||||
|
if (typelen + 3 > sizeof(implicitwild)) {
|
||||||
|
done_dgi_entry(entry);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(implicitwild, type, typelen);
|
||||||
|
implicitwild[typelen++] = '/';
|
||||||
|
implicitwild[typelen++] = '*';
|
||||||
|
implicitwild[typelen++] = '\0';
|
||||||
|
add_dgi_entry(entry, implicitwild, typelen);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_dgi_entry(entry, type, typelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
mem_free_if(line); /* Alloced by file_read_line() */
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct hash *
|
||||||
|
init_dgi_map(void)
|
||||||
|
{
|
||||||
|
dgi_map = init_hash8();
|
||||||
|
|
||||||
|
if (!dgi_map) return NULL;
|
||||||
|
|
||||||
|
parse_dgi_file(get_opt_str("mime.dgi.mime_cfg", NULL));
|
||||||
|
|
||||||
|
return dgi_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
done_dgi(struct module *module)
|
||||||
|
{
|
||||||
|
struct hash_item *item;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!dgi_map) return;
|
||||||
|
|
||||||
|
foreach_hash_item (item, *dgi_map, i) {
|
||||||
|
struct dgi_hash_item *mitem = (struct dgi_hash_item *)item->value;
|
||||||
|
|
||||||
|
if (!mitem) continue;
|
||||||
|
|
||||||
|
while (!list_empty(mitem->entries)) {
|
||||||
|
struct dgi_entry *entry = (struct dgi_entry *)mitem->entries.next;
|
||||||
|
|
||||||
|
del_from_list(entry);
|
||||||
|
done_dgi_entry(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_free(mitem);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_hash(&dgi_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
change_hook_dgi(struct session *ses, struct option *current, struct option *changed)
|
||||||
|
{
|
||||||
|
if (changed == &get_opt_dgi(DGI_MIME_CFG)
|
||||||
|
|| (changed == &get_opt_dgi(DGI_ENABLE)
|
||||||
|
&& !get_dgi_enable())) {
|
||||||
|
done_dgi(&dgi_mime_module);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_dgi(struct module *module)
|
||||||
|
{
|
||||||
|
static const struct change_hook_info mimetypes_change_hooks[] = {
|
||||||
|
{ "mime.dgi.enable", change_hook_dgi },
|
||||||
|
{ "mime.dgi.mime_cfg", change_hook_dgi },
|
||||||
|
{ NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
register_change_hooks(mimetypes_change_hooks);
|
||||||
|
|
||||||
|
if (get_cmd_opt_bool("anonymous"))
|
||||||
|
get_opt_bool("mime.dgi.enable", NULL) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns first usable dgi_entry from a list where @entry is the head.
|
||||||
|
* Use of @filename is not supported (yet). */
|
||||||
|
static struct dgi_entry *
|
||||||
|
check_entries(struct dgi_hash_item *item)
|
||||||
|
{
|
||||||
|
struct dgi_entry *entry;
|
||||||
|
|
||||||
|
foreach (entry, item->entries) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dgi_entry *
|
||||||
|
get_dgi_entry(char *type)
|
||||||
|
{
|
||||||
|
struct dgi_entry *entry;
|
||||||
|
struct hash_item *item;
|
||||||
|
|
||||||
|
item = get_hash_item(dgi_map, type, strlen(type));
|
||||||
|
|
||||||
|
/* Check list of entries */
|
||||||
|
entry = ((item && item->value) ? check_entries((struct dgi_hash_item *)item->value) : NULL);
|
||||||
|
|
||||||
|
if (!entry) {
|
||||||
|
struct dgi_entry *wildcard = NULL;
|
||||||
|
char *wildpos = strchr(type, '/');
|
||||||
|
|
||||||
|
if (wildpos) {
|
||||||
|
int wildlen = wildpos - type + 1; /* include '/' */
|
||||||
|
char *wildtype = memacpy(type, wildlen + 2);
|
||||||
|
|
||||||
|
if (!wildtype) return NULL;
|
||||||
|
|
||||||
|
wildtype[wildlen++] = '*';
|
||||||
|
wildtype[wildlen] = '\0';
|
||||||
|
|
||||||
|
item = get_hash_item(dgi_map, wildtype, wildlen);
|
||||||
|
mem_free(wildtype);
|
||||||
|
|
||||||
|
if (item && item->value)
|
||||||
|
wildcard = check_entries((struct dgi_hash_item *)item->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use @wildcard if its priority is better or @entry is NULL */
|
||||||
|
if (wildcard && (!entry))
|
||||||
|
entry = wildcard;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mime_handler *
|
||||||
|
get_mime_handler_dgi(char *type, int xwin)
|
||||||
|
{
|
||||||
|
struct dgi_entry *entry;
|
||||||
|
struct mime_handler *handler;
|
||||||
|
char *program;
|
||||||
|
|
||||||
|
if (!get_dgi_enable()
|
||||||
|
|| (!dgi_map && !init_dgi_map()))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
entry = get_dgi_entry(type);
|
||||||
|
if (!entry) return NULL;
|
||||||
|
|
||||||
|
program = stracpy(entry->command);
|
||||||
|
if (!program) return NULL;
|
||||||
|
|
||||||
|
handler = init_mime_handler(program, NULL,
|
||||||
|
dgi_mime_module.name,
|
||||||
|
get_dgi_ask(), 0);
|
||||||
|
mem_free(program);
|
||||||
|
|
||||||
|
handler->inpext = entry->inpext;
|
||||||
|
handler->outext = entry->outext;
|
||||||
|
handler->dgi = 1;
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct mime_backend dgi_mime_backend = {
|
||||||
|
/* get_content_type: */ NULL,
|
||||||
|
/* get_mime_handler: */ get_mime_handler_dgi,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Setup the exported module. */
|
||||||
|
struct module dgi_mime_module = struct_module(
|
||||||
|
/* name: */ N_("DGI mime"),
|
||||||
|
/* options: */ dgi_options,
|
||||||
|
/* hooks: */ NULL,
|
||||||
|
/* submodules: */ NULL,
|
||||||
|
/* data: */ NULL,
|
||||||
|
/* init: */ init_dgi,
|
||||||
|
/* done: */ done_dgi
|
||||||
|
);
|
21
src/mime/backend/dgi.h
Normal file
21
src/mime/backend/dgi.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef EL__MIME_BACKEND_DGI_H
|
||||||
|
#define EL__MIME_BACKEND_DGI_H
|
||||||
|
|
||||||
|
#include "main/module.h"
|
||||||
|
#include "mime/backend/common.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct mime_backend dgi_mime_backend;
|
||||||
|
extern struct module dgi_mime_module;
|
||||||
|
|
||||||
|
struct mime_handler *get_mime_handler_dgi(char *type, int xwin);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -1,3 +1,6 @@
|
|||||||
|
if conf_data.get('CONFIG_DGI')
|
||||||
|
srcs += files('dgi.c')
|
||||||
|
endif
|
||||||
if conf_data.get('CONFIG_MAILCAP')
|
if conf_data.get('CONFIG_MAILCAP')
|
||||||
srcs += files('mailcap.c')
|
srcs += files('mailcap.c')
|
||||||
endif
|
endif
|
||||||
|
@ -348,11 +348,15 @@ add_mime_filename_to_string(struct string *string, struct uri *uri)
|
|||||||
/* Backends dynamic area: */
|
/* Backends dynamic area: */
|
||||||
|
|
||||||
#include "mime/backend/default.h"
|
#include "mime/backend/default.h"
|
||||||
|
#include "mime/backend/dgi.h"
|
||||||
#include "mime/backend/mailcap.h"
|
#include "mime/backend/mailcap.h"
|
||||||
#include "mime/backend/mimetypes.h"
|
#include "mime/backend/mimetypes.h"
|
||||||
|
|
||||||
static struct module *mime_submodules[] = {
|
static struct module *mime_submodules[] = {
|
||||||
&default_mime_module,
|
&default_mime_module,
|
||||||
|
#ifdef CONFIG_DGI
|
||||||
|
&dgi_mime_module,
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_MAILCAP
|
#ifdef CONFIG_MAILCAP
|
||||||
&mailcap_mime_module,
|
&mailcap_mime_module,
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,9 +13,12 @@ struct uri;
|
|||||||
struct mime_handler {
|
struct mime_handler {
|
||||||
char *description;
|
char *description;
|
||||||
const char *backend_name;
|
const char *backend_name;
|
||||||
|
char *inpext;
|
||||||
|
char *outext;
|
||||||
unsigned int ask:1;
|
unsigned int ask:1;
|
||||||
unsigned int block:1;
|
unsigned int block:1;
|
||||||
unsigned int copiousoutput:1;
|
unsigned int copiousoutput:1;
|
||||||
|
unsigned int dgi:1;
|
||||||
char program[1]; /* XXX: Keep last! */
|
char program[1]; /* XXX: Keep last! */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "cookies/cookies.h"
|
#include "cookies/cookies.h"
|
||||||
#include "intl/libintl.h"
|
#include "intl/libintl.h"
|
||||||
#include "mime/backend/common.h"
|
#include "mime/backend/common.h"
|
||||||
|
#include "mime/backend/dgi.h"
|
||||||
#include "network/connection.h"
|
#include "network/connection.h"
|
||||||
#include "network/progress.h"
|
#include "network/progress.h"
|
||||||
#include "network/socket.h"
|
#include "network/socket.h"
|
||||||
@ -38,92 +39,12 @@
|
|||||||
#include "terminal/terminal.h"
|
#include "terminal/terminal.h"
|
||||||
#include "util/conv.h"
|
#include "util/conv.h"
|
||||||
#include "util/env.h"
|
#include "util/env.h"
|
||||||
|
#include "util/qs_parse/qs_parse.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
|
||||||
static union option_info dgi_options[] = {
|
|
||||||
INIT_OPT_TREE("protocol.file", N_("DGI"),
|
|
||||||
"dgi", OPT_ZERO,
|
|
||||||
N_("Dos gateway interface specific options.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $a"),
|
|
||||||
"a", OPT_ZERO, "",
|
|
||||||
N_("Path to cache.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $b"),
|
|
||||||
"b", OPT_ZERO, "",
|
|
||||||
N_("Full name of bookmarks.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $c"),
|
|
||||||
"c", OPT_ZERO, "",
|
|
||||||
N_("Full name of cache index.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $d"),
|
|
||||||
"d", OPT_ZERO, "",
|
|
||||||
N_("Document name.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $e"),
|
|
||||||
"e", OPT_ZERO, "",
|
|
||||||
N_("Path to executable files.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $f"),
|
|
||||||
"f", OPT_ZERO, "",
|
|
||||||
N_("File browser arguments.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $g"),
|
|
||||||
"g", OPT_ZERO, "",
|
|
||||||
N_("IP address of 1st gateway.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $h"),
|
|
||||||
"h", OPT_ZERO, "",
|
|
||||||
N_("Full name of History file.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $i"),
|
|
||||||
"i", OPT_ZERO, "",
|
|
||||||
N_("Your IP address.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $j"),
|
|
||||||
"j", OPT_ZERO, "",
|
|
||||||
N_("DJPEG arguments.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $l"),
|
|
||||||
"l", OPT_ZERO, "",
|
|
||||||
N_("Last visited document.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $m"),
|
|
||||||
"m", OPT_ZERO, "",
|
|
||||||
N_("Path to mail.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $n"),
|
|
||||||
"n", OPT_ZERO, "",
|
|
||||||
N_("IP address of 1st nameserver.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $p"),
|
|
||||||
"p", OPT_ZERO, "",
|
|
||||||
N_("Host.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $q"),
|
|
||||||
"q", OPT_ZERO, "",
|
|
||||||
N_("Filename of query string (file created only "
|
|
||||||
"when using this macro).")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $r"),
|
|
||||||
"r", OPT_ZERO, "",
|
|
||||||
N_("Horizontal resolution of screen.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $s"),
|
|
||||||
"s", OPT_ZERO, "",
|
|
||||||
N_("CGI compatible query string.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $t"),
|
|
||||||
"t", OPT_ZERO, "",
|
|
||||||
N_("Path for temporary files.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $u"),
|
|
||||||
"u", OPT_ZERO, "",
|
|
||||||
N_("URL of document.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $w"),
|
|
||||||
"w", OPT_ZERO, "",
|
|
||||||
N_("Download path.")),
|
|
||||||
INIT_OPT_STRING("protocol.file.dgi", N_("Path $x"),
|
|
||||||
"x", OPT_ZERO, "",
|
|
||||||
N_("Netmask.")),
|
|
||||||
NULL_OPTION_INFO,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dgi_entry {
|
|
||||||
const char *name;
|
|
||||||
const char *cmdline;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dgi_entry entries[] = {
|
|
||||||
{ "cdplayer.dgi", "$ecdplayer.exe $s > $2" },
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
struct module dgi_protocol_module = struct_module(
|
struct module dgi_protocol_module = struct_module(
|
||||||
/* name: */ N_("Dos Gateway Interface (DGI)"),
|
/* name: */ N_("DGI"),
|
||||||
/* options: */ dgi_options,
|
/* options: */ NULL,
|
||||||
/* hooks: */ NULL,
|
/* hooks: */ NULL,
|
||||||
/* submodules: */ NULL,
|
/* submodules: */ NULL,
|
||||||
/* data: */ NULL,
|
/* data: */ NULL,
|
||||||
@ -131,25 +52,29 @@ struct module dgi_protocol_module = struct_module(
|
|||||||
/* done: */ NULL
|
/* done: */ NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
static struct dgi_entry *
|
|
||||||
|
static struct mime_handler *
|
||||||
find_dgi(const char *name)
|
find_dgi(const char *name)
|
||||||
{
|
{
|
||||||
const char *last = strrchr(name, '/');
|
const char *last = strrchr(name, '/');
|
||||||
struct dgi_entry *entry;
|
struct mime_handler *handler;
|
||||||
|
|
||||||
if (last) {
|
if (last) {
|
||||||
name = last + 1;
|
name = last + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (entry = entries; entry; entry++) {
|
struct string dtype;
|
||||||
if (!entry->name) break;
|
|
||||||
|
|
||||||
if (!strcmp(name, entry->name)) {
|
if (!init_string(&dtype)) {
|
||||||
return entry;
|
return NULL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
add_to_string(&dtype, "file/");
|
||||||
|
add_to_string(&dtype, name);
|
||||||
|
handler = get_mime_handler_dgi(dtype.source, 0);
|
||||||
|
done_string(&dtype);
|
||||||
|
|
||||||
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -175,16 +100,17 @@ write_request_to_file(struct connection *conn, const char *filename)
|
|||||||
enum dgi_state {
|
enum dgi_state {
|
||||||
NORMAL,
|
NORMAL,
|
||||||
DOLAR,
|
DOLAR,
|
||||||
PERCENT
|
PERCENT,
|
||||||
|
LEFT_BRACKET
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prepare_command(struct dgi_entry *entry, const char *query, struct string *cmd, char **inp, char **out, char **queryfile)
|
prepare_command(struct mime_handler *handler, const char *query, struct string *cmd, char **inp, char **out, char **queryfile)
|
||||||
{
|
{
|
||||||
const char *ch;
|
const char *ch;
|
||||||
enum dgi_state state = NORMAL;
|
enum dgi_state state = NORMAL;
|
||||||
|
|
||||||
for (ch = entry->cmdline; *ch; ch++) {
|
for (ch = handler->program; *ch; ch++) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
default:
|
default:
|
||||||
@ -192,78 +118,89 @@ prepare_command(struct dgi_entry *entry, const char *query, struct string *cmd,
|
|||||||
state = DOLAR;
|
state = DOLAR;
|
||||||
} else if (*ch == '%') {
|
} else if (*ch == '%') {
|
||||||
state = PERCENT;
|
state = PERCENT;
|
||||||
|
} else if (*ch == '[') {
|
||||||
|
state = LEFT_BRACKET;
|
||||||
} else {
|
} else {
|
||||||
add_char_to_string(cmd, *ch);
|
add_char_to_string(cmd, *ch);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case LEFT_BRACKET:
|
||||||
|
switch (*ch) {
|
||||||
|
case ']':
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case DOLAR:
|
case DOLAR:
|
||||||
case PERCENT:
|
case PERCENT:
|
||||||
switch(*ch) {
|
switch (*ch) {
|
||||||
case 'a':
|
case 'a':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.a", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.a", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.b", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.b", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.c", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.c", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.d", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.d", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.e", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.e", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.f", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.f", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.g", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.g", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.h", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.h", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.i", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.i", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'j':
|
case 'j':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.j", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.j", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.l", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.l", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.m", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.m", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.n", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.n", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.p", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.p", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
*queryfile = tempname(NULL, "elinks", ".txt");
|
*queryfile = tempname(NULL, "elinks", handler->inpext);
|
||||||
if (*queryfile) {
|
if (*queryfile) {
|
||||||
add_to_string(cmd, *queryfile);
|
add_to_string(cmd, *queryfile);
|
||||||
}
|
}
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.r", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.r", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
@ -273,30 +210,30 @@ prepare_command(struct dgi_entry *entry, const char *query, struct string *cmd,
|
|||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.t", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.t", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.u", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.u", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.w", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.w", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
add_to_string(cmd, get_opt_str("protocol.file.dgi.x", NULL));
|
add_to_string(cmd, get_opt_str("mime.dgi.x", NULL));
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
*inp = tempname(NULL, "elinks", ".txt");
|
*inp = tempname(NULL, "elinks", handler->inpext);
|
||||||
if (*inp) {
|
if (*inp) {
|
||||||
add_to_string(cmd, *inp);
|
add_to_string(cmd, *inp);
|
||||||
}
|
}
|
||||||
state = NORMAL;
|
state = NORMAL;
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
*out = tempname(NULL, "elinks", ".htm");
|
*out = tempname(NULL, "elinks", handler->outext);
|
||||||
if (*out) {
|
if (*out) {
|
||||||
add_to_string(cmd, *out);
|
add_to_string(cmd, *out);
|
||||||
}
|
}
|
||||||
@ -312,11 +249,284 @@ prepare_command(struct dgi_entry *entry, const char *query, struct string *cmd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_command2(char *program, const char *filename, char *inpext, char *outext, struct string *cmd, char **inp, char **out)
|
||||||
|
{
|
||||||
|
const char *ch;
|
||||||
|
char *query = NULL;
|
||||||
|
enum dgi_state state = NORMAL;
|
||||||
|
|
||||||
|
for (ch = program; *ch; ch++) {
|
||||||
|
switch (state) {
|
||||||
|
case NORMAL:
|
||||||
|
default:
|
||||||
|
if (*ch == '$') {
|
||||||
|
state = DOLAR;
|
||||||
|
} else if (*ch == '%') {
|
||||||
|
state = PERCENT;
|
||||||
|
} else if (*ch == '[') {
|
||||||
|
state = LEFT_BRACKET;
|
||||||
|
} else {
|
||||||
|
add_char_to_string(cmd, *ch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LEFT_BRACKET:
|
||||||
|
switch (*ch) {
|
||||||
|
case ']':
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DOLAR:
|
||||||
|
case PERCENT:
|
||||||
|
switch (*ch) {
|
||||||
|
case 'a':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.a", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.b", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.c", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.d", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.e", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.f", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.g", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.h", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.i", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'j':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.j", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.l", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.m", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.n", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.p", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.r", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
if (query) {
|
||||||
|
add_to_string(cmd, query);
|
||||||
|
}
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.t", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.u", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.w", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
add_to_string(cmd, get_opt_str("mime.dgi.x", NULL));
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
if (filename) {
|
||||||
|
add_to_string(cmd, filename);
|
||||||
|
}
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
*out = tempname(NULL, "elinks", outext);
|
||||||
|
if (*out) {
|
||||||
|
add_to_string(cmd, *out);
|
||||||
|
}
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
add_char_to_string(cmd, *ch);
|
||||||
|
state = NORMAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dgi_protocol_handler(struct connection *conn)
|
||||||
|
{
|
||||||
|
#define NUMKVPAIRS 16
|
||||||
|
char *ref, *query;
|
||||||
|
struct connection_state state = connection_state(S_OK);
|
||||||
|
int check;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
char *kvpairs[NUMKVPAIRS];
|
||||||
|
char *command=NULL;
|
||||||
|
char *filename=NULL;
|
||||||
|
char *inpext=NULL;
|
||||||
|
char *outext=NULL;
|
||||||
|
char *del = NULL;
|
||||||
|
|
||||||
|
struct string command_str;
|
||||||
|
char *tempfilename = NULL;
|
||||||
|
char *outputfilename = NULL;
|
||||||
|
|
||||||
|
/* security checks */
|
||||||
|
if (!conn->referrer || conn->referrer->protocol != PROTOCOL_DGI) {
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
ref = get_uri_string(conn->referrer, URI_PATH);
|
||||||
|
if (!ref) {
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
check = strcmp(ref, "/");
|
||||||
|
mem_free(ref);
|
||||||
|
if (check) goto bad;
|
||||||
|
|
||||||
|
if (!init_string(&command_str)) {
|
||||||
|
state = connection_state(S_OUT_OF_MEM);
|
||||||
|
abort_connection(conn, state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
query = get_uri_string(conn->uri, URI_QUERY);
|
||||||
|
|
||||||
|
if (query) {
|
||||||
|
i = qs_parse(query, kvpairs, 16);
|
||||||
|
command = qs_k2v("command", kvpairs, i);
|
||||||
|
filename = qs_k2v("filename", kvpairs, i);
|
||||||
|
inpext = qs_k2v("inpext", kvpairs, i);
|
||||||
|
outext = qs_k2v("outext", kvpairs, i);
|
||||||
|
del = qs_k2v("delete", kvpairs, i);
|
||||||
|
}
|
||||||
|
prepare_command2(command, filename, inpext, outext, &command_str, &tempfilename, &outputfilename);
|
||||||
|
|
||||||
|
system(command_str.source);
|
||||||
|
done_string(&command_str);
|
||||||
|
|
||||||
|
if (del) {
|
||||||
|
unlink(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tempfilename) {
|
||||||
|
unlink(tempfilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outputfilename) {
|
||||||
|
state = connection_state(S_OK);
|
||||||
|
abort_connection(conn, state);
|
||||||
|
mem_free_if(query);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct string page;
|
||||||
|
struct string name;
|
||||||
|
|
||||||
|
if (!init_string(&name)) {
|
||||||
|
unlink(outputfilename);
|
||||||
|
mem_free_if(query);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
add_to_string(&name, outputfilename);
|
||||||
|
state = read_encoded_file(&name, &page);
|
||||||
|
unlink(outputfilename);
|
||||||
|
done_string(&name);
|
||||||
|
|
||||||
|
if (is_in_state(state, S_OK)) {
|
||||||
|
struct cache_entry *cached;
|
||||||
|
|
||||||
|
/* Try to add fragment data to the connection cache if either
|
||||||
|
* file reading or directory listing worked out ok. */
|
||||||
|
cached = conn->cached = get_cache_entry(conn->uri);
|
||||||
|
if (!conn->cached) {
|
||||||
|
state = connection_state(S_OUT_OF_MEM);
|
||||||
|
} else {
|
||||||
|
add_fragment(cached, 0, page.source, page.length);
|
||||||
|
conn->from += page.length;
|
||||||
|
|
||||||
|
if (1) {
|
||||||
|
char *head;
|
||||||
|
char *otype = NULL;
|
||||||
|
|
||||||
|
if (outext) {
|
||||||
|
otype = get_extension_content_type(outext);
|
||||||
|
}
|
||||||
|
if (!otype) {
|
||||||
|
otype = stracpy("text/html");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the system charset somehow
|
||||||
|
* changes after the directory listing
|
||||||
|
* has been generated, it should be
|
||||||
|
* parsed with the original charset. */
|
||||||
|
head = straconcat("\r\nContent-Type: ", otype, "; charset=",
|
||||||
|
get_cp_mime_name(get_cp_index("System")),
|
||||||
|
"\r\n", (char *) NULL);
|
||||||
|
|
||||||
|
mem_free_if(otype);
|
||||||
|
|
||||||
|
/* Not so gracefully handle failed memory
|
||||||
|
* allocation. */
|
||||||
|
if (!head)
|
||||||
|
state = connection_state(S_OUT_OF_MEM);
|
||||||
|
|
||||||
|
/* Setup directory listing for viewing. */
|
||||||
|
mem_free_set(&cached->head, head);
|
||||||
|
}
|
||||||
|
done_string(&page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mem_free_if(query);
|
||||||
|
abort_connection(conn, state);
|
||||||
|
return;
|
||||||
|
bad:
|
||||||
|
abort_connection(conn, connection_state(S_BAD_URL));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
execute_dgi(struct connection *conn)
|
execute_dgi(struct connection *conn)
|
||||||
{
|
{
|
||||||
char *script;
|
char *script;
|
||||||
struct dgi_entry *entry;
|
struct mime_handler *handler;
|
||||||
struct string command;
|
struct string command;
|
||||||
char *tempfilename = NULL;
|
char *tempfilename = NULL;
|
||||||
char *outputfilename = NULL;
|
char *outputfilename = NULL;
|
||||||
@ -335,8 +545,8 @@ execute_dgi(struct connection *conn)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = find_dgi(script);
|
handler = find_dgi(script);
|
||||||
if (!entry) {
|
if (!handler) {
|
||||||
mem_free(script);
|
mem_free(script);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -348,7 +558,7 @@ execute_dgi(struct connection *conn)
|
|||||||
|
|
||||||
char *query = get_uri_string(conn->uri, URI_QUERY);
|
char *query = get_uri_string(conn->uri, URI_QUERY);
|
||||||
|
|
||||||
prepare_command(entry, query, &command, &tempfilename, &outputfilename, &queryfile);
|
prepare_command(handler, query, &command, &tempfilename, &outputfilename, &queryfile);
|
||||||
|
|
||||||
mem_free_if(query);
|
mem_free_if(query);
|
||||||
|
|
||||||
@ -363,10 +573,6 @@ execute_dgi(struct connection *conn)
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "%s\n", command.source);
|
|
||||||
|
|
||||||
|
|
||||||
system(command.source);
|
system(command.source);
|
||||||
done_string(&command);
|
done_string(&command);
|
||||||
mem_free(script);
|
mem_free(script);
|
||||||
@ -381,6 +587,7 @@ execute_dgi(struct connection *conn)
|
|||||||
|
|
||||||
|
|
||||||
if (!outputfilename) {
|
if (!outputfilename) {
|
||||||
|
mem_free(handler);
|
||||||
state = connection_state(S_OK);
|
state = connection_state(S_OK);
|
||||||
abort_connection(conn, state);
|
abort_connection(conn, state);
|
||||||
return 0;
|
return 0;
|
||||||
@ -391,6 +598,7 @@ execute_dgi(struct connection *conn)
|
|||||||
|
|
||||||
if (!init_string(&name)) {
|
if (!init_string(&name)) {
|
||||||
unlink(outputfilename);
|
unlink(outputfilename);
|
||||||
|
mem_free(handler);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
add_to_string(&name, outputfilename);
|
add_to_string(&name, outputfilename);
|
||||||
@ -412,15 +620,25 @@ execute_dgi(struct connection *conn)
|
|||||||
|
|
||||||
if (1) {
|
if (1) {
|
||||||
char *head;
|
char *head;
|
||||||
|
char *otype = NULL;
|
||||||
|
|
||||||
|
if (handler->outext) {
|
||||||
|
otype = get_extension_content_type(handler->outext);
|
||||||
|
}
|
||||||
|
if (!otype) {
|
||||||
|
otype = stracpy("text/html");
|
||||||
|
}
|
||||||
|
|
||||||
/* If the system charset somehow
|
/* If the system charset somehow
|
||||||
* changes after the directory listing
|
* changes after the directory listing
|
||||||
* has been generated, it should be
|
* has been generated, it should be
|
||||||
* parsed with the original charset. */
|
* parsed with the original charset. */
|
||||||
head = straconcat("\r\nContent-Type: text/html; charset=",
|
head = straconcat("\r\nContent-Type: ", otype, "; charset=",
|
||||||
get_cp_mime_name(get_cp_index("System")),
|
get_cp_mime_name(get_cp_index("System")),
|
||||||
"\r\n", (char *) NULL);
|
"\r\n", (char *) NULL);
|
||||||
|
|
||||||
|
mem_free_if(otype);
|
||||||
|
|
||||||
/* Not so gracefully handle failed memory
|
/* Not so gracefully handle failed memory
|
||||||
* allocation. */
|
* allocation. */
|
||||||
if (!head)
|
if (!head)
|
||||||
@ -432,6 +650,7 @@ execute_dgi(struct connection *conn)
|
|||||||
done_string(&page);
|
done_string(&page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mem_free(handler);
|
||||||
abort_connection(conn, state);
|
abort_connection(conn, state);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
|
||||||
#ifndef EL__PROTOCOL_FILE_DGI_H
|
#ifndef EL__PROTOCOL_FILE_DGI_H
|
||||||
#define EL__PROTOCOL_FILE_DGI_H
|
#define EL__PROTOCOL_FILE_DGI_H
|
||||||
|
|
||||||
|
#include "main/module.h"
|
||||||
|
#include "protocol/protocol.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -10,6 +12,7 @@ struct connection;
|
|||||||
struct module;
|
struct module;
|
||||||
|
|
||||||
extern struct module dgi_protocol_module;
|
extern struct module dgi_protocol_module;
|
||||||
|
extern protocol_handler_T dgi_protocol_handler;
|
||||||
int execute_dgi(struct connection *);
|
int execute_dgi(struct connection *);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -63,6 +63,7 @@ static const struct protocol_backend protocol_backends[] = {
|
|||||||
{ "bittorrent", 0, bittorrent_protocol_handler, 0, 0, 1, 0, 1 },
|
{ "bittorrent", 0, bittorrent_protocol_handler, 0, 0, 1, 0, 1 },
|
||||||
{ "bittorrent-peer",0,bittorrent_peer_protocol_handler, 1, 1, 0, 0, 1 },
|
{ "bittorrent-peer",0,bittorrent_peer_protocol_handler, 1, 1, 0, 0, 1 },
|
||||||
{ "data", 0, data_protocol_handler, 0, 0, 1, 0, 1 },
|
{ "data", 0, data_protocol_handler, 0, 0, 1, 0, 1 },
|
||||||
|
{ "dgi", 0, dgi_protocol_handler, 0, 0, 0, 0, 0 },
|
||||||
{ "file", 0, file_protocol_handler, 1, 0, 0, 0, 0 },
|
{ "file", 0, file_protocol_handler, 1, 0, 0, 0, 0 },
|
||||||
{ "finger", 79, finger_protocol_handler, 1, 1, 0, 0, 1 },
|
{ "finger", 79, finger_protocol_handler, 1, 1, 0, 0, 1 },
|
||||||
{ "fsp", 21, fsp_protocol_handler, 1, 1, 0, 0, 1 },
|
{ "fsp", 21, fsp_protocol_handler, 1, 1, 0, 0, 1 },
|
||||||
|
@ -17,6 +17,7 @@ enum protocol {
|
|||||||
PROTOCOL_BITTORRENT,
|
PROTOCOL_BITTORRENT,
|
||||||
PROTOCOL_BITTORRENT_PEER,
|
PROTOCOL_BITTORRENT_PEER,
|
||||||
PROTOCOL_DATA,
|
PROTOCOL_DATA,
|
||||||
|
PROTOCOL_DGI,
|
||||||
PROTOCOL_FILE,
|
PROTOCOL_FILE,
|
||||||
PROTOCOL_FINGER,
|
PROTOCOL_FINGER,
|
||||||
PROTOCOL_FSP,
|
PROTOCOL_FSP,
|
||||||
|
@ -156,6 +156,8 @@ abort_download(struct file_download *file_download)
|
|||||||
if (file_download->delete_) unlink(file_download->file);
|
if (file_download->delete_) unlink(file_download->file);
|
||||||
mem_free(file_download->file);
|
mem_free(file_download->file);
|
||||||
}
|
}
|
||||||
|
mem_free_if(file_download->inpext);
|
||||||
|
mem_free_if(file_download->outext);
|
||||||
del_from_list(file_download);
|
del_from_list(file_download);
|
||||||
mem_free(file_download);
|
mem_free(file_download);
|
||||||
}
|
}
|
||||||
@ -355,7 +357,6 @@ do_follow_url_mailcap(struct session *ses, struct uri *uri)
|
|||||||
ses_goto(ses, uri, NULL, NULL, CACHE_MODE_NORMAL, TASK_FORWARD, 0);
|
ses_goto(ses, uri, NULL, NULL, CACHE_MODE_NORMAL, TASK_FORWARD, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
exec_mailcap_command(void *data)
|
exec_mailcap_command(void *data)
|
||||||
{
|
{
|
||||||
@ -406,6 +407,71 @@ exec_later(struct session *ses, char *handler, char *file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
exec_dgi_command(void *data)
|
||||||
|
{
|
||||||
|
struct exec_dgi *exec_dgi = (struct exec_dgi *)data;
|
||||||
|
|
||||||
|
if (exec_dgi) {
|
||||||
|
if (exec_dgi->command) {
|
||||||
|
struct string string;
|
||||||
|
|
||||||
|
if (init_string(&string)) {
|
||||||
|
static char dgi_dgi[] = "dgi://";
|
||||||
|
struct uri *ref = get_uri(dgi_dgi, URI_NONE);
|
||||||
|
struct uri *uri;
|
||||||
|
struct session *ses = exec_dgi->ses;
|
||||||
|
|
||||||
|
add_to_string(&string, "dgi:///dgi?command=");
|
||||||
|
add_to_string(&string, exec_dgi->command);
|
||||||
|
add_to_string(&string, "&filename=");
|
||||||
|
if (exec_dgi->file) {
|
||||||
|
add_to_string(&string, exec_dgi->file);
|
||||||
|
}
|
||||||
|
add_to_string(&string, "&inpext=");
|
||||||
|
if (exec_dgi->inpext) {
|
||||||
|
add_to_string(&string, exec_dgi->inpext);
|
||||||
|
}
|
||||||
|
add_to_string(&string, "&outext=");
|
||||||
|
if (exec_dgi->outext) {
|
||||||
|
add_to_string(&string, exec_dgi->outext);
|
||||||
|
}
|
||||||
|
if (exec_dgi->del) {
|
||||||
|
add_to_string(&string, "&delete=1");
|
||||||
|
}
|
||||||
|
uri = get_uri(string.source, URI_BASE_FRAGMENT);
|
||||||
|
done_string(&string);
|
||||||
|
set_session_referrer(ses, ref);
|
||||||
|
if (ref) done_uri(ref);
|
||||||
|
|
||||||
|
do_follow_url_mailcap(ses, uri);
|
||||||
|
if (uri) done_uri(uri);
|
||||||
|
}
|
||||||
|
mem_free(exec_dgi->command);
|
||||||
|
}
|
||||||
|
mem_free_if(exec_dgi->file);
|
||||||
|
mem_free_if(exec_dgi->inpext);
|
||||||
|
mem_free_if(exec_dgi->outext);
|
||||||
|
mem_free(exec_dgi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
exec_later_dgi(struct session *ses, char *handler, char *file, char *inpext, char *outext, int del)
|
||||||
|
{
|
||||||
|
struct exec_dgi *exec_dgi = (struct exec_dgi *)mem_calloc(1, sizeof(*exec_dgi));
|
||||||
|
|
||||||
|
if (exec_dgi) {
|
||||||
|
exec_dgi->ses = ses;
|
||||||
|
exec_dgi->command = null_or_stracpy(handler);
|
||||||
|
exec_dgi->file = null_or_stracpy(file);
|
||||||
|
exec_dgi->inpext = null_or_stracpy(inpext);
|
||||||
|
exec_dgi->outext = null_or_stracpy(outext);
|
||||||
|
exec_dgi->del = del;
|
||||||
|
register_bottom_half(exec_dgi_command, exec_dgi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
download_data_store(struct download *download, struct file_download *file_download)
|
download_data_store(struct download *download, struct file_download *file_download)
|
||||||
{
|
{
|
||||||
@ -462,6 +528,12 @@ download_data_store(struct download *download, struct file_download *file_downlo
|
|||||||
file_download->external_handler, file_download->file);
|
file_download->external_handler, file_download->file);
|
||||||
/* Temporary file is deleted by the mailcap_protocol_handler */
|
/* Temporary file is deleted by the mailcap_protocol_handler */
|
||||||
file_download->delete_ = 0;
|
file_download->delete_ = 0;
|
||||||
|
} else if (file_download->dgi) {
|
||||||
|
exec_later_dgi(file_download->ses,
|
||||||
|
file_download->external_handler, file_download->file,
|
||||||
|
file_download->inpext, file_download->outext, 1);
|
||||||
|
/* Temporary file is deleted by the dgi_protocol_handler */
|
||||||
|
file_download->delete_ = 0;
|
||||||
} else {
|
} else {
|
||||||
exec_on_terminal(term, file_download->external_handler,
|
exec_on_terminal(term, file_download->external_handler,
|
||||||
file_download->file,
|
file_download->file,
|
||||||
@ -1260,7 +1332,17 @@ continue_download_do(struct terminal *term, int fd, void *data,
|
|||||||
codw_hop->real_file = NULL;
|
codw_hop->real_file = NULL;
|
||||||
fd = -1;
|
fd = -1;
|
||||||
|
|
||||||
if (type_query->external_handler) {
|
if (type_query->dgi && type_query->external_handler) {
|
||||||
|
file_download->external_handler = type_query->external_handler;
|
||||||
|
file_download->file = codw_hop->file;
|
||||||
|
file_download->inpext = null_or_stracpy(type_query->inpext);
|
||||||
|
file_download->outext = null_or_stracpy(type_query->outext);
|
||||||
|
file_download->dgi = type_query->dgi;
|
||||||
|
file_download->delete_ = 1;
|
||||||
|
/* change owners a few lines above */
|
||||||
|
codw_hop->file = NULL;
|
||||||
|
type_query->external_handler = NULL;
|
||||||
|
} else if (type_query->external_handler) {
|
||||||
file_download->external_handler = subst_file(type_query->external_handler,
|
file_download->external_handler = subst_file(type_query->external_handler,
|
||||||
codw_hop->file,
|
codw_hop->file,
|
||||||
type_query->uri->string);
|
type_query->uri->string);
|
||||||
@ -1390,6 +1472,8 @@ done_type_query(struct type_query *type_query)
|
|||||||
|
|
||||||
object_unlock(type_query->cached);
|
object_unlock(type_query->cached);
|
||||||
done_uri(type_query->uri);
|
done_uri(type_query->uri);
|
||||||
|
mem_free_if(type_query->inpext);
|
||||||
|
mem_free_if(type_query->outext);
|
||||||
mem_free_if(type_query->external_handler);
|
mem_free_if(type_query->external_handler);
|
||||||
mem_free_if(type_query->target_frame);
|
mem_free_if(type_query->target_frame);
|
||||||
del_from_list(type_query);
|
del_from_list(type_query);
|
||||||
@ -1510,6 +1594,17 @@ tp_open(struct type_query *type_query)
|
|||||||
char *file = get_uri_string(type_query->uri, URI_PATH);
|
char *file = get_uri_string(type_query->uri, URI_PATH);
|
||||||
char *handler = NULL;
|
char *handler = NULL;
|
||||||
|
|
||||||
|
if (type_query->dgi) {
|
||||||
|
if (file) {
|
||||||
|
decode_uri(file);
|
||||||
|
}
|
||||||
|
exec_later_dgi(type_query->ses, type_query->external_handler, file,
|
||||||
|
type_query->inpext, type_query->outext, 0);
|
||||||
|
mem_free_if(file);
|
||||||
|
done_type_query(type_query);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
decode_uri(file);
|
decode_uri(file);
|
||||||
handler = subst_file(type_query->external_handler,
|
handler = subst_file(type_query->external_handler,
|
||||||
@ -1564,6 +1659,9 @@ do_type_query(struct type_query *type_query, char *ct, struct mime_handler *hand
|
|||||||
if (handler) {
|
if (handler) {
|
||||||
type_query->block = handler->block;
|
type_query->block = handler->block;
|
||||||
type_query->copiousoutput = handler->copiousoutput;
|
type_query->copiousoutput = handler->copiousoutput;
|
||||||
|
type_query->dgi = handler->dgi;
|
||||||
|
type_query->inpext = null_or_stracpy(handler->inpext);
|
||||||
|
type_query->outext = null_or_stracpy(handler->outext);
|
||||||
if (!handler->ask) {
|
if (!handler->ask) {
|
||||||
type_query->external_handler = stracpy(handler->program);
|
type_query->external_handler = stracpy(handler->program);
|
||||||
tp_open(type_query);
|
tp_open(type_query);
|
||||||
|
@ -100,6 +100,12 @@ struct type_query {
|
|||||||
* this frame. This string must be freed with mem_free(). */
|
* this frame. This string must be freed with mem_free(). */
|
||||||
char *target_frame;
|
char *target_frame;
|
||||||
|
|
||||||
|
/** input filename extension */
|
||||||
|
char *inpext;
|
||||||
|
|
||||||
|
/** output filename extension */
|
||||||
|
char *outext;
|
||||||
|
|
||||||
/** Command line for an external handler, to be run when the
|
/** Command line for an external handler, to be run when the
|
||||||
* download finishes. When ELinks displays the type query,
|
* download finishes. When ELinks displays the type query,
|
||||||
* it copies this from mime_handler.program of the default
|
* it copies this from mime_handler.program of the default
|
||||||
@ -121,6 +127,7 @@ struct type_query {
|
|||||||
* from a "file" URI that does not refer to a local CGI, then
|
* from a "file" URI that does not refer to a local CGI, then
|
||||||
* Elinks need not copy the file. */
|
* Elinks need not copy the file. */
|
||||||
unsigned int cgi:1;
|
unsigned int cgi:1;
|
||||||
|
unsigned int dgi:1;
|
||||||
|
|
||||||
/** mailcap entry with copiousoutput */
|
/** mailcap entry with copiousoutput */
|
||||||
unsigned int copiousoutput:1;
|
unsigned int copiousoutput:1;
|
||||||
@ -152,6 +159,12 @@ struct file_download {
|
|||||||
int notify;
|
int notify;
|
||||||
struct download download;
|
struct download download;
|
||||||
|
|
||||||
|
/** input filename extension */
|
||||||
|
char *inpext;
|
||||||
|
|
||||||
|
/** output filename extension */
|
||||||
|
char *outext;
|
||||||
|
|
||||||
/** Should the file be deleted when destroying the structure */
|
/** Should the file be deleted when destroying the structure */
|
||||||
unsigned int delete_:1;
|
unsigned int delete_:1;
|
||||||
|
|
||||||
@ -161,6 +174,7 @@ struct file_download {
|
|||||||
/** Whether to block the terminal when running the external handler. */
|
/** Whether to block the terminal when running the external handler. */
|
||||||
unsigned int block:1;
|
unsigned int block:1;
|
||||||
|
|
||||||
|
unsigned int dgi:1;
|
||||||
/** Mailcap entry with copiousoutput */
|
/** Mailcap entry with copiousoutput */
|
||||||
unsigned int copiousoutput:1;
|
unsigned int copiousoutput:1;
|
||||||
|
|
||||||
@ -169,6 +183,15 @@ struct file_download {
|
|||||||
struct listbox_item *box_item;
|
struct listbox_item *box_item;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct exec_dgi {
|
||||||
|
struct session *ses;
|
||||||
|
char *command;
|
||||||
|
char *file;
|
||||||
|
char *inpext;
|
||||||
|
char *outext;
|
||||||
|
unsigned int del:1;
|
||||||
|
};
|
||||||
|
|
||||||
/** Stack of all running downloads */
|
/** Stack of all running downloads */
|
||||||
extern LIST_OF(struct file_download) downloads;
|
extern LIST_OF(struct file_download) downloads;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user