summaryrefslogtreecommitdiff
path: root/package/webif/src/webif-page.c
diff options
context:
space:
mode:
authorUlf Samuelsson <ulf.samuelsson@atmel.com>2008-03-30 20:40:53 +0000
committerUlf Samuelsson <ulf.samuelsson@atmel.com>2008-03-30 20:40:53 +0000
commit0be9560cb5f49d332f9936f36e0b8677affb5866 (patch)
tree103b4415919fa167af76a9cac2d34921657e893a /package/webif/src/webif-page.c
parent4b45fed00627295ee88632dbf81e020ed96e5860 (diff)
Add webif package
Diffstat (limited to 'package/webif/src/webif-page.c')
-rw-r--r--package/webif/src/webif-page.c289
1 files changed, 289 insertions, 0 deletions
diff --git a/package/webif/src/webif-page.c b/package/webif/src/webif-page.c
new file mode 100644
index 000000000..13e70937e
--- /dev/null
+++ b/package/webif/src/webif-page.c
@@ -0,0 +1,289 @@
+/*
+ * Webif page translator
+ *
+ * Copyright (C) 2005 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glob.h>
+#include <ctype.h>
+#ifdef NVRAM
+#include <bcmnvram.h>
+#endif
+
+#define HASH_MAX 100
+#define LINE_BUF 1024 /* max. buffer allocated for one line */
+#define MAX_TR 32 /* max. translations done on one line */
+#define TR_START "@TR<<"
+#define TR_END ">>"
+
+struct lstr {
+ char *name;
+ char *value;
+ struct lstr *next;
+};
+typedef struct lstr lstr;
+
+static lstr *ltable[HASH_MAX];
+static char buf[LINE_BUF], buf2[LINE_BUF];
+
+/* djb2 hash function */
+static inline unsigned long hash(char *str)
+{
+ unsigned long hash = 5381;
+ int c;
+
+ while ((c = *str++))
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+
+ return hash;
+}
+
+static inline char *translate_lookup(char *str)
+{
+ char *name, *def, *p, *res = NULL;
+ lstr *i;
+ int h;
+
+ def = name = str;
+ if (((p = strchr(str, '|')) != NULL)
+ || ((p = strchr(str, '#')) != NULL)) {
+ def = p + 1;
+ *p = 0;
+ }
+
+ h = hash(name) % HASH_MAX;
+ i = ltable[h];
+ while ((res == NULL) && (i != NULL)) {
+ if (strcmp(name, i->name) == 0)
+ res = i->value;
+ i = i->next;
+ }
+
+ if (res == NULL)
+ res = def;
+
+ return res;
+}
+
+static inline void add_line(char *name, char *value)
+{
+ int h = hash(name) % HASH_MAX;
+ lstr *s = malloc(sizeof(lstr));
+ lstr *p;
+
+ s->name = strdup(name);
+ s->value = strdup(value);
+ s->next = NULL;
+
+ if (ltable[h] == NULL)
+ ltable[h] = s;
+ else {
+ for(p = ltable[h]; p->next != NULL; p = p->next);
+ p->next = s;
+ }
+}
+
+static char *translate_line(char *line)
+{
+ static char *tok[MAX_TR * 3];
+ char *l, *p, *p2, *res;
+ int len = 0, pos = 0, i;
+
+ l = line;
+ while (l != NULL) {
+ if ((p = strstr(l, TR_START)) == NULL) {
+ len += strlen((tok[pos++] = l));
+ break;
+ }
+
+ p2 = strstr(p, TR_END);
+ if (p2 == NULL)
+ break;
+
+ *p = 0;
+ *p2 = 0;
+ len += strlen((tok[pos++] = l));
+ len += strlen((tok[pos++] = translate_lookup(p + strlen(TR_START))));
+
+ l = p2;
+ l += strlen(TR_END);
+ }
+ len++;
+
+ if (len > LINE_BUF)
+ p = malloc(len);
+ else
+ p = buf2;
+
+ p[0] = 0;
+ res = p;
+ for (i = 0; i < pos; i++) {
+ strcat(p, tok[i]);
+ p += strlen(tok[i]);
+ }
+
+ return res;
+}
+
+/* load and parse language file */
+static void load_lang(char *file)
+{
+ FILE *f;
+ char *b, *name, *value;
+
+ f = fopen(file, "r");
+ while (!feof(f) && (fgets(buf, LINE_BUF - 1, f) != NULL)) {
+ b = buf;
+ while (isspace(*b))
+ b++; /* skip leading spaces */
+ if (!*b)
+ continue;
+
+ name = b;
+ if ((b = strstr(name, "=>")) == NULL)
+ continue; /* separator not found */
+
+ value = b + 2;
+ if (!*value)
+ continue;
+
+ *b = 0;
+ for (b--; isspace(*b); b--)
+ *b = 0; /* remove trailing spaces */
+
+ while (isspace(*value))
+ value++; /* skip leading spaces */
+
+ for (b = value + strlen(value) - 1; isspace(*b); b--)
+ *b = 0; /* remove trailing spaces */
+
+ if (!*value)
+ continue;
+
+ add_line(name, value);
+ }
+}
+
+int main (int argc, char **argv)
+{
+ FILE *f;
+ int len, i, done;
+ char line[LINE_BUF], *tmp, *arg;
+ glob_t langfiles;
+ char *lang = NULL;
+ char *proc = "/usr/bin/haserl";
+
+ memset(ltable, 0, HASH_MAX * sizeof(lstr *));
+#ifdef NVRAM
+ if ((lang = nvram_get("language")) != NULL) {
+#else
+ if ((f = fopen("/etc/config/webif", "r")) != NULL) {
+ int n, i;
+
+ while (!feof(f) && (lang == NULL)) {
+ fgets(line, LINE_BUF - 1, f);
+
+ if (strncasecmp(line, "lang", 4) != 0)
+ goto nomatch;
+
+ lang = line + 4;
+ while (isspace(*lang))
+ lang++;
+
+ if (*lang != '=')
+ goto nomatch;
+
+ lang++;
+
+ while (isspace(*lang))
+ lang++;
+
+ for (i = 0; isalpha(lang[i]) && (i < 32); i++);
+ lang[i] = 0;
+ continue;
+nomatch:
+ lang = NULL;
+ }
+ fclose(f);
+#endif
+
+ sprintf(buf, "/usr/lib/webif/lang/%s/*.txt", lang);
+ i = glob(buf, GLOB_ERR | GLOB_MARK, NULL, &langfiles);
+ if (i == GLOB_NOSPACE || i == GLOB_ABORTED || i == GLOB_NOMATCH) {
+ // no language files found
+ } else {
+ for (i = 0; i < langfiles.gl_pathc; i++) {
+ load_lang(langfiles.gl_pathv[i]);
+ }
+ }
+ }
+
+ /*
+ * command line options for this parser are stored in argv[1] only.
+ * filename to be processed is in argv[2]
+ */
+ done = 0;
+ i = 1;
+ while (!done) {
+ if (argv[1] == NULL) {
+ done = 1;
+ } else if (strncmp(argv[1], "-e", 2) == 0) {
+ argv[1] = strchr(argv[1], ' ');
+ argv[1]++;
+ if (argv[1] != NULL) {
+ arg = argv[1];
+ if ((tmp = strchr(argv[1], ' ')) != NULL) {
+ *tmp = 0;
+ argv[1] = &tmp[1];
+ } else {
+ argv[1] = NULL;
+ i++;
+ }
+ system(arg);
+ }
+ } else if (strncmp(argv[1], "-p", 2) == 0) {
+ argv[1] = strchr(argv[1], ' ');
+ argv[1]++;
+ if (argv[1] != NULL) {
+ arg = argv[1];
+ if ((tmp = strchr(argv[1], ' ')) != NULL) {
+ *tmp = 0;
+ argv[1] = &tmp[1];
+ } else {
+ argv[1] = NULL;
+ i++;
+ }
+ proc = strdup(arg);
+ }
+ } else {
+ done = 1;
+ }
+ }
+
+ strcpy(buf, proc);
+ while (argv[i]) {
+ sprintf(buf + strlen(buf), " %s", argv[i++]);
+ }
+ f = popen(buf, "r");
+
+ while (!feof(f) && (fgets(buf, LINE_BUF - 1, f)) != NULL) {
+ fprintf(stdout, "%s", translate_line(buf));
+ fflush(stdout);
+ }
+
+ return 0;
+}