diff options
author | Ulf Samuelsson <ulf.samuelsson@atmel.com> | 2008-03-30 20:40:53 +0000 |
---|---|---|
committer | Ulf Samuelsson <ulf.samuelsson@atmel.com> | 2008-03-30 20:40:53 +0000 |
commit | 0be9560cb5f49d332f9936f36e0b8677affb5866 (patch) | |
tree | 103b4415919fa167af76a9cac2d34921657e893a /package/webif/src/webif-page.c | |
parent | 4b45fed00627295ee88632dbf81e020ed96e5860 (diff) |
Add webif package
Diffstat (limited to 'package/webif/src/webif-page.c')
-rw-r--r-- | package/webif/src/webif-page.c | 289 |
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; +} |