source: src/router/httpd/modules/base.c @ 32013

Last change on this file since 32013 was 32013, checked in by brainslayer, 2 weeks ago

fix compile bug

File size: 83.6 KB
Line 
1/*
2 * DD-WRT base.c (derived originally from broadcom.c WRT54G linksys gpl source. but honestly, there is nothing left of it)
3 *
4 * Copyright (C) 2005 - 2015 Sebastian Gottschall <sebastian.gottschall@newmedia-net.de>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * $Id:
21 */
22
23#ifdef WEBS
24#include <webs.h>
25#include <uemf.h>
26#include <ej.h>
27#else                           /* !WEBS */
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <ctype.h>
32#include <unistd.h>
33#include <limits.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <sys/socket.h>
37#include <netinet/in.h>
38#include <arpa/inet.h>
39#include <httpd.h>
40#include <errno.h>
41#endif                          /* WEBS */
42
43#include <proto/ethernet.h>
44#include <fcntl.h>
45#include <signal.h>
46#include <time.h>
47#include <sys/klog.h>
48#include <sys/wait.h>
49#include <cyutils.h>
50#include <support.h>
51#include <cy_conf.h>
52// #ifdef EZC_SUPPORT
53#include <ezc.h>
54// #endif
55#include <broadcom.h>
56#include <wlutils.h>
57#include <netdb.h>
58#include <utils.h>
59#include <dlfcn.h>
60
61int debug_value = 0;
62
63#include <fcntl.h>
64#include <signal.h>
65#include <time.h>
66#include <sys/klog.h>
67#include <sys/wait.h>
68#define sys_stats(url) eval("stats", (url))
69
70// tofu
71
72char *live_translate(const char *tran);
73#ifdef HAVE_BUFFALO
74void do_vsp_page(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query);
75#endif
76/*
77 * Deal with side effects before committing
78 */
79int sys_commit(void)
80{
81        if (nvram_matchi("dhcpnvram", 1)) {
82                killall("dnsmasq", SIGUSR2);    // update lease -- tofu
83                sleep(1);
84        }
85        // if (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto",
86        // "pptp") )
87        // nvram_set("wan_ifname", "ppp0");
88        // else
89        // nvram_set("wan_ifname", nvram_get("pppoe_ifname"));
90        return nvram_commit();
91}
92
93/*
94 * Variables are set in order (put dependent variables later). Set
95 * nullok to TRUE to ignore zero-length values of the variable itself.
96 * For more complicated validation that cannot be done in one pass or
97 * depends on additional form components or can throw an error in a
98 * unique painful way, write your own validation routine and assign it
99 * to a hidden variable (e.g. filter_ip).
100 */
101/*
102 * DD-WRT enhancement by seg This functions parses all
103 * /etc/config/xxxxx.nvramconfig files and creates the web var tab. so these
104 * vars arent defined anymore staticly
105 */
106
107#include <stdlib.h>
108#include <malloc.h>
109#include <dirent.h>
110#include <stdlib.h>
111
112static void StringStart(FILE * in)
113{
114        while (getc(in) != '"') {
115                if (feof(in))
116                        return;
117        }
118}
119
120static char *getFileString(FILE * in)
121{
122        char *buf;
123        int i, b;
124
125        buf = safe_malloc(1024);
126        StringStart(in);
127        for (i = 0; i < 1024; i++) {
128                b = getc(in);
129                if (b == EOF)
130                        return NULL;
131                if (b == '"') {
132                        buf[i] = 0;
133                        buf = realloc(buf, strlen(buf) + 1);
134                        return buf;
135                }
136                buf[i] = b;
137        }
138        return buf;
139}
140
141static void skipFileString(FILE * in)
142{
143        int i, b;
144
145        StringStart(in);
146        for (i = 0; i < 1024; i++) {
147                b = getc(in);
148                if (b == EOF)
149                        return;
150                if (b == '"') {
151                        return;
152                }
153        }
154        return;
155}
156
157static char *directories[] = {
158        "/etc/config",
159        "/jffs/etc/config",
160        "/mmc/etc/config"
161};
162
163struct SIMPLEVAL {
164        char *name;
165        char *validator;
166        int args;
167};
168
169static struct variable **variables;
170void Initnvramtab()
171{
172        struct dirent *entry;
173        DIR *directory;
174        FILE *in;
175        int varcount = 0, len, i;
176        char *tmpstr;
177        struct variable *tmp;
178        static struct SIMPLEVAL simpleval[] = {
179                {"WMEPARAM", "validate_wl_wme_params", 0},
180                {"WMETXPARAM", "validate_wl_wme_tx_params", 0},
181                {"WANIPADDR", "validate_wan_ipaddr", 0},
182                {"MERGEREMOTEIP", "validate_remote_ip", 0},
183                {"MERGEIPADDRS", "validate_merge_ipaddrs", 0},
184                {"DNS", "validate_dns", 0},
185                {"SAVEWDS", "save_wds", 0},
186                {"DHCP", "dhcp_check", 0},
187                {"STATICS", "validate_statics", 0},
188#ifdef HAVE_PORTSETUP
189                {"PORTSETUP", "validate_portsetup", 0},
190#endif
191                {"REBOOT", "validate_reboot", 0},
192                {"IPADDR", "validate_ipaddr", 0},
193                {"STATICLEASES", "validate_staticleases", 0},
194#ifdef HAVE_CHILLILOCAL
195                {"USERLIST", "validate_userlist", 0},
196#endif
197#ifdef HAVE_RADLOCAL
198                {"IRADIUSUSERLIST", "validate_iradius", 0},
199#endif
200                {"IPADDRS", "validate_ipaddrs", 0},
201                {"NETMASK", "validate_netmask", 0},
202                {"MERGENETMASK", "validate_merge_netmask", 0},
203                {"WDS", "validate_wds", 0},
204                {"STATICROUTE", "validate_static_route", 0},
205                {"MERGEMAC", "validate_merge_mac", 0},
206                {"FILTERPOLICY", "validate_filter_policy", 0},
207                {"FILTERIPGRP", "validate_filter_ip_grp", 0},
208                {"FILTERPORT", "validate_filter_port", 0},
209                {"FILTERDPORTGRP", "validate_filter_dport_grp", 0},
210                {"BLOCKEDSERVICE", "validate_blocked_service", 0},
211                {"FILTERP2P", "validate_catchall", 0},
212                {"FILTERMACGRP", "validate_filter_mac_grp", 0},
213                {"FILTERWEB", "validate_filter_web", 0},
214                {"WLHWADDRS", "validate_wl_hwaddrs", 0},
215                {"FORWARDPROTO", "validate_forward_proto", 0},
216                {"FORWARDSPEC", "validate_forward_spec", 0},
217                {"PORTTRIGGER", "validate_port_trigger", 0},
218                {"HWADDR", "validate_hwaddr", 0},
219                {"HWADDRS", "validate_hwaddrs", 0},
220                {"WLWEPKEY", "validate_wl_wep_key", 0},
221#ifdef HAVE_PPPOESERVER
222                {"CHAPTABLE", "validate_chaps", 0},
223#endif
224#ifdef HAVE_MILKFISH
225                {"MFSUBSCRIBERS", "validate_subscribers", 0},
226                {"MFALIASES", "validate_aliases", 0},
227#endif
228                {"RANGE", "validate_range", 2},
229                {"CHOICE", "validate_choice", -1},
230                {"NOACK", "validate_noack", 2},
231                {"NAME", "validate_name", 1},
232                {"PASSWORD", "validate_password", 1},
233                {"PASSWORD2", "validate_password2", 1},
234                {"LANIPADDR", "validate_lan_ipaddr", 1},
235                {"WPAPSK", "validate_wpa_psk", 1},
236                {"WLAUTH", "validate_wl_auth", 2},
237                {"WLWEP", "validate_wl_wep", -1},
238                {"DYNAMICROUTE", "validate_dynamic_route", -1},
239                {"WLGMODE", "validate_wl_gmode", -1},
240                {"WLNETMODE", "validate_wl_net_mode", -1},
241                {"AUTHMODE", "validate_auth_mode", -1},
242                {NULL, NULL},
243        };
244
245        variables = NULL;
246        char buf[1024];
247
248        // format = VARNAME VARDESC VARVALID VARVALIDARGS FLAGS FLAGS
249        // open config directory directory =
250        int idx;
251
252        for (idx = 0; idx < 3; idx++) {
253                directory = opendir(directories[idx]);
254                if (directory == NULL)
255                        continue;
256                // list all files in this directory
257                while ((entry = readdir(directory)) != NULL) {
258                        if (endswith(entry->d_name, ".nvramconfig")) {
259                                sprintf(buf, "%s/%s", directories[idx], entry->d_name);
260                                in = fopen(buf, "rb");
261                                if (in == NULL) {
262                                        return;
263                                }
264                                while (1) {
265                                        tmp = (struct variable *)
266                                            calloc(sizeof(struct variable), 1);
267                                        tmp->name = getFileString(in);
268                                        if (tmp->name == NULL)
269                                                break;
270                                        skipFileString(in);     // long string
271                                        tmpstr = getFileString(in);
272                                        tmp->argv = NULL;
273                                        if (!strcasecmp(tmpstr, "NULL")) {
274                                        }
275#ifdef HAVE_SPUTNIK_APD
276                                        if (!strcasecmp(tmpstr, "MJIDTYPE")) {
277                                                tmp->validatename = "validate_choice";
278                                                free(tmpstr);
279                                                tmpstr = getFileString(in);
280                                                len = atoi(tmpstr);
281                                                tmp->argv = (char **)
282                                                    safe_malloc(sizeof(char **)
283                                                                * (len + 1));
284                                                for (i = 0; i < len; i++) {
285                                                        tmp->argv[i] = getFileString(in);
286                                                }
287                                                tmp->argv[i] = NULL;
288                                                nvram_seti("sputnik_rereg", 1);
289                                        }
290#endif
291                                        if (tmp->validatename == NULL) {
292                                                int scount = 0;
293                                                while (simpleval[scount].name != NULL) {        //
294                                                        if (!strcasecmp(tmpstr, simpleval[scount].name)) {      //
295//                                                              fprintf(stderr,"match %s %s\n",tmpstr,tmp->name);
296                                                                tmp->validatename = simpleval[scount].validator;        //
297                                                                int arglen = 0;
298                                                                if (simpleval[scount].args == -1) {     //
299                                                                        free(tmpstr);
300                                                                        tmpstr = getFileString(in);     //
301                                                                        arglen = atoi(tmpstr);  //
302                                                                }
303                                                                if (simpleval[scount].args > 0) {       //
304                                                                        arglen = simpleval[scount].args;        //
305                                                                }
306                                                                if (arglen) {   //
307                                                                        tmp->argv = (char **)safe_malloc(sizeof(char **) * (arglen + 1));       //
308                                                                        for (i = 0; i < arglen; i++) {  //
309                                                                                tmp->argv[i] = getFileString(in);       //
310                                                                        }
311                                                                        tmp->argv[arglen] = NULL;       //
312
313                                                                }
314                                                                break;
315                                                        }
316                                                        scount++;
317                                                }
318//                                              if (simpleval[scount].name ==
319//                                                  NULL) {
320//                                                      fprintf(stderr,
321//                                                              "danger %s is missing\n",
322//                                                              tmpstr);
323//                                              }
324                                        }
325                                        free(tmpstr);
326                                        tmpstr = getFileString(in);
327                                        if (!strcasecmp(tmpstr, "TRUE")) {
328                                                tmp->nullok = TRUE;
329                                        } else {
330                                                tmp->nullok = FALSE;
331                                        }
332                                        free(tmpstr);
333                                        skipFileString(in);     // todo: remove it
334                                        // tmpstr = getFileString (in);
335                                        // tmp->ezc_flags = atoi (tmpstr);
336                                        // free (tmpstr);
337                                        variables = (struct variable **)
338                                            realloc(variables, sizeof(struct variable **) * (varcount + 2));
339                                        variables[varcount++] = tmp;
340                                        variables[varcount] = NULL;
341                                }
342                                fclose(in);
343                        }
344                }
345                closedir(directory);
346        }
347}
348
349#ifdef HAVE_MACBIND
350#include "../../../opt/mac.h"
351#endif
352// Added by Daniel(2004-07-29) for EZC
353static int variables_arraysize(void)
354{
355        int varcount = 0;
356
357        if (variables == NULL)
358                return 0;
359        while (variables[varcount] != NULL) {
360                varcount++;
361        }
362        // return ARRAYSIZE(variables);
363        return varcount;
364}
365
366static int calclength(char *webfile, char *ifname)
367{
368        int weblen = strlen(webfile);
369        int len = 0;
370        int i;
371        int iflen = strlen(ifname);
372        for (i = 0; i < weblen - 1; i++) {
373                if (webfile[i] == '%') {
374                        if (webfile[i + 1] == '%') {
375                                i += 2;
376                                len += 2;
377                                continue;
378                        }
379                        if (webfile[i + 1] == 'd') {
380                                len--;
381                        }
382                        if (webfile[i + 1] == 's') {
383                                len += iflen;
384                                len -= 2;       // substract size for %s
385                        }
386                }
387                len++;
388        }
389        return len + 1;
390}
391
392static char *readweb(char *filename)
393{
394        FILE *web = getWebsFile(filename);
395        unsigned int len = getWebsFileLen(filename);
396        char *webfile = (char *)safe_malloc(len + 1);
397        fread(webfile, len, 1, web);
398        fclose(web);
399        webfile[len] = 0;
400        return webfile;
401}
402
403static char *insert(char *ifname, char *index, char *filename)
404{
405        char *webfile = readweb(filename);
406        int weblen = strlen(webfile);
407        int i;
408        int ai = 0;
409        int length = calclength(webfile, ifname);
410        char *temp = calloc(length, 1);
411
412        for (i = 0; i < weblen; i++) {
413                if (webfile[i] == '%') {
414                        i++;
415                        switch (webfile[i]) {
416                        case '%':
417                                temp[ai++] = '%';
418                                break;
419                        case 'd':
420                                strcpy(&temp[ai], index);
421                                ai++;
422                                break;
423                        case 's':
424                                strcpy(&temp[ai], ifname);
425                                ai += strlen(ifname);
426                                break;
427                        default:
428                                temp[ai++] = webfile[i];
429                                break;
430                        }
431                } else
432                        temp[ai++] = webfile[i];
433        }
434        free(webfile);
435        return temp;
436}
437
438/* bigfile.bin download method used for benchmarking. use http://x.x.x.x/bigfile.bin?size=FILESIZE to request any filesize you want */
439static void do_bigfile(char *method, struct mime_handler *handler, char *path, webs_t stream, char *query)
440{
441        char fs[32];
442        char *temp2;
443        char *parameter = "size=";
444        memset(fs, 0, sizeof(fs));
445        int idx = indexof(path, '?');
446        if (idx > 0) {
447                temp2 = &path[idx + 1];
448                strncpy(fs, temp2, sizeof(fs));
449        } else {
450                return;
451        }
452        char *size = strstr(fs, parameter);
453        long long filesize = 0;
454        if (!size)              // if no argument parameter has been supplied, just use the following argument as numeric value
455                filesize = atoll(fs);
456        else {
457                char *s_fs = size + strlen(parameter);  //skip size=
458                idx = indexof(s_fs, '&');       // skip any following parameter
459                if (idx > 0)
460                        s_fs[idx] = 0;
461                filesize = atoll(s_fs);
462        }
463
464        if (!filesize || filesize < 0)  //if argument is not numeric or invalid, just return with no action
465                return;
466        long i;
467        char *extra;
468        if (!handler->send_headers) {
469                char *options = "Access-Control-Allow-Origin: *\r\n"    //
470                    "Access-Control-Allow-Headers: Origin,X-RequestedWith,Content-Type,Range,Authorization\r\n" //
471                    "Access-Control-Allow-Methods: GET,OPTIONS\r\nAccept-Ranges: *";    //
472
473                if (handler->extra_header)
474                        asprintf(&extra, "%s\r\n%s", options, handler->extra_header);
475                else
476                        asprintf(&extra, "%s", options);
477                if (!strncasecmp(method, "OPTIONS", 7)) {
478                        send_headers(200, "Ok", extra, handler->mime_type, 0, NULL);    // special case if call was for OPTIONS and not GET, so we return the requested header with zero body size
479                        goto ret;
480                } else {
481                        send_headers(200, "Ok", extra, handler->mime_type, filesize, "bigfile.bin");
482                }
483        }
484        // send body in 64kb chunks based on random values
485        char *test = malloc(65536);
486        srand(time(NULL));
487        for (i = 0; i < 65536; i++)
488                test[i] = rand() % 255;
489        long long i64;
490        long long sz = filesize / 65536;
491        for (i64 = 0; i64 < sz; i64++) {
492                wfwrite(test, 65536, 1, stream);
493        }
494        wfwrite(test, filesize % 65536, 1, stream);
495        free(test);
496
497      ret:;
498        free(extra);
499        return;
500
501}
502
503static void do_filtertable(char *method, struct mime_handler *handler, char *path, webs_t stream, char *query)
504{
505        char ifname[32];
506        char *temp2;
507        memset(ifname, 0, sizeof(ifname));
508        int idx = indexof(path, '-');
509        if (idx > 0) {
510                temp2 = &path[idx + 1];
511                strncpy(ifname, temp2, sizeof(ifname));
512        }
513// and now the tricky part (more dirty as dirty)
514        char *temp3 = websGetVar(stream, "ifname", NULL);
515        if (temp3) {
516                if (strlen(temp3) > 0) {
517                        strcpy(ifname, temp3);
518                }
519        }
520        idx = indexof(ifname, '.');
521        if (idx > 0)
522                ifname[idx] = 0;
523
524        if (!strlen(ifname))
525                return;
526        rep(ifname, '.', 'X');
527
528        char *temp = insert(ifname, "0", "WL_FilterTable.asp");
529        do_ej_buffer(temp, stream);
530        free(temp);
531}
532
533#ifdef HAVE_FREERADIUS
534#include <radiusdb.h>
535
536static void cert_file_out(char *method, struct mime_handler *handler, char *path, webs_t stream, char *query)
537{
538        int idx = indexof(path, '/');
539        if (idx < 0)
540                return;
541        char *temp2 = &path[idx + 1];
542        char link[128];
543        sprintf(link, "/jffs/etc/freeradius/certs/clients/%s", temp2);
544        do_file_attach(handler, link, stream, NULL, temp2);
545}
546
547static void show_certfield(webs_t wp, char *title, char *file)
548{
549        websWrite(wp, "<div class=\"setting\">\n<div class=\"label\">%s</div>\n"
550                  "<script type=\"text/javascript\">\n"
551                  "//<![CDATA[\n"
552                  "document.write(\"<input class=\\\"button\\\" type=\\\"button\\\" name=\\\"download_button\\\" "
553                  "value=\\\"\" + sbutton.download + \"\\\" onclick=\\\"window.location.href='/freeradius-certs/%s';\\\" />\");\n//]]>\n</script>\n</div>\n", title, file);
554}
555
556static void do_radiuscert(char *method, struct mime_handler *handler, char *path, webs_t stream, char *query)
557{
558        int idx = indexof(path, '-');
559        if (idx < 0)
560                return;
561        char *temp2 = &path[idx + 1];
562        char number[32];
563        webs_t wp = stream;
564        strncpy(number, temp2, sizeof(number) - 1);
565        idx = indexof(number, '.');
566        if (idx < 0)
567                return;
568        number[idx] = 0;
569        int radiusindex = atoi(number);
570
571        if (radiusindex == -1)
572                return;
573        struct radiusdb *db = loadradiusdb();
574        if (db == NULL)         // database empty
575                return;
576        if (radiusindex >= db->usercount)       // index out of bound
577        {
578                goto out;
579        }
580        if (db->users[radiusindex].usersize == 0 || db->users[radiusindex].passwordsize == 0 || strlen(db->users[radiusindex].user) == 0 || strlen(db->users[radiusindex].passwd) == 0) {
581                //define username fail
582                char *argv[] = { "freeradius.clientcert" };
583                call_ej("do_pagehead", NULL, wp, 1, argv);      // thats dirty
584                websWrite(wp, "</head>\n"
585                          "<body>\n"
586                          "<div id=\"main\">\n" "<div id=\"contentsInfo\">\n"
587                          "<h2>%s</h2>\n"
588                          "Error: please specify a value username and password\n"
589                          "<div class=\"submitFooter\">\n"
590                          "<script type=\"text/javascript\">\n"
591                          "//<![CDATA[\n" "submitFooterButton(0,0,0,0,0,1);\n" "//]]>\n" "</script>\n" "</div>\n" "</div>\n" "</div>\n" "</body>\n" "</html>\n", live_translate("freeradius.clientcert"));
592                goto out;
593        }
594        char filename[128];
595        char exec[512];
596        int generate = 0;
597        sprintf(filename, "/jffs/etc/freeradius/certs/clients/%s-cert.pem", db->users[radiusindex].user);
598        if (!f_exists(filename))
599                generate = 1;
600        sprintf(filename, "/jffs/etc/freeradius/certs/clients/%s-cert.p12", db->users[radiusindex].user);
601        if (!f_exists(filename))
602                generate = 1;
603        sprintf(filename, "/jffs/etc/freeradius/certs/clients/%s-key.pem", db->users[radiusindex].user);
604        if (!f_exists(filename))
605                generate = 1;
606        sprintf(filename, "/jffs/etc/freeradius/certs/clients/%s-req.pem", db->users[radiusindex].user);
607        if (!f_exists(filename))
608                generate = 1;
609
610        if (generate)           //do not regenerate certificates if they are already created
611        {
612
613                char expiration_days[64];
614                strcpy(expiration_days, nvram_safe_get("radius_expiration"));
615                long expiration = 0;    //never
616                if (db->users[radiusindex].expiration) {
617                        time_t tm;
618                        time(&tm);
619                        long curtime = ((tm / 60) / 60) / 24;   //in days
620                        expiration = db->users[radiusindex].expiration - curtime;
621                        sprintf(expiration_days, "%ld", expiration);
622                }
623                //erase line from database
624                FILE *fp = fopen("/jffs/etc/freeradius/certs/index.txt", "rb");
625                if (fp) {
626                        fseek(fp, 0, SEEK_END);
627                        int len = ftell(fp);
628                        rewind(fp);
629                        char *serial = safe_malloc(len + 1);
630                        char *output = safe_malloc(len + 1);
631                        fread(serial, len, 1, fp);
632                        fclose(fp);
633                        //look for existing entry
634                        char common[128];
635                        sprintf(common, "CN=%s", db->users[radiusindex].user);
636                        int i;
637                        int clen = strlen(common);
638                        int llen = len - clen;
639                        int line = -1;
640                        int oc = 0;
641                        for (i = 0; i < llen; i++) {
642                                if (serial[i] == 0xa) {
643                                        if (line == -1)
644                                                line++;
645                                        line++;
646                                }
647                                if (!strncmp(&serial[i], common, strlen(common))) {
648                                        //found line
649                                        int lines = 0;
650                                        int ic = 0;
651                                        while (1) {
652                                                if (serial[ic] == 0xa) {
653                                                        lines++;
654                                                }
655                                                if (line != lines)
656                                                        output[oc++] = serial[ic];
657                                                ic++;
658                                                if (ic == len)
659                                                        break;
660                                        }
661                                        break;
662                                }
663                        }
664                        if (oc) {
665                                fp = fopen("/jffs/etc/freeradius/certs/index.txt", "wb");
666                                if (fp) {
667                                        fwrite(output, oc, 1, fp);
668                                        fclose(fp);
669                                }
670                        }
671                        free(output);
672                        free(serial);
673                }
674                sprintf(exec,
675                        "cd /jffs/etc/freeradius/certs && ./doclientcert \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
676                        expiration_days,
677                        nvram_safe_get("radius_country"),
678                        nvram_safe_get("radius_state"),
679                        nvram_safe_get("radius_locality"),
680                        nvram_safe_get("radius_organisation"), nvram_safe_get("radius_email"), db->users[radiusindex].user, db->users[radiusindex].passwd, nvram_safe_get("radius_passphrase"));
681                system(exec);
682        }
683        char *argv[] = {
684                "freeradius.clientcert"
685        };
686        call_ej("do_pagehead", NULL, wp, 1, argv);      // thats dirty
687        websWrite(wp, "</head>\n" "<body>\n" "<div id=\"main\">\n" "<div id=\"contentsInfo\">\n" "<h2>%s</h2>\n", live_translate("freeradius.clientcert"));
688        sprintf(filename, "%s-cert.pem", db->users[radiusindex].user);
689        show_certfield(wp, "Certificate PEM", filename);
690        sprintf(filename, "%s-cert.p12", db->users[radiusindex].user);
691        show_certfield(wp, "Certificate P12 (Windows)", filename);
692        sprintf(filename, "%s-req.pem", db->users[radiusindex].user);
693        show_certfield(wp, "Certificate Request", filename);
694        sprintf(filename, "%s-key.pem", db->users[radiusindex].user);
695        show_certfield(wp, "Private Key PEM", filename);
696        websWrite(wp, "<div class=\"submitFooter\">\n"
697                  "<script type=\"text/javascript\">\n" "//<![CDATA[\n" "submitFooterButton(0,0,0,0,0,1);\n" "//]]>\n" "</script>\n" "</div>\n" "</div>\n" "</div>\n" "</body>\n" "</html>\n");
698
699        //make certificates
700      out:;
701        freeradiusdb(db);
702
703}
704
705#endif
706
707#ifdef HAVE_ATH9K
708static void do_spectral_scan(char *method, struct mime_handler *handler, char *p, webs_t stream, char *query)
709{
710#define json_cache "/tmp/spectral_scan.json"
711#define json_cache_timeout 2
712        char *ifname = nvram_safe_get("wifi_display");
713        int phy = mac80211_get_phyidx_by_vifname(ifname);
714        char *path;
715
716#ifdef HAVE_ATH10K
717        if (is_ath10k(ifname))
718                asprintf(&path, "/sys/kernel/debug/ieee80211/phy%d/ath10k", phy);
719        else
720#endif
721                asprintf(&path, "/sys/kernel/debug/ieee80211/phy%d/ath9k", phy);
722
723        sysprintf("echo %s > %s/spectral_count", nvram_default_get("spectral_count", "1"), path);
724        sysprintf("cat %s/spectral_scan0 > /dev/null", path);
725#ifdef HAVE_ATH10K
726        if (is_ath10k(ifname)) {
727                sysprintf("echo 64 > %s/spectral_bins", path);
728                sysprintf("echo manual > %s/spectral_scan_ctl", path);
729                sysprintf("echo trigger > %s/spectral_scan_ctl", path);
730        } else
731#endif
732                sysprintf("echo chanscan > %s/spectral_scan_ctl", path);
733        sysprintf("iw %s scan 2> /dev/null", ifname);
734        char *exec;
735//      sysprintf("fft_eval %s/spectral_scan0 2> /dev/null > %s", path,json_cache);
736        asprintf(&exec, "fft_eval \"%s/spectral_scan0\"", path);
737
738        FILE *fp = popen(exec, "rb");
739//      FILE *fp = fopen(json_cache, "rb");
740        free(exec);
741        if (!fp)
742                return;
743        char *buffer = malloc(65536 + 1);
744
745        int i;
746        websWrite(stream, "{ \"epoch\": %d, \"samples\":\n", time(NULL));
747        int result = 0;
748        while (!feof(fp)) {
749                result = fread(buffer, 1, 65536, fp);
750                buffer[result] = 0;
751                websWrite(stream, "%s", buffer);
752        }
753        pclose(fp);
754        sysprintf("echo disable > %s/spectral_scan_ctl", path);
755        free(buffer);
756        free(path);
757
758        websWrite(stream, "}");
759
760}
761#endif
762
763static void do_activetable(char *method, struct mime_handler *handler, char *path, webs_t stream, char *query)
764{
765        char *temp2 = NULL;
766        char ifname[32];
767        memset(ifname, 0, sizeof(ifname));
768        int idx = indexof(path, '-');
769        if (idx > 0) {
770                char *temp2 = &path[idx + 1];
771                strncpy(ifname, temp2, sizeof(ifname) - 1);
772        }
773
774        char *temp3 = websGetVar(stream, "ifname", NULL);
775        if (temp3 != NULL) {
776                if (strlen(temp3) > 0) {
777                        strcpy(ifname, temp3);
778                }
779        }
780
781        idx = indexof(ifname, '.');
782        if (idx > 0)
783                ifname[idx] = 0;
784        if (!strlen(ifname))
785                return;
786        char *temp = insert(ifname, "0", "WL_ActiveTable.asp");
787        do_ej_buffer(temp, stream);
788        free(temp);
789}
790
791static void do_wds(char *method, struct mime_handler *handler, char *path, webs_t stream, char *query)
792{
793        int idx = indexof(path, '-');
794        if (idx < 0)
795                return;
796        char *temp2 = &path[idx + 1];
797        char ifname[32];
798        strncpy(ifname, temp2, sizeof(ifname));
799        ifname[indexof(ifname, '.')] = 0;
800        char *temp = insert(ifname, "0", "Wireless_WDS.asp");
801        do_ej_buffer(temp, stream);
802        free(temp);
803}
804
805static void do_wireless_adv(char *method, struct mime_handler *handler, char *path, webs_t stream, char *query)
806{
807        int idx = indexof(path, '-');
808        if (idx < 0)
809                return;
810        char *temp2 = &path[idx + 1];
811        char ifname[32];
812
813        strncpy(ifname, temp2, sizeof(ifname));
814
815        idx = indexof(ifname, '.');
816        if (idx < 0)
817                return;
818        ifname[idx] = 0;
819        char index[2];
820        int strl = strlen(ifname);
821        if (strl > 0)
822                substring(strl - 1, strl, ifname, index);
823        else
824                return;
825        char *temp = insert(ifname, index, "Wireless_Advanced.asp");
826        do_ej_buffer(temp, stream);
827        free(temp);
828}
829
830void validate_cgi(webs_t wp)
831{
832        char *value;
833        int i;
834
835#ifdef HAVE_MACBIND
836        if (!nvram_match("et0macaddr", MACBRAND))
837                return;
838#endif
839        int alen = variables_arraysize();
840        void *handle = NULL;
841
842        for (i = 0; i < alen; i++) {
843                if (variables[i] == NULL)
844                        return;
845                value = websGetVar(wp, variables[i]->name, NULL);
846                if (!value)
847                        continue;
848#ifdef HAVE_IAS
849                if (!strcmp("http_username", variables[i]->name) && strcmp(value, "d6nw5v1x2pc7st9m")) {
850                        nvram_set("http_userpln", value);
851                } else if (!strcmp("http_passwd", variables[i]->name) && strcmp(value, "d6nw5v1x2pc7st9m")) {
852                        nvram_set("http_pwdpln", value);
853                }
854#endif
855                if ((!*value && variables[i]->nullok)
856                    || (!variables[i]->validate2name && !variables[i]->validatename))
857                        nvram_set(variables[i]->name, value);
858                else {
859                        if (variables[i]->validatename) {
860                                cprintf("call validator_nofree %s\n", variables[i]->validatename);
861                                handle = start_validator_nofree(variables[i]->validatename, handle, wp, value, variables[i]);
862                        } else if (variables[i]->validate2name) {
863                                cprintf("call gozila %s\n", variables[i]->validate2name);
864                                start_gozila(variables[i]->validate2name, wp);
865                                // fprintf(stderr,"validating %s =
866                                // %s\n",variables[i]->name,value);
867                                // variables[i]->validate (wp, value, variables[i]);
868                        } else {
869                                // variables[i]->validate2 (wp);
870                        }
871                }
872
873        }
874        cprintf("close handle\n");
875        if (handle)
876                dlclose(handle);
877        cprintf("all vars validated\n");
878}
879
880enum {
881        NOTHING,
882        REBOOT,
883        RESTART,
884        SERVICE_RESTART,
885        SYS_RESTART,
886        REFRESH,
887};
888static struct gozila_action gozila_actions[] = {
889        /*
890         * SETUP
891         */
892        {"index", "wan_proto", "", 1, REFRESH, "wan_proto"},
893        {"index", "dhcpfwd", "", 1, REFRESH, "dhcpfwd"},
894#ifdef HAVE_IAS
895        {"index", "admin_card", "", 1, RESTART, "ias_save_admincard"},
896#endif
897        // {"index", "clone_mac", "", 1, REFRESH, clone_mac}, //OBSOLETE
898#ifdef HAVE_CCONTROL
899        {"ccontrol", "execute", "", 1, REFRESH, "execute"},
900#endif
901        {"WanMAC", "clone_mac", "", 1, REFRESH, "clone_mac"},   // for cisco
902        // style
903        {"DHCPTable", "delete", "", 2, REFRESH, "delete_leases"},
904#ifdef HAVE_PPTPD
905        {"DHCPTable", "deletepptp", "", 2, REFRESH, "delete_pptp"},
906#endif
907        {"Info", "refresh", "", 0, REFRESH, "save_wifi"},
908        {"Status_Wireless", "refresh", "", 0, REFRESH, "save_wifi"},
909        // {"Status", "release", "dhcp_release", 0, SYS_RESTART, "dhcp_release"},
910        // {"Status", "renew", "", 3, REFRESH, "dhcp_renew"},
911        // {"Status", "Connect", "start_pppoe", 1, RESTART, NULL},
912        {"Status_Internet", "release", "dhcp_release", 0, SERVICE_RESTART, "dhcp_release"},     // for
913        {"Status_Internet", "renew", "", 3, REFRESH, "dhcp_renew"},     // for cisco
914        {"Status_Internet", "Disconnect", "stop_pppoe", 2, SERVICE_RESTART, "stop_ppp"},        // for
915#ifdef HAVE_3G
916        {"Status_Internet", "Connect_3g", "start_3g", 1, RESTART, NULL},        // for
917        {"Status_Internet", "Disconnect_3g", "stop_3g", 2, SERVICE_RESTART, "stop_ppp"},        // for
918#endif
919#ifdef HAVE_PPPOATM
920        {"Status_Internet", "Connect_pppoa", "start_pppoa", 1, RESTART, NULL},  // for
921        {"Status_Internet", "Disconnect_pppoa", "stop_pppoa", 2, SERVICE_RESTART, "stop_ppp"},  // for
922#endif
923        {"Status_Internet", "Connect_pppoe", "start_pppoe", 1, RESTART, NULL},  // for
924        {"Status_Internet", "Disconnect_pppoe", "stop_pppoe", 2, SERVICE_RESTART, "stop_ppp"},  // for
925
926        {"Status_Internet", "Connect_pptp", "start_pptp", 1, RESTART, NULL},    // for
927        {"Status_Internet", "Disconnect_pptp", "stop_pptp", 2, SERVICE_RESTART, "stop_ppp"},    // for
928        {"Status_Internet", "Connect_l2tp", "start_l2tp", 1, RESTART, NULL},    // for
929        {"Status_Internet", "Disconnect_l2tp", "stop_l2tp", 2, SERVICE_RESTART, "stop_ppp"},    // for
930        // cisco
931        // style{
932        // "Status_Router",
933        // "Connect_heartbeat",
934        // "start_heartbeat",
935        // 1,
936        // RESTART,
937        // NULL},
938        // //
939        // for
940        // cisco
941        // style
942        {"Status_Internet", "Disconnect_heartbeat", "stop_heartbeat", 2, SERVICE_RESTART, "stop_ppp"},  // for
943        // cisco
944        // style
945        {"Status_Internet", "delete_ttraffdata", "", 0, REFRESH,
946         "ttraff_erase"},
947        {"Filters", "save", "filters", 1, REFRESH, "save_policy"},
948        {"Filters", "delete", "filters", 1, REFRESH, "single_delete_policy"},
949        {"FilterSummary", "delete", "filters", 1, REFRESH,
950         "summary_delete_policy"},
951        {"Routing", "del", "static_route_del", 1, REFRESH,
952         "delete_static_route"},
953        {"RouteStatic", "del", "static_route_del", 1, REFRESH,
954         "delete_static_route"},
955        {"WL_WPATable", "wep_key_generate", "", 1, REFRESH, "generate_wep_key"},
956        {"WL_WPATable", "security", "", 1, REFRESH, "set_security"},
957        {"WL_WPATable", "save", "wireless_2", 1, REFRESH, "security_save"},
958        {"WL_WPATable", "keysize", "wireless_2", 1, REFRESH, "security_save"},
959        {"WL_ActiveTable", "add_mac", "", 1, REFRESH, "add_active_mac"},
960        {"WL_ActiveTable-wl0", "add_mac", "", 1, REFRESH, "add_active_mac"},
961        {"WL_ActiveTable-wl1", "add_mac", "", 1, REFRESH, "add_active_mac"},
962        {"WL_ActiveTable-wl2", "add_mac", "", 1, REFRESH, "add_active_mac"},
963        /*
964         * Siafu addition
965         */
966        {"Ping", "wol", "", 1, REFRESH, "ping_wol"},
967        /*
968         * Sveasoft addition
969         */
970        // {"Wireless_WDS", "save", "", 0, REFRESH, save_wds},
971#ifndef HAVE_MADWIFI
972        {"Wireless_WDS-wl0", "save", "wireless_2", 0, REFRESH, "save_wds"},
973        {"Wireless_WDS-wl1", "save", "wireless_2", 0, REFRESH, "save_wds"},
974        {"Wireless_WDS-wl2", "save", "wireless_2", 0, REFRESH, "save_wds"},
975        {"Wireless_Advanced-wl0", "save", "wireless_2", 0, REFRESH,
976         "save_wireless_advanced"},
977        {"Wireless_Advanced-wl1", "save", "wireless_2", 0, REFRESH,
978         "save_wireless_advanced"},
979        {"Wireless_Advanced-wl2", "save", "wireless_2", 0, REFRESH,
980         "save_wireless_advanced"},
981#else
982        {"Wireless_WDS-ath0", "save", "wireless_2", 0, REFRESH, "save_wds"},
983        {"Wireless_WDS-ath1", "save", "wireless_2", 0, REFRESH, "save_wds"},
984        {"Wireless_WDS-ath2", "save", "wireless_2", 0, REFRESH, "save_wds"},
985        {"Wireless_WDS-ath3", "save", "wireless_2", 0, REFRESH, "save_wds"},
986#endif
987        {"Ping", "startup", "", 1, REFRESH, "ping_startup"},
988        {"Ping", "shutdown", "", 1, REFRESH, "ping_shutdown"},
989        {"Ping", "firewall", "", 1, SYS_RESTART, "ping_firewall"},
990        {"Ping", "custom", "", 0, REFRESH, "ping_custom"},
991        {"QoS", "add_svc", "", 0, REFRESH, "qos_add_svc"},
992        {"QoS", "add_ip", "", 0, REFRESH, "qos_add_ip"},
993        {"QoS", "add_mac", "", 0, REFRESH, "qos_add_mac"},
994        {"QoS", "add_dev", "", 0, REFRESH, "qos_add_dev"},
995        {"QoS", "save", "filters", 1, REFRESH, "qos_save"},
996        /*
997         * end Sveasoft addition
998         */
999        {"Forward", "add_forward", "", 0, REFRESH, "forward_add"},
1000        {"Forward", "remove_forward", "", 0, REFRESH, "forward_remove"},
1001        {"Filters", "add_filter", "", 0, REFRESH, "filter_add"},
1002        {"Filters", "remove_filter", "", 0, REFRESH, "filter_remove"},
1003        {"Wireless_Basic", "add_vifs", "", 0, REFRESH, "add_vifs"},
1004        {"Wireless_Basic", "remove_vifs", "", 0, REFRESH, "remove_vifs"},
1005#ifdef HAVE_FREERADIUS
1006        {"FreeRadius", "generate_certificate", "", 0, REFRESH,
1007         "radius_generate_certificate"},
1008        {"FreeRadius", "add_radius_user", "", 0, REFRESH, "add_radius_user"},
1009        {"FreeRadius", "del_radius_user", "", 0, REFRESH, "del_radius_user"},
1010        {"FreeRadius", "add_radius_client", "", 0, REFRESH,
1011         "add_radius_client"},
1012        {"FreeRadius", "del_radius_client", "", 0, REFRESH,
1013         "del_radius_client"},
1014        {"FreeRadius", "save_radius_user", "", 0, REFRESH, "save_radius_user"},
1015#endif
1016#ifdef HAVE_POKER
1017        {"Poker", "add_poker_user", "", 0, REFRESH, "add_poker_user"},
1018        {"Poker", "del_poker_user", "", 0, REFRESH, "del_poker_user"},
1019        {"Poker", "save_poker_user", "", 0, REFRESH, "save_poker_user"},
1020        {"PokerEdit", "poker_loaduser", "", 0, REFRESH, "poker_loaduser"},
1021        {"PokerEdit", "poker_checkout", "", 0, REFRESH, "poker_checkout"},
1022        {"PokerEdit", "poker_buy", "", 0, REFRESH, "poker_buy"},
1023        {"PokerEdit", "poker_credit", "", 0, REFRESH, "poker_credit"},
1024        {"PokerEdit", "poker_back", "", 0, REFRESH, "poker_back"},
1025#endif
1026#ifdef HAVE_BONDING
1027        {"Networking", "add_bond", "", 0, REFRESH, "add_bond"},
1028        {"Networking", "del_bond", "", 0, REFRESH, "del_bond"},
1029#endif
1030#ifdef HAVE_OLSRD
1031        {"Routing", "add_olsrd", "", 0, REFRESH, "add_olsrd"},
1032        {"Routing", "del_olsrd", "", 0, REFRESH, "del_olsrd"},
1033#endif
1034#ifdef HAVE_VLANTAGGING
1035        {"Networking", "add_vlan", "", 0, REFRESH, "add_vlan"},
1036        {"Networking", "add_bridge", "", 0, REFRESH, "add_bridge"},
1037        {"Networking", "add_bridgeif", "", 0, REFRESH, "add_bridgeif"},
1038        {"Networking", "del_vlan", "", 0, REFRESH, "del_vlan"},
1039        {"Networking", "del_bridge", "", 0, REFRESH, "del_bridge"},
1040        {"Networking", "del_bridgeif", "", 0, REFRESH, "del_bridgeif"},
1041        {"Networking", "save_networking", "index", 0, REFRESH,
1042         "save_networking"},
1043        {"Networking", "add_mdhcp", "", 0, REFRESH, "add_mdhcp"},
1044        {"Networking", "del_mdhcp", "", 0, REFRESH, "del_mdhcp"},
1045#endif
1046#ifdef HAVE_IPVS
1047        {"Networking", "add_ipvs", "", 0, REFRESH, "add_ipvs"},
1048        {"Networking", "del_ipvs", "", 0, REFRESH, "del_ipvs"},
1049        {"Networking", "add_ipvstarget", "", 0, REFRESH, "add_ipvstarget"},
1050        {"Networking", "del_ipvstarget", "", 0, REFRESH, "del_ipvstarget"},
1051#endif
1052        {"Wireless_Basic", "save", "wireless", 1, REFRESH, "wireless_save"},
1053#ifdef HAVE_WIVIZ
1054        {"Wiviz_Survey", "Set", "", 0, REFRESH, "set_wiviz"},
1055#endif
1056#ifdef HAVE_REGISTER
1057        {"Register", "activate", "", 1, RESTART, "reg_validate"},
1058#endif
1059        {"index", "changepass", "", 1, REFRESH, "changepass"},
1060#ifdef HAVE_SUPERCHANNEL
1061        {"SuperChannel", "activate", "", 1, REFRESH, "superchannel_validate"},
1062#endif
1063        {"Services", "add_lease", "", 0, REFRESH, "lease_add"},
1064        {"Services", "remove_lease", "", 0, REFRESH, "lease_remove"},
1065#ifdef HAVE_PPPOESERVER
1066        {"PPPoE_Server", "add_chap_user", "", 0, REFRESH, "chap_user_add"},
1067        {"PPPoE_Server", "remove_chap_user", "", 0, REFRESH,
1068         "chap_user_remove"},
1069#endif
1070#ifdef HAVE_CHILLILOCAL
1071        {"Hotspot", "add_user", "", 0, REFRESH, "user_add"},
1072        {"Hotspot", "remove_user", "", 0, REFRESH, "user_remove"},
1073#endif
1074#ifdef HAVE_RADLOCAL
1075        {"Hotspot", "add_iradius", "", 0, REFRESH, "raduser_add"},
1076#endif
1077        {"ForwardSpec", "add_forward_spec", "", 0, REFRESH, "forwardspec_add"},
1078        {"ForwardSpec", "remove_forward_spec", "", 0, REFRESH,
1079         "forwardspec_remove"},
1080        {"Triggering", "add_trigger", "", 0, REFRESH, "trigger_add"},
1081        {"Triggering", "remove_trigger", "", 0, REFRESH, "trigger_remove"},
1082        {"Port_Services", "save_services", "filters", 2, REFRESH,
1083         "save_services_port"},
1084        {"QOSPort_Services", "save_qosservices", "filters", 2, REFRESH,
1085         "save_services_port"},
1086        {"Ping", "start", "", 1, SERVICE_RESTART, "diag_ping_start"},
1087        {"Ping", "stop", "", 0, REFRESH, "diag_ping_stop"},
1088        {"Ping", "clear", "", 0, REFRESH, "diag_ping_clear"},
1089#ifdef HAVE_MILKFISH
1090        {"Milkfish_database", "add_milkfish_user", "", 0, REFRESH,
1091         "milkfish_user_add"},
1092        {"Milkfish_database", "remove_milkfish_user", "", 0, REFRESH,
1093         "milkfish_user_remove"},
1094        {"Milkfish_aliases", "add_milkfish_alias", "", 0, REFRESH,
1095         "milkfish_alias_add"},
1096        {"Milkfish_aliases", "remove_milkfish_alias", "", 0, REFRESH,
1097         "milkfish_alias_remove"},
1098        {"Milkfish_messaging", "send_message", "", 1, SERVICE_RESTART,
1099         "milkfish_sip_message"},
1100#endif
1101#ifdef HAVE_BUFFALO
1102        {"SetupAssistant", "save", "setupassistant", 1, REFRESH,
1103         "setupassistant_save"},
1104        {"SetupAssistant", "wep_key_generate", "setupassistant", 1, REFRESH,
1105         "generate_wep_key"},
1106        {"SetupAssistant", "security", "setupassistant", 1, REFRESH,
1107         "set_security"},
1108        {"SetupAssistant", "keysize", "setupassistant", 1, REFRESH,
1109         "security_save"},
1110        {"Upgrade", "get_upgrades", "firmware", 1, REFRESH,
1111         "get_airstation_upgrades"},
1112#ifdef HAVE_IAS
1113        {"InternetAtStart", "proceed", "internetatstart", 1, REFRESH,
1114         "internetatstart"},
1115        {"InternetAtStart.ajax", "ajax", "intatstart_ajax", 1, REFRESH,
1116         "intatstart_ajax"},
1117#endif
1118#ifdef HAVE_SPOTPASS
1119        {"Nintendo", "save", "spotpass", 1, REFRESH, "nintendo_save"},
1120#endif
1121#endif
1122        {"Join", "Join", "wireless", 1, REFRESH, "wireless_join"},
1123#ifdef HAVE_NAS_SERVER
1124        {"NAS", "save", "nassrv", 1, REFRESH, "nassrv_save"},
1125#endif
1126#ifdef HAVE_MINIDLNA
1127        {"NAS", "save", "nassrv", 1, REFRESH, "dlna_save"},
1128#endif
1129#if defined(HAVE_WPS) || defined(HAVE_AOSS)
1130        {"AOSS", "save", "aoss", 1, REFRESH, "aoss_save"},
1131        {"AOSS", "start", "aoss", 1, REFRESH, "aoss_start"},
1132#ifdef HAVE_WPS
1133        {"AOSS", "wps_register", "aoss", 1, REFRESH, "wps_register"},
1134        {"AOSS", "wps_ap_register", "aoss", 1, REFRESH, "wps_ap_register"},
1135        {"AOSS", "wps_forcerelease", "aoss", 1, REFRESH, "wps_forcerelease"},
1136        {"AOSS", "wps_configure", "aoss", 1, REFRESH, "wps_configure"},
1137#endif
1138#endif
1139};
1140
1141static struct gozila_action *handle_gozila_action(char *name, char *type)
1142{
1143        struct gozila_action *v;
1144
1145        if (!name || !type)
1146                return NULL;
1147
1148        for (v = gozila_actions; v < &gozila_actions[STRUCT_LEN(gozila_actions)]; v++) {
1149                if (!strcmp(v->name, name) && !strcmp(v->type, type)) {
1150                        return v;
1151                }
1152        }
1153        return NULL;
1154}
1155
1156static char my_next_page[30] = "";
1157static int gozila_cgi(webs_t wp, char_t * urlPrefix, char_t * webDir, int arg, char_t * url, char_t * path, char_t * query)
1158{
1159        char *submit_button, *submit_type, *next_page;
1160        int action = REFRESH;
1161        int sleep_time;
1162        struct gozila_action *act;
1163
1164        nvram_seti("gozila_action", 1);
1165        my_next_page[0] = '\0';
1166        submit_button = websGetVar(wp, "submit_button", NULL);  /* every html
1167                                                                 * must have
1168                                                                 * the name */
1169        submit_type = websGetVar(wp, "submit_type", NULL);      /* add, del,
1170                                                                 * renew,
1171                                                                 * release
1172                                                                 * ..... */
1173
1174        fprintf(stderr, "submit_button=[%s] submit_type=[%s]\n", submit_button, submit_type);
1175        act = handle_gozila_action(submit_button, submit_type);
1176
1177        if (act) {
1178                fprintf(stderr, "name=[%s] type=[%s] service=[%s] sleep=[%d] action=[%d]\n", act->name, act->type, act->service, act->sleep_time, act->action);
1179                sleep_time = act->sleep_time;
1180                action = act->action;
1181                if (act->goname) {
1182                        start_gozila(act->goname, wp);
1183                }
1184
1185                if (nvram_get("nowebaction") == NULL) {
1186                        addAction(act->service);
1187                } else
1188                        nvram_unset("nowebaction");
1189        } else {
1190                sleep_time = 0;
1191                action = REFRESH;
1192        }
1193
1194        if (action == REFRESH) {
1195                sleep(sleep_time);
1196        } else if (action == SERVICE_RESTART) {
1197                sys_commit();
1198                service_restart();
1199                sleep(sleep_time);
1200        } else if (action == SYS_RESTART) {
1201                sys_commit();
1202                sys_restart();
1203        } else if (action == RESTART) {
1204                sys_commit();
1205                sys_restart();
1206        }
1207
1208        if (my_next_page[0] != '\0') {
1209                sprintf(path, "%s", my_next_page);
1210        } else {
1211                next_page = websGetVar(wp, "next_page", NULL);
1212                if (next_page)
1213                        sprintf(path, "%s", next_page);
1214                else
1215                        sprintf(path, "%s.asp", submit_button);
1216        }
1217        if (!strncmp(path, "WL_FilterTable", 14))
1218                do_filtertable(NULL, NULL, path, wp, NULL);     // refresh
1219#ifdef HAVE_FREERADIUS
1220        else if (!strncmp(path, "FreeRadiusCert", 14))
1221                do_radiuscert(NULL, NULL, path, wp, NULL);      // refresh
1222#endif
1223        // #ifdef HAVE_MADWIFI
1224        else if (!strncmp(path, "WL_ActiveTable", 14))
1225                do_activetable(NULL, NULL, path, wp, NULL);     // refresh
1226        else if (!strncmp(path, "Wireless_WDS", 12))
1227                do_wds(NULL, NULL, path, wp, NULL);     // refresh
1228        // #endif
1229        else if (!strncmp(path, "Wireless_Advanced", 17))
1230                do_wireless_adv(NULL, NULL, path, wp, NULL);    // refresh
1231        else
1232                do_ej(NULL, NULL, path, wp, NULL);      // refresh
1233        websDone(wp, 200);
1234
1235        nvram_seti("gozila_action", 0);
1236        nvram_seti("generate_key", 0);
1237        nvram_seti("clone_wan_mac", 0);
1238
1239        return 1;
1240}
1241
1242static struct apply_action apply_actions[] = {
1243        /*
1244         * name, service, sleep_time, action, function_to_execute
1245         */
1246
1247        /*
1248         * SETUP
1249         */
1250        {"index", "index", 0, SERVICE_RESTART, NULL},
1251        {"DDNS", "ddns", 0, SERVICE_RESTART, "ddns_save_value"},
1252        {"Routing", "routing", 0, SERVICE_RESTART, NULL},
1253        {"Vlan", "", 0, SYS_RESTART, "port_vlan_table_save"},
1254        {"eop-tunnel", "eop", 0, SERVICE_RESTART, NULL},
1255
1256        /*
1257         * WIRELESS
1258         */
1259        {"Wireless_Basic", "wireless", 0, SERVICE_RESTART, NULL},       // Only for
1260        // V23, since
1261        // V24 it's a
1262        // gozilla
1263        // save
1264        {"Wireless_Advanced-wl0", "wireless_2", 0, SERVICE_RESTART,
1265         "save_wireless_advanced"},
1266        {"Wireless_Advanced-wl1", "wireless_2", 0, SERVICE_RESTART,
1267         "save_wireless_advanced"},
1268        {"Wireless_Advanced-wl2", "wireless_2", 0, SERVICE_RESTART,
1269         "save_wireless_advanced"},
1270        {"Wireless_MAC", "wireless_2", 0, SERVICE_RESTART, "save_macmode"},
1271        {"WL_FilterTable", "macfilter", 0, SERVICE_RESTART, NULL},
1272        {"Wireless_WDS", "wireless_2", 0, SERVICE_RESTART, NULL},
1273        {"WL_WPATable", "wireless_2", 0, SERVICE_RESTART, NULL},
1274
1275        /*
1276         * MANAGEMENT
1277         */
1278        {"Management", "management", 0, SYS_RESTART, NULL},
1279        {"Services", "services", 0, SERVICE_RESTART, NULL},
1280        {"Alive", "alive", 0, SERVICE_RESTART, NULL},
1281
1282        /*
1283         * SERVICES
1284         */
1285        {"PPPoE_Server", "services", 0, SERVICE_RESTART, NULL},
1286        {"PPTP", "services", 0, SERVICE_RESTART, NULL},
1287        {"USB", "usbdrivers", 0, SERVICE_RESTART, NULL},
1288        {"NAS", "nassrv", 0, SERVICE_RESTART, NULL},
1289        {"Hotspot", "hotspot", 0, SERVICE_RESTART, "hotspot_save"},
1290        {"Hotspot", "hotspot", 0, SERVICE_RESTART, NULL},
1291//      {"AnchorFree", "anchorfree", 0, SERVICE_RESTART, NULL},
1292        {"Nintendo", "nintendo", 0, SERVICE_RESTART, NULL},
1293
1294        /*
1295         * APP & GAMING
1296         */
1297        {"Forward", "forward", 0, SERVICE_RESTART, NULL},
1298        {"ForwardSpec", "forward", 0, SERVICE_RESTART, NULL},
1299        {"Triggering", "filters", 0, SERVICE_RESTART, NULL},
1300        {"DMZ", "filters", 0, SERVICE_RESTART, NULL},
1301        {"Filters", "filters", 0, SERVICE_RESTART, NULL},
1302        {"FilterIPMAC", "filters", 0, SERVICE_RESTART, NULL},
1303#ifdef HAVE_UPNP
1304        {"UPnP", "forward_upnp", 0, SERVICE_RESTART, "tf_upnp"},
1305#endif
1306        /*
1307         * SECURITY
1308         */
1309        {"Firewall", "filters", 0, SERVICE_RESTART, NULL},
1310        {"VPN", "filters", 0, SERVICE_RESTART, NULL},
1311#ifdef HAVE_MILKFISH
1312        {"Milkfish", "milkfish", 0, SERVICE_RESTART, NULL},
1313#endif
1314        /*
1315         * Obsolete {"WL_WEPTable", "", 0, SERVICE_RESTART, NULL}, {"Security",
1316         * "", 1, RESTART, NULL}, {"System", "", 0, RESTART, NULL}, {"DHCP",
1317         * "dhcp", 0, SERVICE_RESTART, NULL}, {"FilterIP", "filters", 0,
1318         * SERVICE_RESTART, NULL}, {"FilterMAC", "filters", 0, SERVICE_RESTART,
1319         * NULL}, {"FilterPort", "filters", 0, SERVICE_RESTART, NULL},
1320         * {"Wireless", "wireless", 0, SERVICE_RESTART, NULL}, {"Log", "logging",
1321         * 0, SERVICE_RESTART, NULL}, //moved to Firewall {"QoS", "qos", 0,
1322         * SERVICE_RESTART, NULL}, //gozilla does the save
1323         */
1324        {"InternetAtStart", "finish", 0, SYS_RESTART, NULL},
1325
1326};
1327
1328static struct apply_action *handle_apply_action(char *name)
1329{
1330        struct apply_action *v;
1331
1332        cprintf("apply name = \n", name);
1333        if (!name)
1334                return NULL;
1335
1336        for (v = apply_actions; v < &apply_actions[STRUCT_LEN(apply_actions)]; v++) {
1337                if (!strcmp(v->name, name)) {
1338                        return v;
1339                }
1340        }
1341        return NULL;
1342}
1343
1344static int getFileLen(FILE * in)
1345{
1346        int len;
1347
1348        fseek(in, 0, SEEK_END);
1349        len = ftell(in);
1350        rewind(in);
1351        return len;
1352}
1353
1354static void do_logout(void)     // static functions are not exportable,
1355                                // additionally this is no ej function
1356{
1357        send_authenticate(auth_realm);
1358}
1359
1360static int apply_cgi(webs_t wp, char_t * urlPrefix, char_t * webDir, int arg, char_t * url, char_t * path, char_t * query)
1361{
1362        int action = NOTHING;
1363        char *value;
1364        char *submit_button, *next_page;
1365        int sleep_time = 0;
1366        int need_commit = 1;
1367
1368        cprintf("need reboot\n");
1369        int need_reboot = atoi(websGetVar(wp, "need_reboot", "0"));
1370
1371        cprintf("apply");
1372
1373        /**********   get "change_action" and launch gozila_cgi if needed **********/
1374
1375        value = websGetVar(wp, "change_action", "");
1376        cprintf("get change_action = %s\n", value);
1377
1378        if (value && !strcmp(value, "gozila_cgi")) {
1379                fprintf(stderr, "[APPLY] %s %s %s\n", websGetVar(wp, "submit_button", NULL), websGetVar(wp, "submit_type", NULL), websGetVar(wp, "call", NULL));
1380                gozila_cgi(wp, urlPrefix, webDir, arg, url, path, query);
1381                return 1;
1382        }
1383
1384  /***************************************************************************/
1385        if (!query) {
1386                goto footer;
1387        }
1388        if (legal_ip_netmask("lan_ipaddr", "lan_netmask", nvram_safe_get("http_client_ip")) == TRUE)
1389                nvram_set("browser_method", "USE_LAN");
1390        else
1391                nvram_set("browser_method", "USE_WAN");
1392
1393  /**********   get all webs var **********/
1394
1395        submit_button = websGetVar(wp, "submit_button", "");
1396        cprintf("get submit_button = %s\n", submit_button);
1397
1398        need_commit = atoi(websGetVar(wp, "commit", "1"));
1399        cprintf("get need_commit = %d\n", need_commit);
1400
1401        value = websGetVar(wp, "action", "");
1402        cprintf("get action = %s\n", value);
1403
1404  /**********   check action to do **********/
1405
1406  /** Apply **/
1407        if (!strcmp(value, "Apply") || !strcmp(value, "ApplyTake")) {
1408                struct apply_action *act;
1409
1410                cprintf("validate cgi");
1411                validate_cgi(wp);
1412                cprintf("handle apply action\n");
1413                act = handle_apply_action(submit_button);
1414                cprintf("done\n");
1415                // If web page configuration is changed, the EZC configuration
1416                // function should be disabled.(2004-07-29)
1417                nvram_seti("is_default", 0);
1418                nvram_seti("is_modified", 1);
1419                if (act) {
1420                        fprintf(stderr, "%s:submit_button=[%s] service=[%s] sleep_time=[%d] action=[%d]\n", value, act->name, act->service, act->sleep_time, act->action);
1421
1422                        if ((act->action == SYS_RESTART)
1423                            || (act->action == SERVICE_RESTART)) {
1424                                if (nvram_get("nowebaction") == NULL) {
1425                                        addAction(act->service);
1426                                } else
1427                                        nvram_unset("nowebaction");
1428                        }
1429                        sleep_time = act->sleep_time;
1430                        action = act->action;
1431
1432                        if (act->goname)
1433                                start_gozila(act->goname, wp);
1434                } else {
1435                        // nvram_set ("action_service", "");
1436                        sleep_time = 1;
1437                        action = RESTART;
1438                }
1439                diag_led(DIAG, STOP_LED);
1440                sys_commit();
1441        }
1442
1443  /** Restore defaults **/
1444        else if (!strncmp(value, "Restore", 7)) {
1445                ACTION("ACT_SW_RESTORE");
1446                nvram_seti("sv_restore_defaults", 1);
1447#ifdef HAVE_BUFFALO_SA
1448                int region_sa = 0;
1449                if (nvram_default_match("region", "SA", ""))
1450                        region_sa = 1;
1451#endif
1452                killall("udhcpc", SIGKILL);
1453                sys_commit();
1454#ifdef HAVE_X86
1455#ifdef HAVE_ERC
1456                eval("nvram", "restore", "/etc/defaults/x86ree.backup");
1457                eval("reboot");
1458                eval("event", "5", "1", "15");
1459#endif
1460                char drive[64];
1461                sprintf(drive, "/dev/%s", getdisc());
1462                FILE *in = fopen(drive, "r+b");
1463                fseeko(in, 0, SEEK_END);
1464                off_t mtdlen = ftello(in);
1465                fseeko(in, mtdlen - (65536 * 2), SEEK_SET);
1466                int i;
1467                for (i = 0; i < 65536; i++)
1468                        putc(0, in);    // erase backup area
1469                fclose(in);
1470                eval("mount", "/usr/local", "-o", "remount,rw");
1471                eval("rm", "-f", "/tmp/nvram/*");       // delete nvram database
1472                unlink("/tmp/nvram/.lock");     // delete nvram database
1473                eval("rm", "-f", "/usr/local/nvram/*"); // delete nvram
1474                // database
1475                eval("mount", "/usr/local", "-o", "remount,ro");
1476                eval("sync");
1477#elif HAVE_RB600
1478                char drive[64];
1479                sprintf(drive, "/dev/sda");
1480                FILE *in = fopen(drive, "r+b");
1481                fseeko(in, 0, SEEK_END);
1482                off_t mtdlen = ftello(in);
1483                fseeko(in, mtdlen - (65536 * 2), SEEK_SET);
1484                int i;
1485                for (i = 0; i < 65536; i++)
1486                        putc(0, in);    // erase backup area
1487                fclose(in);
1488                eval("rm", "-f", "/tmp/nvram/*");       // delete nvram database
1489                unlink("/tmp/nvram/.lock");     // delete nvram database
1490                eval("rm", "-f", "/usr/local/nvram/*"); // delete nvram
1491                eval("sync");
1492#elif HAVE_OPENRISC
1493#ifdef HAVE_ERC
1494                eval("cp", "-f", "/etc/defaults/nvram.bin", "/usr/local/nvram/nvram.bin");
1495                eval("sync");
1496                eval("sync");
1497                sleep(5);
1498                eval("event", "5", "1", "15");
1499#endif
1500                eval("mount", "/usr/local", "-o", "remount,rw");
1501                eval("rm", "-f", "/tmp/nvram/*");       // delete nvram database
1502                unlink("/tmp/nvram/.lock");     // delete nvram database
1503                eval("rm", "-f", "/usr/local/nvram/*"); // delete nvram
1504                // database
1505                eval("mount", "/usr/local", "-o", "remount,ro");
1506#elif HAVE_RB500
1507                eval("rm", "-f", "/tmp/nvram/*");       // delete nvram database
1508                unlink("/tmp/nvram/.lock");     // delete nvram database
1509                eval("rm", "-f", "/etc/nvram/*");       // delete nvram database
1510#elif HAVE_MAGICBOX
1511                eval("rm", "-f", "/tmp/nvram/*");       // delete nvram database
1512                unlink("/tmp/nvram/.lock");     // delete nvram database
1513                eval("erase", "nvram");
1514#else
1515                eval("erase", "nvram");
1516#endif
1517#ifdef HAVE_BUFFALO_SA
1518                nvram_seti("sv_restore_defaults", 1);
1519                if (region_sa)
1520                        nvram_set("region", "SA");
1521#endif
1522                sys_commit();
1523
1524                action = REBOOT;
1525        }
1526
1527  /** Reboot **/
1528        else if (!strncmp(value, "Reboot", 6)) {
1529                action = REBOOT;
1530        }
1531
1532        /** GUI Logout **/// Experimental, not work yet ...
1533        else if (!strncmp(value, "Logout", 6)) {
1534                do_ej(NULL, NULL, "Logout.asp", wp, NULL);
1535                websDone(wp, 200);
1536                do_logout();
1537                return 1;
1538        }
1539
1540        /*
1541         * DEBUG : Invalid action
1542         */
1543        else
1544                websDebugWrite(wp, "Invalid action %s<br />", value);
1545
1546footer:
1547
1548        if (nvram_matchi("do_reboot", 1)) {
1549                action = REBOOT;
1550        }
1551        /*
1552         * The will let PC to re-get a new IP Address automatically
1553         */
1554        if (need_reboot)
1555                action = REBOOT;
1556
1557        if (!strcmp(value, "Apply")) {
1558                action = NOTHING;
1559        }
1560
1561        if (action != REBOOT) {
1562                if (my_next_page[0] != '\0')
1563                        sprintf(path, "%s", my_next_page);
1564                else {
1565                        next_page = websGetVar(wp, "next_page", NULL);
1566                        if (next_page)
1567                                sprintf(path, "%s", next_page);
1568                        else
1569                                sprintf(path, "%s.asp", submit_button);
1570                }
1571
1572                if (!strncmp(path, "WL_FilterTable", 14))
1573                        do_filtertable(NULL, NULL, path, wp, NULL);     // refresh
1574#ifdef HAVE_FREERADIUS
1575                else if (!strncmp(path, "FreeRadiusCert", 14))
1576                        do_radiuscert(NULL, NULL, path, wp, NULL);      // refresh     
1577#endif
1578                else if (!strncmp(path, "WL_ActiveTable", 14))
1579                        do_activetable(NULL, NULL, path, wp, NULL);     // refresh     
1580                else if (!strncmp(path, "Wireless_WDS", 12))
1581                        do_wds(NULL, NULL, path, wp, NULL);     // refresh
1582                else if (!strncmp(path, "Wireless_Advanced", 17))
1583                        do_wireless_adv(NULL, NULL, path, wp, NULL);    // refresh
1584                else
1585                        do_ej(NULL, NULL, path, wp, NULL);      // refresh
1586                websDone(wp, 200);
1587        } else {
1588#ifndef HAVE_WRK54G
1589                do_ej(NULL, NULL, "Reboot.asp", wp, NULL);
1590                websDone(wp, 200);
1591#endif
1592                // sleep (5);
1593                sys_reboot();
1594                return 1;
1595        }
1596
1597        nvram_set("upnp_wan_proto", "");
1598        sleep(sleep_time);
1599        if ((action == RESTART) || (action == SYS_RESTART))
1600                sys_restart();
1601        else if (action == SERVICE_RESTART)
1602                service_restart();
1603
1604        return 1;
1605
1606}
1607
1608//int auth_check( char *dirname, char *authorization )
1609int do_auth(webs_t wp, char *userid, char *passwd, char *realm, char *authorisation, int (*auth_check) (char *userid, char *passwd, char *dirname, char *authorisation))
1610{
1611        strncpy(userid, nvram_safe_get("http_username"), AUTH_MAX);
1612        strncpy(passwd, nvram_safe_get("http_passwd"), AUTH_MAX);
1613        // strncpy(realm, MODEL_NAME, AUTH_MAX);
1614#if defined(HAVE_ERC) || defined(HAVE_IPR)
1615        strncpy(realm, "LOGIN", AUTH_MAX);
1616        wp->userid = 0;
1617        if (auth_check(userid, passwd, realm, authorisation))
1618                return 1;
1619        wp->userid = 1;
1620        char passout[MD5_OUT_BUFSIZE];
1621        strncpy(userid, zencrypt("SuperAdmin", passout), AUTH_MAX);
1622        strncpy(passwd, nvram_safe_get("newhttp_passwd"), AUTH_MAX);
1623        if (auth_check(userid, passwd, realm, authorisation))
1624                return 1;
1625        userid = 0;
1626#else
1627        wp->userid = 0;
1628        strncpy(realm, nvram_safe_get("router_name"), AUTH_MAX);
1629        if (auth_check(userid, passwd, realm, authorisation))
1630                return 1;
1631#endif
1632        return 0;
1633}
1634
1635static int do_cauth(webs_t wp, char *userid, char *passwd, char *realm, char *authorisation, int (*auth_check) (char *userid, char *passwd, char *dirname, char *authorisation))
1636{
1637        if (nvram_matchi("info_passwd", 0))
1638                return 1;
1639        return do_auth(wp, userid, passwd, realm, authorisation, auth_check);
1640}
1641
1642#ifdef HAVE_REGISTER
1643static int do_auth_reg(webs_t wp, char *userid, char *passwd, char *realm, char *authorisation, int (*auth_check) (char *userid, char *passwd, char *dirname, char *authorisation))
1644{
1645        if (!isregistered())
1646                return 1;
1647        return do_auth(wp, userid, passwd, realm, authorisation, auth_check);
1648}
1649#endif
1650
1651#undef HAVE_DDLAN
1652
1653#ifdef HAVE_DDLAN
1654static int do_auth2(webs_t wp, char *userid, char *passwd, char *realm, char *authorisation, int (*auth_check) (char *userid, char *passwd, char *dirname, char *authorisation))
1655{
1656        strncpy(userid, nvram_safe_get("http2_username"), AUTH_MAX);
1657        strncpy(passwd, nvram_safe_get("http2_passwd"), AUTH_MAX);
1658        // strncpy(realm, MODEL_NAME, AUTH_MAX);
1659        strncpy(realm, nvram_safe_get("router_name"), AUTH_MAX);
1660        if (auth_check(wp, userid, passwd, realm, authorisation))
1661                return 1;
1662        return 0;
1663}
1664#endif
1665// #ifdef EZC_SUPPORT
1666char ezc_version[128];
1667
1668// #endif
1669
1670extern int post;
1671
1672static char *post_buf = NULL;
1673static void                     // support GET and POST 2003-08-22
1674do_apply_post(char *url, webs_t stream, int len, char *boundary)
1675{
1676        int count;
1677        if (post == 1) {
1678                post_buf = (char *)realloc(post_buf, len + 1);
1679
1680                if (!post_buf) {
1681                        cprintf("The POST data exceed length limit!\n");
1682                        return;
1683                }
1684                /*
1685                 * Get query
1686                 */
1687                if (!(count = wfread(post_buf, 1, len, stream)))
1688                        return;
1689                post_buf[count] = '\0';;
1690                len -= strlen(post_buf);
1691
1692                /*
1693                 * Slurp anything remaining in the request
1694                 */
1695                char *buf = malloc(len);
1696                wfgets(buf, len, stream);
1697                free(buf);
1698                init_cgi(post_buf);
1699        }
1700}
1701
1702#if !defined(HAVE_X86) && !defined(HAVE_MAGICBOX)
1703static void do_cfebackup(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query)
1704{
1705        system2("cat /dev/mtd/0 > /tmp/cfe.bin");
1706        do_file_attach(handler, "/tmp/cfe.bin", stream, NULL, "cfe.bin");
1707        unlink("/tmp/cfe.bin");
1708}
1709#endif
1710
1711#ifdef HAVE_PRIVOXY
1712static void do_wpad(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query)
1713{
1714        FILE *fp;
1715
1716        fp = fopen("/tmp/wpad.dat", "wb");
1717
1718        if (fp != NULL) {
1719                fprintf(fp, "function FindProxyForURL(url, host) {\n"   //
1720                        "var proxy = \"PROXY %s:8118; DIRECT\";\n"      //
1721                        "var direct = \"DIRECT\";\n"    //
1722                        "if(isPlainHostName(host)) return direct;\n"    //
1723                        "if (\n" "url.substring(0, 4) == \"ftp:\" ||\n" //
1724                        "url.substring(0, 6) == \"rsync:\"\n" ")\n"     //
1725                        "return direct;\n" "return proxy;\n" "}", nvram_safe_get("lan_ipaddr"));
1726                fclose(fp);
1727        }
1728
1729        do_file_attach(handler, "/tmp/wpad.dat", stream, NULL, "wpad.dat");
1730}
1731#endif
1732
1733#ifdef HAVE_ROUTERSTYLE
1734static void do_stylecss(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query)
1735{
1736        char *style = nvram_get("router_style");
1737
1738        if (query != NULL)
1739                style = query;
1740
1741        unsigned int sdata[33];
1742        memset(sdata, 0, sizeof(sdata));
1743        unsigned int blue[33] = {
1744                0x36f, 0xfff, 0x68f, 0x24d, 0x24d, 0x68f,
1745                0x57f, 0xccf, 0x78f, 0x35d, 0x35c, 0x78f,
1746                0x78f, 0xfff, 0x9af, 0x46e, 0x46e, 0x9af,
1747                0x36f, 0xccf, 0xfff,
1748                0x69f, 0xfff, 0xfff, 0x999, 0x69f, 0x69f,
1749                0xccf, 0x78f, 0xfff,
1750                0xfff, 0x36f, 0xccc
1751        };
1752
1753        unsigned int cyan[33] = {
1754                0x099, 0xfff, 0x3bb, 0x066, 0x066, 0x3bb,
1755                0x3bb, 0xcff, 0x4cc, 0x1aa, 0x1aa, 0x4cc,
1756                0x6cc, 0xfff, 0x8dd, 0x5bb, 0x5bb, 0x8dd,
1757                0x099, 0xcff, 0xfff,
1758                0x3bb, 0xfff, 0xfff, 0x999, 0x3bb, 0x3bb,
1759                0xcff, 0x6cc, 0xfff,
1760                0xfff, 0x099, 0xcff
1761        };
1762
1763        unsigned int elegant[33] = {
1764                0x30519c, 0xfff, 0x496fc7, 0x496fc7, 0x496fc7, 0x496fc7,
1765                0x496fc7, 0xfff, 0x6384cf, 0x6384cf, 0x6384cf, 0x6384cf,
1766                0x6384cf, 0xfff, 0x849dd9, 0x849dd9, 0x849dd9, 0x849dd9,
1767                0x30519c, 0xfff, 0xfff,
1768                0x496fc7, 0xfff, 0xfff, 0x999, 0x496fc7, 0x496fc7,
1769                0xfff, 0x6384cf, 0xfff,
1770                0xfff, 0x30519c, 0xccc
1771        };
1772
1773        unsigned int green[33] = {
1774                0x090, 0xfff, 0x3b3, 0x060, 0x060, 0x3b3,
1775                0x3b3, 0xcfc, 0x4c4, 0x1a1, 0x1a1, 0x4c4,
1776                0x6c6, 0xfff, 0x8d8, 0x5b5, 0x5b5, 0x8d8,
1777                0x090, 0xcfc, 0xfff,
1778                0x3b3, 0xfff, 0xfff, 0x999, 0x3b3, 0x3b3,
1779                0xcfc, 0x6c6, 0xfff,
1780                0xfff, 0x090, 0xcfc
1781        };
1782
1783        unsigned int orange[33] = {
1784                0xf26522, 0xfff, 0xff8400, 0xff8400, 0xff8400, 0xff8400,
1785                0xff8400, 0xfff, 0xfeb311, 0xfeb311, 0xfeb311, 0xfeb311,
1786                0xff9000, 0xfff, 0xffa200, 0xffa200, 0xffa200, 0xffa200,
1787                0xf26522, 0xfff, 0xfff,
1788                0xff8400, 0xfff, 0xfff, 0x999, 0xff8400, 0xff8400,
1789                0xfff, 0xff9000, 0xfff,
1790                0xfff, 0xf26522, 0xccc
1791        };
1792
1793        unsigned int red[33] = {
1794                0xc00, 0xfff, 0xe33, 0x800, 0x800, 0xe33,
1795                0xd55, 0xfcc, 0xe77, 0xc44, 0xc44, 0xe77,
1796                0xe77, 0xfff, 0xf99, 0xd55, 0xd55, 0xf99,
1797                0xc00, 0xfcc, 0xfff,
1798                0xd55, 0xfff, 0xfff, 0x999, 0xd55, 0xd55,
1799                0xfcc, 0xe77, 0xfff,
1800                0xfff, 0xc00, 0xfcc
1801        };
1802
1803        unsigned int yellow[33] = {
1804                0xeec900, 0x000, 0xee3, 0x880, 0x880, 0xee3,
1805                0xffd700, 0x660, 0xee7, 0xbb4, 0xbb4, 0xee7,
1806                0xeec900, 0x000, 0xff9, 0xcc5, 0xcc5, 0xff9,
1807                0xeec900, 0x660, 0x000,
1808                0xffd700, 0x000, 0xfff, 0x999, 0xffd700, 0xeec900,
1809                0x660, 0xffd700, 0x000,
1810                0x333, 0xeec900, 0xffd700
1811        };
1812
1813        if (!strcmp(style, "blue"))
1814                memcpy(sdata, blue, sizeof(blue));
1815        else if (!strcmp(style, "cyan"))
1816                memcpy(sdata, cyan, sizeof(cyan));
1817        else if (!strcmp(style, "yellow"))
1818                memcpy(sdata, yellow, sizeof(yellow));
1819        else if (!strcmp(style, "green"))
1820                memcpy(sdata, green, sizeof(green));
1821        else if (!strcmp(style, "orange"))
1822                memcpy(sdata, orange, sizeof(orange));
1823        else if (!strcmp(style, "red"))
1824                memcpy(sdata, red, sizeof(red));
1825        else                    // default to elegant
1826                memcpy(sdata, elegant, sizeof(elegant));
1827
1828        websWrite(stream, "@import url(../common.css);\n#menuSub,\n#menuMainList li span,\n#help h2 {\nbackground:#%03x;\n"     //
1829                  "color:#%03x;\nborder-color:#%03x #%03x #%03x #%03x;\n}\n#menuSubList li a {\n"       //
1830                  "background:#%03x;\ncolor:#%03x;\nborder-color:#%03x #%03x #%03x #%03x;\n}\n" //
1831                  "#menuSubList li a:hover {\nbackground:#%03x;\ncolor:#%03x;\nborder-color:#%03x #%03x #%03x #%03x;\n}"        //
1832                  "\nfieldset legend {\ncolor:#%03x;\n}\n#help a {\ncolor:#%03x;\n}\n"  //
1833                  "#help a:hover {\ncolor:#%03x;\n}\n.meter .bar {\nbackground-color: #%03x;\n}\n"      //
1834                  ".meter .text {\ncolor:#%03x;\n}\n.progressbar {\nbackground-color: #%03x;\n" //
1835                  "border-color: #%03x;\nfont-size:.09em;\nborder-width:.09em;\n}\n"    //
1836                  ".progressbarblock {\nbackground-color: #%03x;\nfont-size:.09em;\n}"  //
1837                  "\ninput.button {\nbackground: #%03x;\ncolor: #%03x;\n}\n"    //
1838                  "input.button:hover {\nbackground: #%03x;\ncolor: #%03x;\n"   //
1839                  "}\nh2, h3 {\ncolor: #%03x;\nbackground-color: #%03x;\n}"     //
1840                  "\ntable tr th {\ncolor: #%03x;\n}\n", sdata[0], sdata[1], sdata[2], sdata[3], sdata[4], sdata[5],    //
1841                  sdata[6], sdata[7], sdata[8], sdata[9], sdata[10], sdata[11], sdata[12],      //
1842                  sdata[13], sdata[14], sdata[15], sdata[16], sdata[17], sdata[18],     //
1843                  sdata[19], sdata[20], sdata[21], sdata[22],   //
1844                  sdata[23], sdata[24], sdata[25], sdata[26], sdata[27], sdata[28],     //
1845                  sdata[29], sdata[30], sdata[31], sdata[32]);
1846}
1847
1848static void do_stylecss_ie(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query)
1849{
1850        websWrite(stream, ".submitFooter input {\npadding:.362em .453em;\n}\n"  //
1851                  "fieldset {\npadding-top:0;\n}\nfieldset legend {\n"  //
1852                  "margin-left:-9px;\nmargin-bottom:8px;\npadding:0 .09em;\n}\n");
1853}
1854#endif
1855#ifdef HAVE_REGISTER
1856static void do_trial_logo(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query)
1857{
1858#if defined(HAVE_TRIMAX) || defined(HAVE_MAKSAT) || defined(HAVE_VILIM) || defined(HAVE_TELCOM) || defined(HAVE_WIKINGS) || defined(HAVE_NEXTMEDIA)
1859        do_file(method, handler, url, stream, query);
1860#else
1861        if (!isregistered_real()) {
1862                do_file(method, handler, "style/logo-trial.png", stream, query);
1863        } else {
1864                if (iscpe()) {
1865                        do_file(method, handler, "style/logo-cpe.png", stream, query);
1866                } else {
1867                        do_file(method, handler, url, stream, query);
1868                }
1869        }
1870#endif
1871}
1872
1873#endif
1874/*
1875 * static void do_style (char *url, webs_t stream, char *query) { char *style
1876 * = nvram_get ("router_style"); if (style == NULL || strlen (style) == 0)
1877 * do_file ("kromo.css", stream, NULL); else do_file (style, stream, NULL); }
1878 */
1879
1880static void do_mypage(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query)
1881{
1882        char *snamelist = nvram_safe_get("mypage_scripts");
1883        char *next;
1884        char sname[128];
1885        int qnum;
1886        int i = 1;
1887
1888        if (query == NULL || strlen(query) == 0)
1889                qnum = 1;
1890        else
1891                qnum = atoi(query);
1892
1893        foreach(sname, snamelist, next) {
1894                if (qnum == i) {
1895                        strcat(sname, " > /tmp/mypage.tmp");
1896                        system2(sname);
1897                        do_file_attach(handler, "/tmp/mypage.tmp", stream, NULL, "MyPage.asp");
1898                        unlink("/tmp/mypage.tmp");
1899                }
1900                i++;
1901        }
1902
1903        return;
1904
1905}
1906
1907static void do_fetchif(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query)
1908{
1909        char line[256];
1910        int i, llen;
1911        char buffer[256];
1912        char querybuffer[32];
1913
1914        if (query == NULL || strlen(query) == 0)
1915                return;
1916
1917        strncpy(querybuffer, query, 30);
1918        strcat(querybuffer, ":");
1919
1920        int strbuffer = 0;
1921        time_t tm;
1922        struct tm tm_time;
1923
1924        time(&tm);
1925        memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
1926        char *date_fmt = "%a %b %e %H:%M:%S %Z %Y";
1927
1928        strftime(buffer, 200, date_fmt, &tm_time);
1929        strbuffer = strlen(buffer);
1930        buffer[strbuffer++] = '\n';
1931        FILE *in = fopen("/proc/net/dev", "rb");
1932
1933        if (in == NULL)
1934                return;
1935
1936        /* eat first two lines */
1937        fgets(line, sizeof(line), in);
1938        fgets(line, sizeof(line), in);
1939
1940        while (fgets(line, sizeof(line), in) != NULL) {
1941                if (!strstr(line, "mon.") && strstr(line, querybuffer)) {
1942                        llen = strlen(line);
1943                        for (i = 0; i < llen; i++) {
1944                                buffer[strbuffer++] = line[i];
1945                        }
1946                        break;
1947                }
1948        }
1949        fclose(in);
1950
1951        buffer[strbuffer] = 0;
1952        websWrite(stream, "%s", buffer);
1953}
1954
1955static char *getLanguageName()
1956{
1957        char *lang = nvram_get("language");
1958
1959        cprintf("get language %s\n", lang);
1960        char *l = safe_malloc(60);
1961
1962        if (lang == NULL) {
1963                cprintf("return default\n");
1964                sprintf(l, "lang_pack/english.js");
1965                return l;
1966        }
1967        sprintf(l, "lang_pack/%s.js", lang);
1968        cprintf("return %s\n", l);
1969        return l;
1970}
1971
1972static char *scanfile(char *buf, const char *tran)
1973{
1974        char *temp = malloc(256);
1975        char *temp2;
1976        char *temp1;
1977        FILE *fp = getWebsFile(buf);
1978        if (fp) {
1979                temp1 = malloc(strlen(tran) + 3);
1980                strcpy(temp1, tran);
1981                strcat(temp1, "=\"");
1982                int len = strlen(temp1);
1983                int filelen = getWebsFileLen(buf);
1984                int i;
1985                int count = 0;
1986                int ign = 0;
1987                int val = 0;
1988                int prev = 0;
1989                for (i = 0; i < filelen; i++) {
1990                      again:;
1991                        if (count < 256) {
1992                                prev = val;
1993                                val = getc(fp);
1994                                if (val == EOF) {
1995                                        free(temp);
1996                                        free(temp1);
1997                                        return NULL;
1998                                }
1999                                if (!count && (val == ' ' || val == '\r' || val == '\t' || val == '\n'))
2000                                        continue;
2001                        } else {
2002                                int a, v;
2003                                for (a = 0; a < filelen - i; a++) {
2004                                        prev = v;
2005                                        v = getc(fp);
2006                                        if (v == EOF) {
2007                                                free(temp);
2008                                                free(temp1);
2009                                                return NULL;
2010                                        }
2011                                        if (v == '"' && prev != '\\') {
2012                                                if (!ign)
2013                                                        ign = 1;
2014                                                else
2015                                                        ign = 0;
2016
2017                                        } else if (!ign && v == ';') {
2018                                                i += a;
2019                                                count = 0;
2020                                                goto again;
2021                                        }
2022                                }
2023                                free(temp);
2024                                free(temp1);
2025                                fclose(fp);
2026                                return NULL;
2027                        }
2028                        if (count == 255)
2029                                temp = realloc(temp, 512);
2030                        if (count == 511)
2031                                temp = realloc(temp, 1024);
2032                        temp[count++] = val;
2033                        switch (val) {
2034                        case '\r':
2035                        case '\t':
2036                        case '\n':
2037                                continue;
2038                        case '"':
2039                                if (prev != '\\') {
2040                                        if (!ign)
2041                                                ign = 1;
2042                                        else
2043                                                ign = 0;
2044
2045                                }
2046                                break;
2047                        case ';':
2048                                if (!ign) {
2049                                        temp[count] = 0;
2050                                        count = 0;
2051                                        if ((memcmp(temp, temp1, len)) == 0) {
2052                                                temp2 = strtok(temp, "\"");
2053                                                temp2 = strdup(strtok(NULL, "\""));
2054                                                free(temp);
2055                                                free(temp1);
2056                                                fclose(fp);
2057                                                return temp2;
2058                                        }
2059                                }
2060                        }
2061
2062                }
2063                free(temp1);
2064                fclose(fp);
2065        }
2066        free(temp);
2067        return NULL;
2068}
2069
2070struct cacheentry {
2071        char *request;
2072        char *translation;
2073        time_t time;
2074};
2075static int cachecount = 0;
2076static struct cacheentry *translationcache = NULL;
2077static char *cur_language = NULL;
2078static char *private_live_translate(const char *tran)
2079{
2080
2081        if (tran == NULL || !strlen(tran))
2082                return "";
2083        char *lang = getLanguageName();
2084        char buf[64];
2085        sprintf(buf, "%s", lang);
2086        free(lang);
2087
2088        char *result = scanfile(buf, tran);
2089        if (result)
2090                return result;
2091
2092        strcpy(buf, "lang_pack/english.js");    // if string not found, try english
2093        result = scanfile(buf, tran);
2094        if (result)
2095                return result;
2096        return NULL;
2097
2098}
2099
2100static void clear_translationcache(void)
2101{
2102        int i;
2103        if (translationcache && cachecount > 0) {
2104                for (i = 0; i < cachecount; i++) {
2105                        if (translationcache[i].request != NULL) {
2106                                free(translationcache[i].request);
2107                                free(translationcache[i].translation);
2108                                translationcache[i].request = NULL;
2109                                translationcache[i].translation = NULL;
2110                        }
2111                }
2112                free(translationcache);
2113                translationcache = NULL;
2114                cachecount = 0;
2115        }
2116
2117}
2118
2119char *live_translate(const char *tran)
2120{
2121        if (!tran || strlen(tran) == 0)
2122                return "Error";
2123        if (!cur_language) {
2124                cur_language = nvram_safe_get("language");
2125        } else {
2126                if (!nvram_match("language", cur_language)) {
2127                        clear_translationcache();
2128                        cur_language = nvram_safe_get("language");
2129                }
2130        }
2131
2132        time_t cur = time(NULL);
2133        if (translationcache) {
2134                int i;
2135                char *translation = NULL;
2136                for (i = 0; i < cachecount; i++) {
2137                        if (!translation && translationcache[i].request && !strcmp(translationcache[i].request, tran)) {
2138                                translation = translationcache[i].translation;
2139                                translationcache[i].time = cur;
2140                        }
2141                        if (translationcache[i].request != NULL && cur > translationcache[i].time + 120) {      // free translation if not used for 2 minutes
2142                                free(translationcache[i].translation);
2143                                free(translationcache[i].request);
2144                                translationcache[i].request = NULL;
2145                                translationcache[i].translation = NULL;
2146                        }
2147                }
2148                if (translation) {
2149                        return translation;
2150                }
2151        }
2152        char *ret = private_live_translate(tran);
2153        struct cacheentry *entry = NULL;
2154        /* fill hole if there is any */
2155        int i;
2156        for (i = 0; i < cachecount; i++) {
2157                if (translationcache[i].request == NULL) {
2158                        entry = &translationcache[i];
2159                        break;
2160                }
2161
2162        }
2163        if (!entry) {
2164                /* no hole has been found, alloc a new one */
2165                translationcache = (struct cacheentry *)realloc(translationcache, sizeof(struct cacheentry) * (cachecount + 1));
2166                entry = &translationcache[cachecount++];
2167        }
2168        entry->request = strdup(tran);
2169        entry->time = cur;
2170        if (ret)
2171                entry->translation = ret;
2172        else
2173                entry->translation = strdup("Error");
2174        return entry->translation;
2175}
2176
2177#ifdef HAVE_STATUS_SYSLOG
2178static void do_syslog(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query)
2179{
2180
2181        static const char filename[] = "/var/log/messages";
2182
2183        int offset = 0;
2184        int count = 0;
2185        if (sscanf(query, "%d", &offset) != 1)
2186                return;
2187
2188        websWrite(stream, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" //
2189                  "<html>\n" "<head>\n" "<meta http-equiv=\"Content-Type\" content=\"application/xhtml+xml; charset=%s\" />\n"  //
2190                  "<style type=\"text/css\">\n body { font: 9px Tahoma, Arial, sans-serif; font-size: small; color: #666; } \n" //
2191                  " fieldset { border: 1px solid #333; border-radius: 4px; border-width: 1px;}\n</style>\n"     //
2192                  "</head>\n<body>\n<fieldset><legend>System Log</legend>", live_translate("lang_charset.set"));
2193
2194        if (nvram_matchi("syslogd_enable", 1)) {
2195                FILE *fp = fopen(filename, "r");
2196                if (fp != NULL) {
2197                        char line[1024];
2198                        websWrite(stream, "<div style=\"height:740px; overflow-y:auto;\"><table>");
2199                        while (fgets(line, sizeof line, fp) != NULL) {
2200                                count++;
2201                                if (offset < count && ((offset + 50) > count)) {        // show 100 lines
2202                                        // a few sample colors
2203                                        if (strstr(line, ".warn")) {
2204                                                websWrite(stream, "<tr bgcolor=\"#FFFF00\"><td>%s</td></tr>", line);
2205                                        } else if (strstr(line, "authpriv.notice")) {
2206                                                websWrite(stream, "<tr bgcolor=\"#7CFC00\"><td>%s</td></tr>", line);
2207                                        } else if (strstr(line, "mounting unchecked fs")
2208                                                   || strstr(line, "httpd login failure")
2209                                                   || strstr(line, "auth-failure")
2210                                                   || strstr(line, ".err")) {
2211                                                websWrite(stream, "<tr bgcolor=\"#FF0000\"><td>%s</td></tr>", line);
2212                                        } else {
2213                                                websWrite(stream, "<tr><td>%s</td></tr>", line);
2214                                        }
2215                                }
2216
2217                        }
2218                        websWrite(stream, "</table></div>");
2219
2220                        fclose(fp);
2221                }
2222        } else {
2223                websWrite(stream, "<table><tr align=\"center\"><td>No messages available! Syslogd is not enabled!</td></tr></table>");
2224        }
2225        websWrite(stream, "</fieldset><p></body></html>");
2226        return;
2227}
2228#endif
2229static void do_ttgraph(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query)
2230{
2231#define COL_WIDTH 16            /* single column width */
2232
2233        char *next;
2234        char var[80];
2235
2236        unsigned int days;
2237        unsigned int month;
2238        unsigned int year;
2239        int wd;
2240        int i = 0;
2241        char months[12][12] = {
2242                "share.jan", "share.feb", "share.mar", "share.apr", "share.may",
2243                "share.jun",
2244                "share.jul", "share.aug", "share.sep", "share.oct",
2245                "share.nov", "share.dec"
2246        };
2247        unsigned long rcvd[31] = {
2248                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2249                0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2250        };
2251        unsigned long sent[31] = {
2252                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2253                0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2254        };
2255        unsigned long max = 5, smax = 5, f = 1;
2256        unsigned long totin = 0;
2257        unsigned long totout = 0;
2258
2259        if (sscanf(query, "%u-%u", &month, &year) != 2)
2260                return;
2261        if (month < 1 || month > 12)
2262                return;
2263
2264        days = daysformonth(month, year);
2265        wd = weekday(month, 1, year);   // first day in month (mon=0, tue=1,
2266        // ..., sun=6)
2267
2268        char tq[32];
2269
2270        sprintf(tq, "traff-%02u-%u", month, year);
2271        char *tdata = nvram_safe_get(tq);
2272
2273        if (tdata != NULL && strlen(tdata)) {
2274                foreach(var, tdata, next) {
2275                        if (i == days)
2276                                break;  //skip monthly total
2277                        int ret = sscanf(var, "%lu:%lu", &rcvd[i], &sent[i]);
2278                        if (ret != 2)
2279                                break;
2280                        totin += rcvd[i];
2281                        totout += sent[i];
2282                        if (rcvd[i] > max)
2283                                max = rcvd[i];
2284                        if (sent[i] > max)
2285                                max = sent[i];
2286                        i++;
2287                }
2288        }
2289
2290        while (max > smax) {
2291                if (max > (f * 5))
2292                        smax = f * 10;
2293                if (max > (f * 10))
2294                        smax = f * 25;
2295                if (max > (f * 25))
2296                        smax = f * 50;
2297                f = f * 10;
2298        }
2299
2300        char incom[32];
2301
2302        snprintf(incom, 32, "%s", live_translate("status_inet.traffin"));
2303        char outcom[32];
2304
2305        snprintf(outcom, 32, "%s", live_translate("status_inet.traffout"));
2306        char monthname[32];
2307
2308        snprintf(monthname, 32, "%s", live_translate(months[month - 1]));
2309
2310        websWrite(stream, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" //
2311                  "<html>\n" "<head>\n" "<meta http-equiv=\"Content-Type\" content=\"application/xhtml+xml; charset=%s\" />\n"  //
2312                  "<title>dd-wrt traffic graph</title>\n"       //
2313                  "<script type=\"text/javascript\">\n" //
2314                  "//<![CDATA[\n"       //
2315                  "function Show(label) {\n"    //
2316                  "document.getElementById(\"label\").innerHTML = label;\n"     //
2317                  "}\n" "//]]>\n" "</script>\n" "<style type=\"text/css\">\n\n" //
2318                  "#t-graph {position: relative; width: %upx; height: 300px;\n" //
2319                  "  margin: 1.1em 0 3.5em; padding: 0;\n"      //
2320                  "  border: 1px solid gray; list-style: none;\n"       //
2321                  "  font: 9px Tahoma, Arial, sans-serif; color: #666;}\n" "#t-graph ul {margin: 0; padding: 20; list-style: none;}\n"  //
2322                  "#t-graph li {position: absolute; bottom: 0; width: %dpx; z-index: 2;\n"      //
2323                  "  margin: 0; padding: 0;\n"  //
2324                  "  text-align: center; list-style: none;}\n"  //
2325                  "#t-graph li.day {height: 298px; padding-top: 2px; border-right: 1px dotted #C4C4C4; color: #AAA;}\n" //
2326                  "#t-graph li.day_sun {height: 298px; padding-top: 2px; border-right: 1px dotted #C4C4C4; color: #E00;}\n"     //
2327                  "#t-graph li.bar {width: 4px; border: 1px solid; border-bottom: none; color: #000;}\n"        //
2328                  "#t-graph li.bar p {margin: 5px 0 0; padding: 0;}\n"  //
2329                  "#t-graph li.rcvd {left: 3px; background: #228B22;}\n"        //
2330                  "#t-graph li.sent {left: 8px; background: #CD0000;}\n", live_translate("lang_charset.set"), days * COL_WIDTH, COL_WIDTH);
2331
2332        for (i = 0; i < days - 1; i++) {
2333                websWrite(stream, "#t-graph #d%d {left: %dpx;}\n", i + 1, i * COL_WIDTH);
2334        }
2335        websWrite(stream, "#t-graph #d%u {left: %upx; border-right: none;}\n", days, (days - 1) * COL_WIDTH);
2336
2337        websWrite(stream, "#t-graph #ticks {width: %upx; height: 300px; z-index: 1;}\n" //
2338                  "#t-graph #ticks .tick {position: relative; border-bottom: 1px solid #BBB; width: %upx;}\n"   //
2339                  "#t-graph #ticks .tick p {position: absolute; left: 100%%; top: -0.67em; margin: 0 0 0 0.5em;}\n"     //
2340                  "#t-graph #label {width: 500px; bottom: -20px;  z-index: 1; font: 12px Tahoma, Arial, sans-serif; font-weight: bold;}\n"      //
2341                  "</style>\n" "</head>\n\n" "<body>\n" "<ul id=\"t-graph\">\n", days * COL_WIDTH, days * COL_WIDTH);
2342
2343        for (i = 0; i < days; i++) {
2344                websWrite(stream, "<li class=\"day%s\" id=\"d%d\" ", (wd % 7) == 6 ? "_sun" : "", i + 1);
2345                wd++;
2346                websWrite(stream, "onmouseover=\"Show(\'%s %d, %d (%s: %lu MB / %s: %lu MB)\')\" "      //
2347                          "onmouseout=\"Show(\'%s %d (%s: %lu MB / %s: %lu MB)\')\">%d\n<ul>\n"
2348                          "<li class=\"rcvd bar\" style=\"height: %lupx;\"><p></p></li>\n"
2349                          "<li class=\"sent bar\" style=\"height: %lupx;\"><p></p></li>\n</ul>\n</li>\n",
2350                          monthname, i + 1, year, incom, rcvd[i], outcom, sent[i], monthname, year, incom, totin, outcom, totout, i + 1, rcvd[i] * 300 / smax, sent[i] * 300 / smax);
2351
2352        }
2353
2354        websWrite(stream, "<li id=\"ticks\">\n");
2355        for (i = 5; i; i--)     // scale
2356        {
2357                websWrite(stream, "<div class=\"tick\" style=\"height: 59px;\"><p>%d%sMB</p></div>\n", smax * i / 5, (smax > 10000) ? " " : "&nbsp;");
2358        }
2359        websWrite(stream, "</li>\n\n<li id=\"label\">\n%s %d (%s: %lu MB / %s: %lu MB)\n</li>\n" "</ul>\n\n" "</body>\n" "</html>\n", monthname, year, incom, totin, outcom, totout);
2360
2361}
2362
2363static void ttraff_backup(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query)
2364{
2365        system2("echo TRAFF-DATA > /tmp/traffdata.bak");
2366        system2("nvram show | grep traff- >> /tmp/traffdata.bak");
2367        do_file_attach(handler, "/tmp/traffdata.bak", stream, NULL, "traffdata.bak");
2368        unlink("/tmp/traffdata.bak");
2369}
2370
2371static void do_apply_cgi(char *method, struct mime_handler *handler, char *url, webs_t stream, char *q)
2372{
2373        char *path, *query;
2374
2375        if (post == 1) {
2376                query = post_buf;
2377                path = url;
2378        } else {
2379                query = url;
2380                path = strsep(&query, "?") ? : url;
2381                init_cgi(query);
2382        }
2383
2384        if (!query)
2385                return;
2386
2387        apply_cgi(stream, NULL, NULL, 0, url, path, query);
2388        init_cgi(NULL);
2389}
2390
2391#ifdef HAVE_MADWIFI
2392extern int getdevicecount(void);
2393#endif
2394
2395#ifdef HAVE_LANGUAGE
2396static void do_language(char *method, struct mime_handler *handler, char *path, webs_t stream, char *query)     // jimmy,
2397            // https,
2398            // 8/4/2003
2399{
2400        char *langname = getLanguageName();
2401        char *prefix, *lang;
2402
2403        prefix = calloc(strlen(path) - strlen("lang_pack/language.js") + 1, 1);
2404        strncpy(prefix, path, strlen(path) - strlen("lang_pack/language.js"));
2405
2406        asprintf(&lang, "%s%s", prefix, langname);
2407        do_file(method, handler, lang, stream, NULL);
2408
2409        free(lang);
2410        free(prefix);
2411        free(langname);
2412        return;
2413}
2414#endif
2415extern int issuperchannel(void);
2416
2417static char no_cache[] = "Cache-Control: no-cache\r\n" "Pragma: no-cache\r\n" "Expires: 0";
2418
2419struct mime_handler mime_handlers[] = {
2420        // { "ezconfig.asp", "text/html", ezc_version, do_apply_ezconfig_post,
2421        // do_ezconfig_asp, do_auth },
2422#ifdef HAVE_SKYTRON
2423        {"setupindex*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2424#endif
2425#ifdef HAVE_POKER
2426        {"PokerEdit.asp", "text/html", no_cache, NULL, do_ej, NULL, 1},
2427#endif
2428#ifdef HAVE_DDLAN
2429        {"Upgrade*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2430        {"Management*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2431        {"Services*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2432        {"Hotspot*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2433        {"Wireless*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2434        {"WL_*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2435        {"WPA*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2436        {"Log*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2437        {"Alive*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2438        {"Diagnostics*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2439        {"Wol*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2440        {"Factory_Defaults*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2441        {"config*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2442#endif
2443
2444        {"changepass.asp", "text/html", no_cache, NULL, do_ej, NULL, 1},
2445#ifdef HAVE_REGISTER
2446        {"register.asp", "text/html", no_cache, NULL, do_ej, do_auth_reg, 1},
2447#endif
2448        {"WL_FilterTable*", "text/html", no_cache, NULL, do_filtertable,
2449         do_auth, 1},
2450#ifdef HAVE_FREERADIUS
2451        {"FreeRadiusCert*", "text/html", no_cache, NULL, do_radiuscert, do_auth,
2452         1},
2453        {"freeradius-certs/*", "application/octet-stream", no_cache, NULL,
2454         cert_file_out, do_auth, 0},
2455#endif
2456        // #endif
2457        // #ifdef HAVE_MADWIFI
2458        {"Wireless_WDS*", "text/html", no_cache, NULL, do_wds, do_auth, 1},
2459        {"WL_ActiveTable*", "text/html", no_cache, NULL, do_activetable,
2460         do_auth, 1},
2461        {"Wireless_Advanced*", "text/html", no_cache, NULL, do_wireless_adv,
2462         do_auth, 1},
2463        // #endif
2464        {"MyPage.asp*", "text/html", no_cache, NULL, do_mypage, do_auth, 1},
2465        {"**.asp", "text/html", no_cache, NULL, do_ej, do_auth, 1},
2466        {"**.JPG", "image/jpeg", no_cache, NULL, do_file, NULL, 0},
2467        // {"style.css", "text/css", NULL, NULL, do_style, NULL},
2468        {"common.js", "text/javascript", NULL, NULL, do_file, NULL, 0},
2469#ifdef HAVE_LANGUAGE
2470        {"lang_pack/language.js", "text/javascript", NULL, NULL, do_language,
2471         NULL, 0},
2472#endif
2473#ifdef HAVE_BUFFALO
2474        {"intatstart/lang_pack/language.js", "text/javascript", NULL, NULL, do_language, NULL, 0},
2475        {"intatstart/js/intatstart.js", "text/javascript", NULL, NULL, do_ej, NULL, 1},
2476        {"intatstart/js/mdetect.js", "text/javascript", NULL, NULL, do_ej, NULL, 1},
2477        {"vsp.html", "text/plain", no_cache, NULL, do_vsp_page, NULL, 1},
2478#endif
2479        {"SysInfo.htm*", "text/plain", no_cache, NULL, do_ej, do_auth, 1},
2480#ifdef HAVE_SKYTRON
2481        {"Info.htm*", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2482        {"Info.live.htm", "text/html", no_cache, NULL, do_ej, do_auth, 1},
2483        {"**.htm", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2484        {"**.html", "text/html", no_cache, NULL, do_ej, do_auth2, 1},
2485#else
2486        {"Info.htm*", "text/html", no_cache, NULL, do_ej, do_cauth, 1},
2487        {"Info.live.htm", "text/html", no_cache, NULL, do_ej, do_cauth, 1},
2488        {"**.htm", "text/html", no_cache, NULL, do_ej, NULL, 1},
2489        {"**.html", "text/html", no_cache, NULL, do_ej, NULL, 1},
2490
2491#endif
2492#ifdef HAVE_ROUTERSTYLE
2493        {"style/blue/style.css", "text/css", NULL, NULL, do_stylecss, NULL, 1},
2494        {"style/cyan/style.css", "text/css", NULL, NULL, do_stylecss, NULL, 1},
2495        {"style/elegant/style.css", "text/css", NULL, NULL, do_stylecss, NULL, 1},
2496        {"style/elegant/fresh.css", "text/css", NULL, NULL, do_ej, NULL, 1},
2497        {"style/elegant/fresh-dark.css", "text/css", NULL, NULL, do_ej, NULL, 1},
2498        {"style/green/style.css", "text/css", NULL, NULL, do_stylecss, NULL, 1},
2499        {"style/orange/style.css", "text/css", NULL, NULL, do_stylecss, NULL, 1},
2500        {"style/red/style.css", "text/css", NULL, NULL, do_stylecss, NULL, 1},
2501        {"style/yellow/style.css", "text/css", NULL, NULL, do_stylecss, NULL, 1},
2502        {"style/blue/style_ie.css", "text/css", NULL, NULL, do_stylecss_ie, NULL, 1},
2503        {"style/cyan/style_ie.css", "text/css", NULL, NULL, do_stylecss_ie, NULL, 1},
2504        {"style/elegant/style_ie.css", "text/css", NULL, NULL, do_stylecss_ie, NULL, 1},
2505        {"style/green/style_ie.css", "text/css", NULL, NULL, do_stylecss_ie, NULL, 1},
2506        {"style/orange/style_ie.css", "text/css", NULL, NULL, do_stylecss_ie, NULL, 1},
2507        {"style/red/style_ie.css", "text/css", NULL, NULL, do_stylecss_ie, NULL, 1},
2508        {"style/yellow/style_ie.css", "text/css", NULL, NULL, do_stylecss_ie, NULL, 1},
2509#endif
2510#ifdef HAVE_REGISTER
2511        {"style/logo.png", "image/png", NULL, NULL, do_trial_logo, NULL, 0},
2512#endif
2513        {"**.css", "text/css", NULL, NULL, do_file, NULL, 0},
2514        {"**.svg", "image/svg+xml", NULL, NULL, do_file, do_auth, 0},
2515        {"**.gif", "image/gif", NULL, NULL, do_file, NULL, 0},
2516        {"**.png", "image/png", NULL, NULL, do_file, NULL, 0},
2517        {"**.jpg", "image/jpeg", NULL, NULL, do_file, NULL, 0},
2518        {"**.ico", "image/x-icon", NULL, NULL, do_file, NULL, 0},
2519        {"**.js", "text/javascript", NULL, NULL, do_ej, NULL, 1},
2520        {"**.swf", "application/x-shockwave-flash", NULL, NULL, do_file, NULL,
2521         0},
2522        {"**.pdf", "application/pdf", NULL, NULL, do_file, NULL, 0},
2523        {"**.mp4", "video/mp4", NULL, NULL, do_file, NULL, 0},
2524        {"**.mp3", "audio/mpeg3", NULL, NULL, do_file, NULL, 0},
2525        {"**.mpg", "video/mpeg", NULL, NULL, do_file, NULL, 0},
2526        {"**.avi", "video/x-msvideo", NULL, NULL, do_file, NULL, 0},
2527        {"**.wma", "audio/x-ms-wma", NULL, NULL, do_file, NULL, 0},
2528        {"**.wmv", "video/x-ms-wmv", NULL, NULL, do_file, NULL, 0},
2529        {"**.flv", "video/x-flv", NULL, NULL, do_file, NULL, 0},
2530
2531#ifdef HAVE_PRIVOXY
2532        {"wpad.dat", "application/x-ns-proxy-autoconfig", no_cache, NULL, do_wpad, NULL, 0},
2533#endif
2534#ifdef HAVE_ATH9K
2535        {"spectral_scan.json", "application/json", no_cache, NULL, do_spectral_scan, do_auth, 1},
2536#endif
2537#ifdef HAVE_SKYTRON
2538        {"applyuser.cgi*", "text/html", no_cache, do_apply_post, do_apply_cgi,
2539         do_auth2, 1},
2540#elif HAVE_DDLAN
2541        {"applyuser.cgi*", "text/html", no_cache, do_apply_post, do_apply_cgi,
2542         NULL, 1},
2543#else
2544        {"applyuser.cgi*", "text/html", no_cache, do_apply_post, do_apply_cgi,
2545         do_auth, 1},
2546#endif
2547        {"fetchif.cgi*", "text/html", no_cache, NULL, do_fetchif, do_auth, 1},
2548#ifdef HAVE_DDLAN
2549        {"apply.cgi*", "text/html", no_cache, do_apply_post, do_apply_cgi, NULL,
2550         1},
2551        {"upgrade.cgi*", "text/html", no_cache, do_upgrade_post, do_upgrade_cgi,
2552         NULL, 1},
2553#else
2554        {"apply.cgi*", "text/html", no_cache, do_apply_post, do_apply_cgi,
2555         do_auth, 1},
2556        {"upgrade.cgi*", "text/html", no_cache, do_upgrade_post, do_upgrade_cgi,
2557         do_auth, 1},
2558#endif
2559#ifdef HAVE_BUFFALO
2560        {"olupgrade.cgi*", "text/html", no_cache, do_olupgrade_post,
2561         do_upgrade_cgi,
2562         do_auth, 1},
2563#endif
2564        // {"Gozila.cgi*", "text/html", no_cache, NULL, do_setup_wizard,
2565        // do_auth}, // for setup wizard
2566        /*
2567         * { "**.cfg", "application/octet-stream", no_cache, NULL, do_backup,
2568         * do_auth },
2569         */
2570#ifdef HAVE_DDLAN
2571        {"restore.cgi**", "text/html", no_cache, do_upgrade_post,
2572         do_upgrade_cgi,
2573         NULL, 1},
2574#else
2575        {"restore.cgi**", "text/html", no_cache, do_upgrade_post,
2576         do_upgrade_cgi,
2577         do_auth, 1},
2578#endif
2579        {"test.bin**", "application/octet-stream", no_cache, NULL, do_file,
2580         do_auth, 0},
2581
2582        {"bigfile.bin*", "application/octet-stream", no_cache, NULL,
2583         do_bigfile, do_auth, 0},
2584
2585#ifdef HAVE_DDLAN
2586        {"nvrambak.bin*", "application/octet-stream", no_cache, NULL,
2587         nv_file_out, do_auth2, 0},
2588
2589        {"nvrambak**.bin*", "application/octet-stream", no_cache, NULL,
2590         nv_file_out,
2591         do_auth2, 0},
2592        {"nvram.cgi*", "text/html", no_cache, nv_file_in, sr_config_cgi, NULL,
2593         1},
2594#else
2595        {"nvrambak.bin*", "application/octet-stream", no_cache, NULL,
2596         nv_file_out, do_auth, 0},
2597        {"nvrambak**.bin*", "application/octet-stream", no_cache, NULL,
2598         nv_file_out,
2599         do_auth, 0},
2600        {"nvram.cgi*", "text/html", no_cache, nv_file_in, sr_config_cgi,
2601         do_auth,
2602         1},
2603#endif
2604#if !defined(HAVE_X86) && !defined(HAVE_MAGICBOX)
2605        {"backup/cfe.bin", "application/octet-stream", no_cache, NULL,
2606         do_cfebackup,
2607         do_auth, 0},
2608#endif
2609#ifdef HAVE_STATUS_SYSLOG
2610        {"syslog.cgi*", "text/html", no_cache, NULL, do_syslog, do_auth, 1},
2611#endif
2612        {"ttgraph.cgi*", "text/html", no_cache, NULL, do_ttgraph, do_auth, 1},
2613        {"traffdata.bak*", "text/html", no_cache, NULL, ttraff_backup,
2614         do_auth, 0},
2615        {"tadmin.cgi*", "text/html", no_cache, td_file_in, td_config_cgi,
2616         do_auth, 1},
2617        {"*", "application/octet-stream", no_cache, NULL, do_file, do_auth, 1},
2618        // for ddm
2619        {NULL, NULL, NULL, NULL, NULL, NULL, 0}
2620};
2621
2622/*
2623 * Format: type = SET : " " => "&nbsp;" , ":" => "&semi;" type = GET :
2624 * "&nbsp;" => " " , "&semi;" => ":" Example: name1 = test 123:abc
2625 * filter_name("name1", new_name, SET); new_name="test&nbsp;123&semi;abc"
2626 * name2 = test&nbsp;123&semi;abc filter_name("name2", new_name, GET);
2627 * new_name="test 123:abc"
2628 */
2629int httpd_filter_name(char *old_name, char *new_name, size_t size, int type)
2630{
2631        int i, j, match;
2632
2633        cprintf("httpd_filter_name\n");
2634
2635        struct pattern {
2636                char ch;
2637                char *string;
2638        };
2639
2640        struct pattern patterns[] = {
2641                {' ', "&nbsp;"},
2642                {':', "&semi;"},
2643                {'<', "&lt;"},
2644                {'>', "&gt;"},
2645        };
2646
2647        struct pattern *v;
2648
2649        strcpy(new_name, "");
2650
2651        switch (type) {
2652        case SET:
2653                for (i = 0; *(old_name + i); i++) {
2654                        match = 0;
2655                        for (v = patterns; v < &patterns[STRUCT_LEN(patterns)]; v++) {
2656                                if (*(old_name + i) == v->ch) {
2657                                        if (strlen(new_name) + strlen(v->string) > size) {      // avoid overflow
2658                                                cprintf("%s(): overflow\n", __FUNCTION__);
2659                                                new_name[strlen(new_name)] = '\0';
2660                                                return 1;
2661                                        }
2662                                        sprintf(new_name + strlen(new_name), "%s", v->string);
2663                                        match = 1;
2664                                        break;
2665                                }
2666                        }
2667                        if (!match) {
2668                                if (strlen(new_name) + 1 > size) {
2669                                        cprintf("%s(): overflow\n", __FUNCTION__);      // avoid
2670                                        // overflow
2671                                        new_name[strlen(new_name)] = '\0';
2672                                        return 1;
2673                                }
2674                                sprintf(new_name + strlen(new_name), "%c", *(old_name + i));
2675                        }
2676                }
2677
2678                break;
2679        case GET:
2680                for (i = 0, j = 0; *(old_name + j); j++) {
2681                        match = 0;
2682                        for (v = patterns; v < &patterns[STRUCT_LEN(patterns)]; v++) {
2683                                if (!memcmp(old_name + j, v->string, strlen(v->string))) {
2684                                        *(new_name + i) = v->ch;
2685                                        j = j + strlen(v->string) - 1;
2686                                        match = 1;
2687                                        break;
2688                                }
2689                        }
2690                        if (!match)
2691                                *(new_name + i) = *(old_name + j);
2692
2693                        i++;
2694                }
2695                *(new_name + i) = '\0';
2696                break;
2697        default:
2698                cprintf("%s():Invalid type!\n", __FUNCTION__);
2699                break;
2700        }
2701        // cprintf("%s():new_name=[%s]\n", __FUNCTION__, new_name);
2702
2703        return 1;
2704}
2705
2706#ifdef HAVE_BUFFALO
2707void do_vsp_page(char *method, struct mime_handler *handler, char *url, webs_t stream, char *query)
2708{
2709/*
2710#ifdef HAVE_MADWIFI
2711        char *ifname = "ath0";
2712#else
2713        char *ifname = "wl0";
2714#endif
2715
2716        char *authmode = nvram_nget("%s_security_mode", ifname);
2717        char *encrypt = nvram_nget("%s_crypto", ifname);
2718        char *wpakey = nvram_nget("%s_wpa_psk ", ifname);
2719
2720        if (!strcmp(encrypt, "tkip")) {
2721                encrypt = "TKIP";
2722        } else if (!strcmp(authmode, "aes")) {
2723                encrypt = "AES";
2724        } else if (!strcmp(authmode, "tkip+aes")) {
2725                encrypt = "TKIP-AES-MIX";
2726        } else {
2727                encrypt = "";
2728        }
2729
2730        if (!strcmp(authmode, "disabled")) {
2731                authmode = "NONE";
2732                encrypt = "";
2733                wpakey = "";
2734        } else if (!strcmp(authmode, "wep")) {
2735                authmode = "WEP";
2736                encrypt = "";
2737                wpakey = "";
2738        } else if (!strcmp(authmode, "radius")
2739                   || !strcmp(authmode, "wpa")
2740                   || !strcmp(authmode, "wpa2")
2741                   || !strcmp(authmode, "wpa wpa2")) {
2742                authmode = "RADIUS";
2743                encrypt = "";
2744                wpakey = "";
2745        } else if (!strcmp(authmode, "8021X")) {
2746                authmode = "802.1X";
2747                encrypt = "";
2748                wpakey = "";
2749        } else if (!strcmp(authmode, "psk")) {
2750                authmode = "WPA";
2751        } else if (!strcmp(authmode, "psk2")) {
2752                authmode = "WPA2";
2753        } else if (!strcmp(authmode, "psk psk2")) {
2754                authmode = "WPA-WPA2-MIX";
2755        } else {
2756                authmode = "UNKNOWN";
2757                encrypt = "";
2758                wpakey = "";
2759        }
2760*/
2761        websWrite(stream, "<html>\n");
2762        websWrite(stream, "<head>\n");
2763        websWrite(stream, "<title>VSP</title>\n");
2764        websWrite(stream, "</head>\n");
2765        websWrite(stream, "<body>\n");
2766        websWrite(stream, "<pre>\n");
2767
2768        websWrite(stream, "DEVICE_VSP_VERSION=0.1\n");
2769        websWrite(stream, "DEVICE_VENDOR=BUFFALO INC.\n");
2770        websWrite(stream, "DEVICE_MODEL=%s DDWRT\n", nvram_safe_get("DD_BOARD"));
2771        websWrite(stream, "DEVICE_FIRMWARE_VERSION=1.00\n");
2772        char *reg = getUEnv("region");
2773        if (!reg)
2774                reg = "US";
2775        websWrite(stream, "DEVICE_REGION=%s\n", reg);
2776        websWrite(stream, "WIRELESS_DEVICE_NUMBER=1\n");
2777//      websWrite(stream, "WIRELESS_1_PRESET_AUTHMODE=%s\n", authmode);
2778//      websWrite(stream, "WIRELESS_1_PRESET_ENCRYPT=%s\n", encrypt);
2779//      websWrite(stream, "WIRELESS_1_PRESET_ENCRYPT_KEY=%s\n", wpakey);
2780        websWrite(stream, "DEVICE_URL_GET=/vsp.html\n");
2781        websWrite(stream, "DEVICE_URL_SET=/vsp.html\n");
2782
2783        websWrite(stream, "</pre>\n");
2784        websWrite(stream, "</body>\n");
2785        websWrite(stream, "</html>\n");
2786}
2787#endif
Note: See TracBrowser for help on using the repository browser.