wapbox -- support for external filters

Pavel Machek <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
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?]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.