Something like this has been suggested before. It has been discarded for different reasons, foremost security (don't start programs from servers that interact with untrusted clients). Of course this was when Lars Wirzenius was the code dictator, so the new leadership might have a different opinion.
Regards Joerg -----Urspr�ngliche Nachricht----- Von: Pavel Machek [mailto:[EMAIL PROTECTED] Gesendet: Freitag, 24. Oktober 2003 20:24 An: [EMAIL PROTECTED] Betreff: wapbox -- support for external filters Hi! Here's a patch to support external convertors for wapbox. With this, it is possible to call lynx -dump on text/html documents, so that they are at least somehow displayed. What do you think? Could this or something similar go into CVS? Pavel diff -ur kannel-1.3.1-ofic/debian/kannel.conf kannel-1.3.1/debian/kannel.conf --- kannel-1.3.1-ofic/debian/kannel.conf 2003-02-17 16:50:56.000000000 +0100 +++ kannel-1.3.1/debian/kannel.conf 2003-10-16 01:22:33.000000000 +0200 @@ -20,3 +20,8 @@ group = wapbox bearerbox-host = localhost log-file = "/var/log/kannel/wapbox.log" +filters-num = 1 +filter-from-0 = "text/html" +filter-to-0 = "text/vnd.wap.wml" +filter-command-0 = "/tmp/html2wml %s" + diff -ur kannel-1.3.1-ofic/gw/wap-appl.c kannel-1.3.1/gw/wap-appl.c --- kannel-1.3.1-ofic/gw/wap-appl.c 2003-02-17 16:50:56.000000000 +0100 +++ kannel-1.3.1/gw/wap-appl.c 2003-10-16 01:22:50.000000000 +0200 @@ -117,24 +117,11 @@ static void dev_null(const char *data, size_t len, void *context); -static Octstr *convert_wml_to_wmlc(struct content *content); -static Octstr *convert_wmlscript_to_wmlscriptc(struct content *content); static void wsp_http_map_url(Octstr **osp); static List *negotiate_capabilities(List *req_caps); -static struct { - char *type; - char *result_type; - Octstr *(*convert)(struct content *); -} converters[] = { - { "text/vnd.wap.wml", - "application/vnd.wap.wmlc", - convert_wml_to_wmlc }, - { "text/vnd.wap.wmlscript", - "application/vnd.wap.wmlscriptc", - convert_wmlscript_to_wmlscriptc }, -}; -#define NUM_CONVERTERS ((long)(sizeof(converters) / sizeof(converters[0]))) +struct converter converters[NUM_CONVERTERS]; +int cur_converter = 0; /* * Following functions implement indications and conformations part of Push @@ -329,26 +316,29 @@ { Octstr *new_body; int failed = 0; - int i; + int succeeded = 0; + int i = 0; - for (i = 0; i < NUM_CONVERTERS; i++) { - if (octstr_str_compare(content->type, converters[i].type) == 0) { - new_body = converters[i].convert(content); + while (i < cur_converter) { + if (octstr_compare(content->type, converters[i].type) == 0) { + new_body = converters[i].convert(content, converters[i].data); if (new_body != NULL) { octstr_destroy(content->body); content->body = new_body; octstr_destroy(content->type); - content->type = octstr_create( - converters[i].result_type); - return 1; + content->type = octstr_duplicate(converters[i].result_type); + succeeded = 1; + i = 0; + continue; } failed = 1; } + i++; } if (failed) return -1; - return 0; + return succeeded; } @@ -382,10 +372,10 @@ { int i; - for (i = 0; i < NUM_CONVERTERS; i++) { - if (http_type_accepted(headers, converters[i].result_type) - && !http_type_accepted(headers, converters[i].type)) { - http_header_add(headers, "Accept", converters[i].type); + for (i = 0; i < cur_converter; i++) { + if (http_type_accepted(headers, octstr_get_cstr(converters[i].result_type)) + && !http_type_accepted(headers, octstr_get_cstr(converters[i].type))) { + http_header_add(headers, "Accept", octstr_get_cstr(converters[i].type)); } } } @@ -857,20 +847,63 @@ } -static Octstr *convert_wml_to_wmlc(struct content *content) +Octstr *convert_external(struct content *content, Octstr *data) +{ + Octstr *res; + char namebuf[128], cmd[1024]; +#define MAXLEN 1024*1024 + char inbuf[MAXLEN]; + FILE *f; + + + strcpy(namebuf, "/tmp/kannel.tmp.XXXXXXXX"); + if (mkstemp(namebuf) == -1) + return NULL; + f = fopen(namebuf, "w"); + octstr_print(f, content->body); + fclose(f); + + sprintf(cmd, octstr_get_cstr(data), namebuf); + f = popen(cmd, "r"); + { + int len, pos = 0; + while(1) { + len = fread(inbuf + pos, 1, MAXLEN-pos-1, f); + if (len <= 0) + break; + pos += len; + } + inbuf[pos] = 0; + } + pclose(f); + + printf("Filter returned: %s\n", inbuf); + res = octstr_create(inbuf); + unlink(namebuf); + + printf("convert_external: returning\n"); + return res; +} + + +static Octstr *convert_wml_to_wmlc(struct content *content, Octstr *o) { Octstr *wmlc; int ret; + printf("convert_wml_to_wmlc\n"); + octstr_print(stdout, content->body); ret = wml_compile(content->body, content->charset, &wmlc); - if (ret == 0) + if (ret == 0) { + printf("converted okay\n"); return wmlc; + } warning(0, "WSP: WML compilation failed."); return NULL; } -static Octstr *convert_wmlscript_to_wmlscriptc(struct content *content) +static Octstr *convert_wmlscript_to_wmlscriptc(struct content *content, Octstr *o) { WsCompilerParams params; WsCompilerPtr compiler; @@ -1410,7 +1443,13 @@ wsp_session_dispatch_event(wsp_event); } - - - - +void init_converters() +{ + converters[0].type = octstr_create("text/vnd.wap.wml"); + converters[0].result_type = octstr_create("application/vnd.wap.wmlc"); + converters[0].convert = convert_wml_to_wmlc; + converters[1].type = octstr_create("text/vnd.wap.wmlscript"); + converters[1].result_type = octstr_create("application/vnd.wap.wmlscriptc"); + converters[1].convert = convert_wmlscript_to_wmlscriptc; + cur_converter = 2; +} Only in kannel-1.3.1/gw: wap-appl.c~ diff -ur kannel-1.3.1-ofic/gw/wap-appl.h kannel-1.3.1/gw/wap-appl.h --- kannel-1.3.1-ofic/gw/wap-appl.h 2003-02-17 16:50:56.000000000 +0100 +++ kannel-1.3.1/gw/wap-appl.h 2003-10-16 01:06:08.000000000 +0200 @@ -26,4 +26,20 @@ /* Free URL mapping table. */ void wsp_http_map_destroy(void); +void init_converters(void); + +struct content; +struct converter { + Octstr *type; + Octstr *result_type; + Octstr *(*convert)(struct content *, Octstr *data); + Octstr *data; +}; + +#define NUM_CONVERTERS 3 +extern struct converter converters[NUM_CONVERTERS]; +extern int cur_converter; + +Octstr *convert_external(struct content *, Octstr *); + #endif diff -ur kannel-1.3.1-ofic/gw/wap_push_ppg.c kannel-1.3.1/gw/wap_push_ppg.c --- kannel-1.3.1-ofic/gw/wap_push_ppg.c 2003-02-17 16:50:56.000000000 +0100 +++ kannel-1.3.1/gw/wap_push_ppg.c 2003-10-16 00:09:52.000000000 +0200 @@ -1843,7 +1843,7 @@ char *type; char *result_type; Octstr *(*convert) (struct content *); -} converters[] = { +} push_converters[] = { { "text/vnd.wap.wml", "application/vnd.wap.wmlc", convert_wml_to_wmlc }, @@ -1855,7 +1855,7 @@ convert_sl_to_slc} }; -#define NUM_CONVERTERS ((long) (sizeof(converters) / sizeof(converters[0]))) +#define NUM_PUSH_CONVERTERS ((long) (sizeof(push_converters) / sizeof(push_converters[0]))) static struct { char *transfer_encoding; @@ -1876,16 +1876,16 @@ long i; Octstr *new_body; - for (i = 0; i < NUM_CONVERTERS; i++) { + for (i = 0; i < NUM_PUSH_CONVERTERS; i++) { if (octstr_compare(content->type, - octstr_imm(converters[i].type)) == 0) { - new_body = converters[i].convert(content); + octstr_imm(push_converters[i].type)) == 0) { + new_body = push_converters[i].convert(content); if (new_body == NULL) return 0; octstr_destroy(content->body); content->body = new_body; octstr_destroy(content->type); - content->type = octstr_create(converters[i].result_type); + content->type = octstr_create(push_converters[i].result_type); return 1; } } diff -ur kannel-1.3.1-ofic/gw/wapbox.c kannel-1.3.1/gw/wapbox.c --- kannel-1.3.1-ofic/gw/wapbox.c 2003-02-17 16:50:56.000000000 +0100 +++ kannel-1.3.1/gw/wapbox.c 2003-10-16 00:59:32.000000000 +0200 @@ -66,7 +66,7 @@ List *http_proxy_exceptions; Octstr *http_proxy_username; Octstr *http_proxy_password; - long map_url_max; + long map_url_max, filters_num; cfg_dump(cfg); @@ -148,6 +148,40 @@ debug("wap", 0, "Could not open access-log"); } + /* configure filters */ + filters_num = -1; + cfg_get_integer(&filters_num, grp, octstr_imm("filters-num")); + + printf("%d filters\n", filters_num); + + init_converters(); + + for (i = 0; i < filters_num; i++) { + Octstr *from, *to, *command, *name; + + if (cur_converter == NUM_CONVERTERS) + panic(0, "Too many converters, increase NUM_CONVERTERS"); + + name = octstr_format("filter-from-%d", i); + if ((from = cfg_get(grp, name)) == NULL) + panic(0, "Filter with no from"); + octstr_destroy(name); + name = octstr_format("filter-to-%d", i); + if ((to = cfg_get(grp, name)) == NULL) + panic(0, "Filter with no from"); + octstr_destroy(name); + name = octstr_format("filter-command-%d", i); + if ((command = cfg_get(grp, name)) == NULL) + panic(0, "Filter with no from"); + octstr_destroy(name); + + converters[cur_converter].type = from; + converters[cur_converter].result_type = to; + converters[cur_converter].data = command; + converters[cur_converter].convert = convert_external; + cur_converter++; + } + /* configure URL mappings */ map_url_max = -1; cfg_get_integer(&map_url_max, grp, octstr_imm("map-url-max")); diff -ur kannel-1.3.1-ofic/gwlib/cfg.def kannel-1.3.1/gwlib/cfg.def --- kannel-1.3.1-ofic/gwlib/cfg.def 2003-02-17 16:50:56.000000000 +0100 +++ kannel-1.3.1/gwlib/cfg.def 2003-10-15 23:48:52.000000000 +0200 @@ -77,6 +77,16 @@ OCTSTR(syslog-level) OCTSTR(smart-errors) OCTSTR(access-log) + OCTSTR(filters-num) + OCTSTR(filter-from-0) + OCTSTR(filter-to-0) + OCTSTR(filter-command-0) + OCTSTR(filter-from-1) + OCTSTR(filter-to-1) + OCTSTR(filter-command-1) + OCTSTR(filter-from-2) + OCTSTR(filter-to-2) + OCTSTR(filter-command-2) ) -- When do you have a heart between your knees? [Johanka's followup: and *two* hearts?]
