Updates to Tomato RAF including NGINX && PHP
[tomato.git] / release / src / router / httpd / misc.c
blobf3c87f64fe0e559267f6f32524f9dc31fe4c1172
1 /*
3 Tomato Firmware
4 Copyright (C) 2006-2009 Jonathan Zarate
6 */
8 #include "tomato.h"
10 #include <ctype.h>
11 #include <sys/sysinfo.h>
12 #include <sys/stat.h>
13 #include <sys/ioctl.h>
14 #include <net/if.h>
15 #include <fcntl.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include <sys/types.h>
20 #include <dirent.h>
21 #include <time.h>
22 #include <sys/statfs.h>
23 #include <netdb.h>
24 #include <net/route.h>
26 #ifdef TCONFIG_IPV6
27 #include <ifaddrs.h>
28 #endif
30 #include <wlioctl.h>
31 #include <wlutils.h>
33 // to javascript-safe string
34 char *js_string(const char *s)
36 unsigned char c;
37 char *buffer;
38 char *b;
40 if ((buffer = malloc((strlen(s) * 4) + 1)) != NULL) {
41 b = buffer;
42 while ((c = *s++) != 0) {
43 if ((c == '"') || (c == '\'') || (c == '\\') || (!isprint(c))) {
44 b += sprintf(b, "\\x%02x", c);
46 else {
47 *b++ = c;
50 *b = 0;
52 return buffer;
55 // to html-safe string
56 char *html_string(const char *s)
58 unsigned char c;
59 char *buffer;
60 char *b;
62 if ((buffer = malloc((strlen(s) * 6) + 1)) != NULL) {
63 b = buffer;
64 while ((c = *s++) != 0) {
65 if ((c == '&') || (c == '<') || (c == '>') || (c == '"') || (c == '\'') || (!isprint(c))) {
66 b += sprintf(b, "&#%d;", c);
68 else {
69 *b++ = c;
72 *b = 0;
74 return buffer;
77 // removes \r
78 char *unix_string(const char *s)
80 char *buffer;
81 char *b;
82 char c;
84 if ((buffer = malloc(strlen(s) + 1)) != NULL) {
85 b = buffer;
86 while ((c = *s++) != 0)
87 if (c != '\r') *b++ = c;
88 *b = 0;
90 return buffer;
93 // # days, ##:##:##
94 char *reltime(char *buf, time_t t)
96 int days;
97 int m;
99 if (t < 0) t = 0;
100 days = t / 86400;
101 m = t / 60;
102 if (days == 0) {
103 sprintf(buf, "%02d:%02d:%02d", ((m / 60) % 24), (m % 60), (int)(t % 60));
104 } else {
105 sprintf(buf, "%d day%s, %02d:%02d:%02d", days, ((days==1) ? "" : "s"), ((m / 60) % 24), (m % 60), (int)(t % 60));
107 return buf;
110 int get_client_info(char *mac, char *ifname)
112 FILE *f;
113 char s[256];
114 #ifdef TCONFIG_IPV6
115 char ip[INET6_ADDRSTRLEN];
116 #else
117 char ip[INET_ADDRSTRLEN];
118 #endif
121 # ip neigh show fe80:0:0::201:02ff:fe03:0405
122 fe80::201:2ff:fe3:405 dev br0 lladdr 00:01:02:03:04:05 REACHABLE
124 if (clientsai.ss_family == AF_INET) {
125 inet_ntop(clientsai.ss_family, &(((struct sockaddr_in*)&clientsai)->sin_addr), ip, sizeof(ip));
126 sprintf(s, "ip neigh show %s", ip);
128 #ifdef TCONFIG_IPV6
129 else if (clientsai.ss_family == AF_INET6) {
130 inet_ntop(clientsai.ss_family, &(((struct sockaddr_in6*)&clientsai)->sin6_addr), ip, sizeof(ip));
131 if (IN6_IS_ADDR_V4MAPPED( &(((struct sockaddr_in6*)&clientsai)->sin6_addr) ))
132 sprintf(s, "ip neigh show %s", ip + 7); // chop off the ::ffff: to get the ipv4 bit
133 else
134 sprintf(s, "ip neigh show %s", ip);
136 #endif
138 if ((f = popen(s, "r")) != NULL) {
139 while (fgets(s, sizeof(s), f)) {
140 if (sscanf(s, "%*s dev %16s lladdr %17s %*s", ifname, mac) == 2) {
141 pclose(f);
142 return 1;
145 pclose(f);
147 return 0;
151 // <% lanip(mode); %>
152 // <mode>
153 // 1 return first 3 octets (192.168.1)
154 // 2 return last octet (1)
155 // else return full (192.168.1.1)
157 void asp_lanip(int argc, char **argv)
159 char *nv, *p;
160 char s[64];
161 char mode;
163 mode = argc ? *argv[0] : 0;
165 if ((nv = nvram_get("lan_ipaddr")) != NULL) {
166 strcpy(s, nv);
167 if ((p = strrchr(s, '.')) != NULL) {
168 *p = 0;
169 web_puts((mode == '1') ? s : (mode == '2') ? (p + 1) : nv);
174 void asp_lipp(int argc, char **argv)
176 char *one = "1";
177 asp_lanip(1, &one);
180 // <% psup(process); %>
181 // returns 1 if process is running
183 void asp_psup(int argc, char **argv)
185 if (argc == 1) web_printf("%d", pidof(argv[0]) > 0);
188 void wo_vpn_status(char *url)
190 #ifdef TCONFIG_OPENVPN
191 char buf[256];
192 char *type;
193 char *str;
194 int num;
195 FILE *fp;
197 type = 0;
198 if ( (str = webcgi_get("server")) )
199 type = "server";
200 else if ( (str = webcgi_get("client")) )
201 type = "client";
203 num = str? atoi(str): 0;
204 if ( type && num > 0 )
206 // Trigger OpenVPN to update the status file
207 snprintf(&buf[0], sizeof(buf), "vpn%s%d", type, num);
208 killall(&buf[0], SIGUSR2);
210 // Give it a chance to update the file
211 sleep(1);
213 // Read the status file and repeat it verbatim to the caller
214 snprintf(&buf[0], sizeof(buf), "/etc/openvpn/%s%d/status", type, num);
215 fp = fopen(&buf[0], "r");
216 if( fp != NULL )
218 while (fgets(&buf[0], sizeof(buf), fp) != NULL)
219 web_puts(&buf[0]);
220 fclose(fp);
223 #endif
227 # cat /proc/meminfo
228 total: used: free: shared: buffers: cached:
229 Mem: 14872576 12877824 1994752 0 1236992 4837376
230 Swap: 0 0 0
231 MemTotal: 14524 kB
232 MemFree: 1948 kB
233 MemShared: 0 kB
234 Buffers: 1208 kB
235 Cached: 4724 kB
236 SwapCached: 0 kB
237 Active: 4364 kB
238 Inactive: 2952 kB
239 HighTotal: 0 kB
240 HighFree: 0 kB
241 LowTotal: 14524 kB
242 LowFree: 1948 kB
243 SwapTotal: 0 kB
244 SwapFree: 0 kB
248 typedef struct {
249 unsigned long total;
250 unsigned long free;
251 unsigned long shared;
252 unsigned long buffers;
253 unsigned long cached;
254 unsigned long swaptotal;
255 unsigned long swapfree;
256 unsigned long maxfreeram;
257 } meminfo_t;
259 static int get_memory(meminfo_t *m)
261 FILE *f;
262 char s[128];
263 int ok = 0;
265 memset(m, 0, sizeof(*m));
266 if ((f = fopen("/proc/meminfo", "r")) != NULL) {
267 while (fgets(s, sizeof(s), f)) {
268 #ifdef LINUX26
269 if (strncmp(s, "MemTotal:", 9) == 0) {
270 m->total = strtoul(s + 12, NULL, 10) * 1024;
271 ++ok;
273 else if (strncmp(s, "MemFree:", 8) == 0) {
274 m->free = strtoul(s + 12, NULL, 10) * 1024;
275 ++ok;
277 else if (strncmp(s, "Buffers:", 8) == 0) {
278 m->buffers = strtoul(s + 12, NULL, 10) * 1024;
279 ++ok;
281 else if (strncmp(s, "Cached:", 7) == 0) {
282 m->cached = strtoul(s + 12, NULL, 10) * 1024;
283 ++ok;
285 #else
286 if (strncmp(s, "Mem:", 4) == 0) {
287 if (sscanf(s + 6, "%ld %*d %ld %ld %ld %ld", &m->total, &m->free, &m->shared, &m->buffers, &m->cached) == 5)
288 ++ok;
290 #endif
291 else if (strncmp(s, "SwapTotal:", 10) == 0) {
292 m->swaptotal = strtoul(s + 12, NULL, 10) * 1024;
293 ++ok;
295 else if (strncmp(s, "SwapFree:", 9) == 0) {
296 m->swapfree = strtoul(s + 11, NULL, 10) * 1024;
297 ++ok;
298 #ifndef LINUX26
299 break;
300 #endif
303 fclose(f);
305 if (ok == 0) {
306 return 0;
308 m->maxfreeram = m->free;
309 if (nvram_match("t_cafree", "1")) m->maxfreeram += (m->cached + m->buffers);
310 return 1;
313 #ifdef TCONFIG_IPV6
314 #define IP6ADDR_MAX_CNT 3 // wan, lan, lan-ll
315 static void print_ipv6_addrs(void)
317 char buf[INET6_ADDRSTRLEN];
318 int found;
319 char *addrtype;
320 struct ifaddrs *ifap, *ifa;
321 struct sockaddr_in6 *s6;
323 if (!ipv6_enabled() || (getifaddrs(&ifap) != 0))
324 return;
326 found = 0;
327 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
328 if ((ifa->ifa_addr == NULL) || (ifa->ifa_addr->sa_family != AF_INET6))
329 continue;
331 s6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
333 if (strncmp(ifa->ifa_name, nvram_safe_get("lan_ifname"), IFNAMSIZ) == 0) {
334 if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr))
335 addrtype = "lan_ll";
336 else
337 addrtype = "lan";
339 else if (strncmp(ifa->ifa_name, get_wan6face(), IFNAMSIZ) == 0) {
340 if (!IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr))
341 addrtype = "wan";
342 else
343 continue;
345 else
346 continue;
348 if (inet_ntop(ifa->ifa_addr->sa_family, &(s6->sin6_addr), buf, sizeof(buf)) != NULL) {
349 web_printf("\tip6_%s: '%s',\n",
350 addrtype, buf);
351 if (++found >= IP6ADDR_MAX_CNT)
352 break;
355 freeifaddrs(ifap);
359 void asp_calc6rdlocalprefix(int argc, char **argv)
361 struct in6_addr prefix_addr, local_prefix_addr;
362 int prefix_len = 0, relay_prefix_len = 0, local_prefix_len = 0;
363 struct in_addr wanip_addr;
364 char local_prefix[INET6_ADDRSTRLEN];
365 char s[128];
367 if (argc != 3) return;
369 inet_pton(AF_INET6, argv[0], &prefix_addr);
370 prefix_len = atoi(argv[1]);
371 relay_prefix_len = atoi(argv[2]);
372 inet_pton(AF_INET, get_wanip(), &wanip_addr);
374 if (calc_6rd_local_prefix(&prefix_addr, prefix_len, relay_prefix_len,
375 &wanip_addr, &local_prefix_addr, &local_prefix_len) &&
376 inet_ntop(AF_INET6, &local_prefix_addr, local_prefix, sizeof(local_prefix)) != NULL) {
377 sprintf(s, "\nlocal_prefix = '%s/%d';\n", local_prefix, local_prefix_len);
378 web_puts(s);
381 #endif
384 int get_flashsize()
387 # cat /proc/mtd
388 dev: size erasesize name
389 mtd0: 00020000 00010000 "pmon"
390 mtd1: 007d0000 00010000 "linux"
392 FILE *f;
393 char s[512];
394 unsigned int size;
395 char partname[16];
396 int found = 0;
398 if ((f = fopen("/proc/mtd", "r")) != NULL) {
399 while (fgets(s, sizeof(s), f)) {
400 if (sscanf(s, "%*s %X %*s %16s", &size, partname) != 2) continue;
401 if (strcmp(partname, "\"linux\"") == 0) {
402 found = 1;
403 break;
406 fclose(f);
408 if (found) {
409 if (nvram_match("boardtype", "0x052b") && nvram_match("boardrev", "02")) return 128; //Netgear 3500L v2 has 128MB NAND flash but linux partition has only 32MB
410 else if ((size > 0x2000000) && (size < 0x4000000)) return 64;
411 else if ((size > 0x1000000) && (size < 0x2000000)) return 32;
412 else if ((size > 0x800000) && (size < 0x1000000)) return 16;
413 else if ((size > 0x400000) && (size < 0x800000)) return 8;
414 else if ((size > 0x200000) && (size < 0x400000)) return 4;
415 else if ((size > 0x100000) && (size < 0x200000)) return 2;
416 else return 1;
418 else {
419 return 0;
423 void asp_jiffies(int argc, char **argv)
425 char sa[64];
426 FILE *a;
427 char *e = NULL;
428 char *f= NULL;
430 const char procstat[] = "/proc/stat";
431 if ((a = fopen(procstat, "r")) != NULL) {
432 fgets(sa, sizeof(sa), a);
434 e = sa;
436 if ((e = strchr(sa, ' ')) != NULL) e = e + 2;
438 if ((f = strchr(sa, 10)) != NULL) *f = 0;
440 web_printf("\njiffies = [ '");
441 web_printf("%s", e);
442 web_puts("' ];\n");
443 fclose(a);
447 void asp_etherstates(int argc, char **argv)
449 FILE *f;
450 char s[32], *a, b[16];
451 unsigned n;
453 if ((nvram_get_int("lan_state") & 1)) {
455 web_puts("\netherstates = {");
457 system("/usr/sbin/ethstate");
458 n = 0;
459 if ((f = fopen("/tmp/ethernet.state", "r")) != NULL) {
460 while (fgets(s, sizeof(s), f)) {
461 if (sscanf(s, "Port 0: %s", b) == 1) a="port0";
462 else if (sscanf(s, "Port 1: %s", b) == 1) a="port1";
463 else if (sscanf(s, "Port 2: %s", b) == 1) a="port2";
464 else if (sscanf(s, "Port 3: %s", b) == 1) a="port3";
465 else if (sscanf(s, "Port 4: %s", b) == 1) a="port4";
466 else continue;
468 web_printf("%s\t%s: '%s'", n ? ",\n" : "", a, b);
469 n++;
471 fclose(f);
473 web_puts("\n};\n");
474 } else {
475 web_puts("\netherstates = {\tport0: 'disabled'\n};\n");
479 void asp_sysinfo(int argc, char **argv)
481 struct sysinfo si;
482 char s[64];
483 meminfo_t mem;
485 char sa[64];
486 FILE *a;
487 char *e = NULL;
488 char *f= NULL;
489 const char procstat[] = "/proc/stat";
491 char system_type[64];
492 char cpu_model[64];
493 char bogomips[8];
494 char cpuclk[8];
496 get_cpuinfo(system_type, cpu_model, bogomips, cpuclk);
498 web_puts("\nsysinfo = {\n");
500 #ifdef TCONFIG_IPV6
501 print_ipv6_addrs();
502 #endif
503 sysinfo(&si);
504 get_memory(&mem);
505 web_printf(
506 "\tuptime: %ld,\n"
507 "\tuptime_s: '%s',\n"
508 "\tloads: [%ld, %ld, %ld],\n"
509 "\ttotalram: %ld,\n"
510 "\tfreeram: %ld,\n"
511 "\tshareram: %ld,\n"
512 "\tbufferram: %ld,\n"
513 "\tcached: %ld,\n"
514 "\ttotalswap: %ld,\n"
515 "\tfreeswap: %ld,\n"
516 "\ttotalfreeram: %ld,\n"
517 "\tprocs: %d,\n"
518 "\tflashsize: %d,\n"
519 "\tsystemtype: '%s',\n"
520 "\tcpumodel: '%s',\n"
521 "\tbogomips: '%s',\n"
522 "\tcpuclk: '%s'",
523 si.uptime,
524 reltime(s, si.uptime),
525 si.loads[0], si.loads[1], si.loads[2],
526 mem.total, mem.free,
527 mem.shared, mem.buffers, mem.cached,
528 mem.swaptotal, mem.swapfree,
529 mem.maxfreeram,
530 si.procs,
531 get_flashsize(),
532 system_type,
533 cpu_model,
534 bogomips,
535 cpuclk);
537 if ((a = fopen(procstat, "r")) != NULL) {
538 fgets(sa, sizeof(sa), a);
539 e = sa;
540 if ((e = strchr(sa, ' ')) != NULL) e = e + 2;
541 if ((f = strchr(sa, 10)) != NULL) *f = 0;
542 web_printf(",\n\tjiffies: '");
543 web_printf("%s", e);
544 web_puts("'\n");
545 fclose(a);
546 } else {
547 web_puts("\n");
550 web_puts("};\n");
553 void asp_activeroutes(int argc, char **argv)
555 FILE *f;
556 char s[512];
557 char dev[17];
558 unsigned long dest;
559 unsigned long gateway;
560 unsigned long flags;
561 unsigned long mask;
562 unsigned metric;
563 struct in_addr ia;
564 char s_dest[16];
565 char s_gateway[16];
566 char s_mask[16];
567 int n;
569 web_puts("\nactiveroutes = [");
570 n = 0;
571 if ((f = fopen("/proc/net/route", "r")) != NULL) {
572 while (fgets(s, sizeof(s), f)) {
573 if (sscanf(s, "%16s%lx%lx%lx%*s%*s%u%lx", dev, &dest, &gateway, &flags, &metric, &mask) != 6) continue;
574 if ((flags & RTF_UP) == 0) continue;
575 if (dest != 0) {
576 ia.s_addr = dest;
577 strcpy(s_dest, inet_ntoa(ia));
579 else {
580 strcpy(s_dest, "default");
582 if (gateway != 0) {
583 ia.s_addr = gateway;
584 strcpy(s_gateway, inet_ntoa(ia));
586 else {
587 strcpy(s_gateway, "*");
589 ia.s_addr = mask;
590 strcpy(s_mask, inet_ntoa(ia));
591 web_printf("%s['%s','%s','%s','%s',%u]", n ? "," : "", dev, s_dest, s_gateway, s_mask, metric);
592 ++n;
594 fclose(f);
597 #ifdef TCONFIG_IPV6
598 int pxlen;
599 char addr6x[80];
600 struct sockaddr_in6 snaddr6;
601 char addr6[40], nhop6[40];
603 if ((ipv6_enabled()) &&
604 (f = fopen("/proc/net/ipv6_route", "r")) != NULL) {
605 while (fgets(s, sizeof(s), f)) {
606 if (sscanf(s, "%32s%x%*s%*s%32s%x%*s%*s%lx%s\n",
607 addr6x+14, &pxlen, addr6x+40+7, &metric, &flags, dev) != 6) continue;
609 if ((flags & RTF_UP) == 0) continue;
611 int i = 0;
612 char *p = addr6x+14;
613 do {
614 if (!*p) {
615 if (i == 40) { // nul terminator for 1st address?
616 addr6x[39] = 0; // Fixup... need 0 instead of ':'.
617 ++p; // Skip and continue.
618 continue;
620 goto OUT;
622 addr6x[i++] = *p++;
623 if (!((i+1) % 5)) {
624 addr6x[i++] = ':';
626 } while (i < 40+28+7);
628 inet_pton(AF_INET6, addr6x, (struct sockaddr *) &snaddr6.sin6_addr);
629 if (IN6_IS_ADDR_UNSPECIFIED(&snaddr6.sin6_addr))
630 strcpy(addr6, "default");
631 else
632 inet_ntop(AF_INET6, &snaddr6.sin6_addr, addr6, sizeof(addr6));
634 inet_pton(AF_INET6, addr6x + 40, (struct sockaddr *) &snaddr6.sin6_addr);
635 if (IN6_IS_ADDR_UNSPECIFIED(&snaddr6.sin6_addr))
636 strcpy(nhop6, "*");
637 else
638 inet_ntop(AF_INET6, &snaddr6.sin6_addr, nhop6, sizeof(nhop6));
640 web_printf("%s['%s','%s','%s','%d',%u]", n ? "," : "", dev, addr6, nhop6, pxlen, metric);
641 ++n;
643 OUT:
644 fclose(f);
646 #endif
648 web_puts("];\n");
651 void asp_cgi_get(int argc, char **argv)
653 const char *v;
654 int i;
656 for (i = 0; i < argc; ++i) {
657 v = webcgi_get(argv[i]);
658 if (v) web_puts(v);
662 void asp_time(int argc, char **argv)
664 time_t t;
665 char s[64];
667 t = time(NULL);
668 if (t < Y2K) {
669 web_puts("Not Available");
671 else {
672 strftime(s, sizeof(s), "%a, %d %b %Y %H:%M:%S %z", localtime(&t));
673 web_puts(s);
677 void asp_wanup(int argc, char **argv)
679 web_puts(check_wanup() ? "1" : "0");
682 void asp_wanstatus(int argc, char **argv)
684 const char *p;
686 if ((using_dhcpc()) && (f_exists("/var/lib/misc/dhcpc.renewing"))) {
687 p = "Renewing...";
689 else if (check_wanup()) {
690 p = "Connected";
692 else if (f_exists("/var/lib/misc/wan.connecting")) {
693 int proto = get_wan_proto();
695 p = "Connecting...";
697 if ((proto == WP_PPPOE || proto == WP_PPP3G) && f_exists("/tmp/ppp/log")) {
698 char s[256];
700 f_read_string("/tmp/ppp/log", s, sizeof(s));
702 if (strcmp(s, "PADO_TIMEOUT") == 0 || strcmp(s, "PADS_TIMEOUT") == 0) {
703 web_printf("Timed out%s", nvram_get_int("ppp_demand") == 0 ? ", Trying again...":"");
704 } else if (strcmp(s, "PAP_AUTH_FAIL") == 0 || strcmp(s, "CHAP_AUTH_FAIL") == 0) {
705 web_printf("Authentication failed%s", nvram_get_int("ppp_demand") == 0 ? ", Trying again...":"");
706 } else {
707 web_puts(p);
710 return;
715 else {
716 p = "Disconnected";
718 web_puts(p);
721 void asp_link_uptime(int argc, char **argv)
723 struct sysinfo si;
724 char buf[64];
725 long uptime;
727 buf[0] = '-';
728 buf[1] = 0;
729 if (check_wanup()) {
730 sysinfo(&si);
731 if (f_read("/var/lib/misc/wantime", &uptime, sizeof(uptime)) == sizeof(uptime)) {
732 reltime(buf, si.uptime - uptime);
735 web_puts(buf);
738 void asp_link_starttime(int argc, char **argv)
740 struct sysinfo si;
741 char buf[64];
742 long uptime;
744 buf[0] = 0;
746 if (!check_wanup() && f_exists("/var/lib/misc/wan.connecting")) {
747 sysinfo(&si);
748 if (f_read("/var/lib/misc/wan.connecting", &uptime, sizeof(uptime)) == sizeof(uptime)) {
749 reltime(buf, si.uptime - uptime);
752 web_puts(buf);
755 void asp_rrule(int argc, char **argv)
757 char s[32];
758 int i;
760 i = nvram_get_int("rruleN");
761 sprintf(s, "rrule%d", i);
762 web_puts("\nrrule = '");
763 web_putj(nvram_safe_get(s));
764 web_printf("';\nrruleN = %d;\n", i);
767 void asp_compmac(int argc, char **argv)
769 char mac[32];
770 char ifname[32];
772 if (get_client_info(mac, ifname)) {
773 web_puts(mac);
777 void asp_ident(int argc, char **argv)
779 web_puth(nvram_safe_get("router_name"));
782 void asp_statfs(int argc, char **argv)
784 struct statfs sf;
785 int mnt;
787 if (argc != 2) return;
789 // used for /cifs/, /jffs/... if it returns squashfs type, assume it's not mounted
790 if ((statfs(argv[0], &sf) != 0) || (sf.f_type == 0x73717368)) {
791 mnt = 0;
792 memset(&sf, 0, sizeof(sf));
793 #ifdef TCONFIG_JFFS2
794 // for jffs, try to get total size from mtd partition
795 if (strncmp(argv[1], "jffs", 4) == 0) {
796 int part;
798 if (mtd_getinfo(argv[1], &part, (int *)&sf.f_blocks)) {
799 sf.f_bsize = 1;
802 #endif
804 else {
805 mnt = 1;
808 web_printf(
809 "\n%s = {\n"
810 "\tmnt: %d,\n"
811 "\tsize: %llu,\n"
812 "\tfree: %llu\n"
813 "};\n",
814 argv[1], mnt,
815 ((uint64_t)sf.f_bsize * sf.f_blocks),
816 ((uint64_t)sf.f_bsize * sf.f_bfree));
819 void asp_notice(int argc, char **argv)
821 char s[256];
822 char buf[2048];
824 if (argc != 1) return;
825 snprintf(s, sizeof(s), "/var/notice/%s", argv[0]);
826 if (f_read_string(s, buf, sizeof(buf)) <= 0) return;
827 web_putj(buf);
830 void wo_wakeup(char *url)
832 char *mac;
833 char *p;
834 char *end;
836 if ((mac = webcgi_get("mac")) != NULL) {
837 end = mac + strlen(mac);
838 while (mac < end) {
839 while ((*mac == ' ') || (*mac == '\t') || (*mac == '\r') || (*mac == '\n')) ++mac;
840 if (*mac == 0) break;
842 p = mac;
843 while ((*p != 0) && (*p != ' ') && (*p != '\r') && (*p != '\n')) ++p;
844 *p = 0;
846 eval("ether-wake", "-b", "-i", nvram_safe_get("lan_ifname"), mac);
847 #ifdef TCONFIG_VLAN
848 if (strcmp(nvram_safe_get("lan1_ifname"), "") != 0)
849 eval("ether-wake", "-b", "-i", nvram_safe_get("lan1_ifname"), mac);
850 if (strcmp(nvram_safe_get("lan2_ifname"), "") != 0)
851 eval("ether-wake", "-b", "-i", nvram_safe_get("lan2_ifname"), mac);
852 if (strcmp(nvram_safe_get("lan3_ifname"), "") != 0)
853 eval("ether-wake", "-b", "-i", nvram_safe_get("lan3_ifname"), mac);
854 #endif
855 mac = p + 1;
858 common_redirect();
861 void asp_dns(int argc, char **argv)
863 char s[128];
864 int i;
865 const dns_list_t *dns;
867 dns = get_dns(); // static buffer
868 strcpy(s, "\ndns = [");
869 for (i = 0 ; i < dns->count; ++i) {
870 sprintf(s + strlen(s), "%s'%s:%u'", i ? "," : "", inet_ntoa(dns->dns[i].addr), dns->dns[i].port);
872 strcat(s, "];\n");
873 web_puts(s);
876 int resolve_addr(const char *ip, char *host)
878 struct addrinfo hints;
879 struct addrinfo *res;
880 int ret;
882 memset(&hints, 0, sizeof(hints));
883 hints.ai_family = AF_UNSPEC;
884 hints.ai_socktype = SOCK_STREAM;
886 ret = getaddrinfo(ip, NULL, &hints, &res);
887 if (ret == 0) {
888 ret = getnameinfo(res->ai_addr, res->ai_addrlen, host, NI_MAXHOST, NULL, 0, 0);
889 freeaddrinfo(res);
891 return ret;
894 void wo_resolve(char *url)
896 char *p;
897 char *ip;
898 char host[NI_MAXHOST];
899 char comma;
900 char *js;
902 comma = ' ';
903 web_puts("\nresolve_data = [\n");
904 if ((p = webcgi_get("ip")) != NULL) {
905 while ((ip = strsep(&p, ",")) != NULL) {
906 if (resolve_addr(ip, host) != 0) continue;
907 js = js_string(host);
908 web_printf("%c['%s','%s']", comma, ip, js);
909 free(js);
910 comma = ',';
913 web_puts("];\n");