4 Copyright (C) 2006-2008 Jonathan Zarate
11 #include <sys/sysinfo.h>
13 #include <sys/ioctl.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include <sys/types.h>
22 #include <sys/statfs.h>
24 #include <net/route.h>
27 //#include <sys/mount.h>
34 int wait_file_exists(const char *name
, int max
, int invert
)
37 if (f_exists(name
) ^ invert
) return 1;
43 // to javascript-safe string
44 char *js_string(const char *s
)
50 if ((buffer
= malloc((strlen(s
) * 4) + 1)) != NULL
) {
52 while ((c
= *s
++) != 0) {
53 if ((c
== '"') || (c
== '\'') || (c
== '\\') || (!isprint(c
))) {
54 b
+= sprintf(b
, "\\x%02x", c
);
65 // to html-safe string
66 char *html_string(const char *s
)
72 if ((buffer
= malloc((strlen(s
) * 6) + 1)) != NULL
) {
74 while ((c
= *s
++) != 0) {
75 if ((c
== '&') || (c
== '<') || (c
== '>') || (c
== '"') || (c
== '\'') || (!isprint(c
))) {
76 b
+= sprintf(b
, "&#%d;", c
);
88 char *unix_string(const char *s
)
94 if ((buffer
= malloc(strlen(s
) + 1)) != NULL
) {
96 while ((c
= *s
++) != 0)
97 if (c
!= '\r') *b
++ = c
;
104 char *reltime(char *buf
, time_t t
)
112 sprintf(buf
, "%d day%s, %02d:%02d:%02d", days
, ((days
==1) ? "" : "s"), ((m
/ 60) % 24), (m
% 60), (int)(t
% 60));
116 int get_client_info(char *mac
, char *ifname
)
124 IP address HW type Flags HW address Mask Device
125 192.168.0.1 0x1 0x2 00:01:02:03:04:05 * vlan1
126 192.168.1.5 0x1 0x2 00:05:06:07:08:09 * br0
129 if ((f
= fopen("/proc/net/arp", "r")) != NULL
) {
130 while (fgets(s
, sizeof(s
), f
)) {
131 if (sscanf(s
, "%15s %*s %*s %17s %*s %16s", ips
, mac
, ifname
) == 3) {
132 if (inet_addr(ips
) == clientsai
.sin_addr
.s_addr
) {
147 // <% lanip(mode); %>
149 // 1 return first 3 octets (192.168.1)
150 // 2 return last octet (1)
151 // else return full (192.168.1.1)
153 void asp_lanip(int argc
, char **argv
)
159 mode
= argc
? *argv
[0] : 0;
161 if ((nv
= nvram_get("lan_ipaddr")) != NULL
) {
163 if ((p
= strrchr(s
, '.')) != NULL
) {
165 web_puts((mode
== '1') ? s
: (mode
== '2') ? (p
+ 1) : nv
);
170 void asp_lipp(int argc
, char **argv
)
176 // <% psup(process); %>
177 // returns 1 if process is running
179 void asp_psup(int argc
, char **argv
)
181 if (argc
== 1) web_printf("%d", pidof(argv
[0]) > 0);
186 total: used: free: shared: buffers: cached:
187 Mem: 14872576 12877824 1994752 0 1236992 4837376
209 unsigned long shared
;
210 unsigned long buffers
;
211 unsigned long cached
;
212 unsigned long swaptotal
;
213 unsigned long swapfree
;
214 unsigned long maxfreeram
;
217 static int get_memory(meminfo_t
*m
)
223 if ((f
= fopen("/proc/meminfo", "r")) != NULL
) {
224 while (fgets(s
, sizeof(s
), f
)) {
225 if (strncmp(s
, "Mem:", 4) == 0) {
226 if (sscanf(s
+ 6, "%ld %*d %ld %ld %ld %ld", &m
->total
, &m
->free
, &m
->shared
, &m
->buffers
, &m
->cached
) == 5)
229 else if (strncmp(s
, "SwapTotal:", 10) == 0) {
230 m
->swaptotal
= strtoul(s
+ 12, NULL
, 10) * 1024;
233 else if (strncmp(s
, "SwapFree:", 9) == 0) {
234 m
->swapfree
= strtoul(s
+ 11, NULL
, 10) * 1024;
242 memset(m
, 0, sizeof(*m
));
245 m
->maxfreeram
= m
->free
;
246 if (nvram_match("t_cafree", "1")) m
->maxfreeram
+= m
->cached
;
250 void asp_sysinfo(int argc
, char **argv
)
256 web_puts("\nsysinfo = {\n");
261 "\tuptime_s: '%s',\n"
262 "\tloads: [%ld, %ld, %ld],\n"
266 "\tbufferram: %ld,\n"
268 "\ttotalswap: %ld,\n"
270 "\ttotalfreeram: %ld,\n"
273 reltime(s
, si
.uptime
),
274 si
.loads
[0], si
.loads
[1], si
.loads
[2],
276 mem
.shared
, mem
.buffers
, mem
.cached
,
277 mem
.swaptotal
, mem
.swapfree
,
283 void asp_activeroutes(int argc
, char **argv
)
289 unsigned long gateway
;
299 web_puts("\nactiveroutes = [");
301 if ((f
= fopen("/proc/net/route", "r")) != NULL
) {
302 while (fgets(s
, sizeof(s
), f
)) {
303 if (sscanf(s
, "%16s%lx%lx%lx%*s%*s%u%lx", dev
, &dest
, &gateway
, &flags
, &metric
, &mask
) != 6) continue;
304 if ((flags
& RTF_UP
) == 0) continue;
307 strcpy(s_dest
, inet_ntoa(ia
));
310 strcpy(s_dest
, "default");
314 strcpy(s_gateway
, inet_ntoa(ia
));
317 strcpy(s_gateway
, "*");
320 strcpy(s_mask
, inet_ntoa(ia
));
321 web_printf("%s['%s','%s','%s','%s',%u]", n
? "," : "", dev
, s_dest
, s_gateway
, s_mask
, metric
);
329 void asp_cgi_get(int argc
, char **argv
)
334 for (i
= 0; i
< argc
; ++i
) {
335 v
= webcgi_get(argv
[i
]);
340 void asp_time(int argc
, char **argv
)
347 web_puts("Not Available");
350 strftime(s
, sizeof(s
), "%a, %d %b %Y %H:%M:%S %z", localtime(&t
));
355 void asp_wanup(int argc
, char **argv
)
357 web_puts(check_wanup() ? "1" : "0");
360 void asp_wanstatus(int argc
, char **argv
)
364 if ((using_dhcpc()) && (f_exists("/var/lib/misc/dhcpc.renewing"))) {
367 else if (check_wanup()) {
370 else if (f_exists("/var/lib/misc/wan.connecting")) {
379 void asp_link_uptime(int argc
, char **argv
)
389 if (f_read("/var/lib/misc/wantime", &uptime
, sizeof(uptime
)) == sizeof(uptime
)) {
390 reltime(buf
, si
.uptime
- uptime
);
396 void asp_bandwidth(int argc
, char **argv
)
401 if ((nvram_match("rstats_enable", "1")) && (argc
== 1)) {
402 if (strcmp(argv
[0], "speed") == 0) {
404 name
= "/var/spool/rstats-speed.js";
408 name
= "/var/spool/rstats-history.js";
411 killall("rstats", sig
);
412 wait_file_exists(name
, 5, 0);
418 void asp_rrule(int argc
, char **argv
)
423 i
= nvram_get_int("rruleN");
424 sprintf(s
, "rrule%d", i
);
425 web_puts("\nrrule = '");
426 web_putj(nvram_safe_get(s
));
427 web_printf("';\nrruleN = %d;\n", i
);
430 void asp_compmac(int argc
, char **argv
)
435 if (get_client_info(mac
, ifname
)) {
440 void asp_ident(int argc
, char **argv
)
442 web_puth(nvram_safe_get("router_name"));
445 void asp_statfs(int argc
, char **argv
)
449 if (argc
!= 2) return;
451 // used for /cifs/, /jffs/... if it returns squashfs type, assume it's not mounted
452 if ((statfs(argv
[0], &sf
) != 0) || (sf
.f_type
== 0x73717368))
453 memset(&sf
, 0, sizeof(sf
));
461 ((uint64_t)sf
.f_bsize
* sf
.f_blocks
),
462 ((uint64_t)sf
.f_bsize
* sf
.f_bfree
));
465 void asp_notice(int argc
, char **argv
)
470 if (argc
!= 1) return;
471 snprintf(s
, sizeof(s
), "/var/notice/%s", argv
[0]);
472 if (f_read_string(s
, buf
, sizeof(buf
)) <= 0) return;
476 void wo_wakeup(char *url
)
482 if ((mac
= webcgi_get("mac")) != NULL
) {
483 end
= mac
+ strlen(mac
);
485 while ((*mac
== ' ') || (*mac
== '\t') || (*mac
== '\r') || (*mac
== '\n')) ++mac
;
486 if (*mac
== 0) break;
489 while ((*p
!= 0) && (*p
!= ' ') && (*p
!= '\r') && (*p
!= '\n')) ++p
;
492 eval("ether-wake", "-i", nvram_safe_get("lan_ifname"), mac
);
499 void asp_dns(int argc
, char **argv
)
503 const dns_list_t
*dns
;
505 dns
= get_dns(); // static buffer
506 strcpy(s
, "\ndns = [");
507 for (i
= 0 ; i
< dns
->count
; ++i
) {
508 sprintf(s
+ strlen(s
), "%s'%s'", i
? "," : "", inet_ntoa(dns
->dns
[i
]));
514 void wo_resolve(char *url
)
524 web_puts("\nresolve_data = [\n");
525 if ((p
= webcgi_get("ip")) != NULL
) {
526 while ((ip
= strsep(&p
, ",")) != NULL
) {
527 ia
.s_addr
= inet_addr(ip
);
528 he
= gethostbyaddr(&ia
, sizeof(ia
), AF_INET
);
529 js
= js_string(he
? he
->h_name
: "");
530 web_printf("%c['%s','%s']", comma
, inet_ntoa(ia
), js
);
541 #define PROC_SCSI_ROOT "/proc/scsi"
542 #define USB_STORAGE "usb-storage"
544 int is_host_mounted(uint host_no
)
547 char usb_part
[128], usb_disc
[128];
548 struct dirent
*dp_disc
;
550 // check if at least one partition of the host is mounted
551 sprintf(usb_disc
, "/dev/discs/disc%d", host_no
);
554 if ((usb_dev_part
= opendir(usb_disc
))) {
555 while (usb_dev_part
&& (dp_disc
= readdir(usb_dev_part
))) {
556 if (!strcmp(dp_disc
->d_name
, "..") || !strcmp(dp_disc
->d_name
, "."))
559 sprintf(usb_part
, "%s/%s", usb_disc
, dp_disc
->d_name
);
561 if (findmntent(usb_part
)) {
566 closedir(usb_dev_part
);
572 void asp_usbdevices(int argc
, char **argv
)
580 char *tmp
=NULL
, g_usb_vendor
[25], g_usb_product
[20], g_usb_serial
[20];
582 web_puts("\nusbdev = [");
584 if (!nvram_match("usb_enable", "1")) {
593 /* find all attached USB storage devices */
594 if ((usb_dev_disc
= opendir("/dev/discs"))) {
595 while (usb_dev_disc
&& (dp
= readdir(usb_dev_disc
))) {
596 if (!strcmp(dp
->d_name
, "..") || !strcmp(dp
->d_name
, "."))
599 /* Host no. assigned by scsi driver for this UFD */
600 host_no
= atoi(dp
->d_name
+ 4);
601 sprintf(line
, "%s/%s-%d/%d", PROC_SCSI_ROOT
, USB_STORAGE
, host_no
, host_no
);
603 fp
= fopen(line
, "r");
605 sprintf(line
, "%s/%s/%d", PROC_SCSI_ROOT
, USB_STORAGE
, host_no
);
606 fp
= fopen(line
, "r");
612 g_usb_product
[0] = 0;
616 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
617 if (strstr(line
, "Attached: Yes")) {
620 else if (strstr(line
, "Vendor")) {
621 tmp
= strtok(line
, " ");
622 tmp
= strtok(NULL
, "\n");
623 strcpy(g_usb_vendor
, tmp
);
626 else if (strstr(line
, "Product")) {
627 tmp
= strtok(line
, " ");
628 tmp
= strtok(NULL
, "\n");
629 strcpy(g_usb_product
, tmp
);
632 else if (strstr(line
, "Serial Number")) {
633 tmp
= strtok(line
, " ");
634 tmp
= strtok(NULL
, " ");
635 tmp
= strtok(NULL
, "\n");
636 strcpy(g_usb_serial
, tmp
);
643 web_printf("%s['Storage','%d','%s','%s','%s', %d]", i
? "," : "",
644 host_no
, g_usb_vendor
, g_usb_product
, g_usb_serial
, is_host_mounted(host_no
));
649 closedir(usb_dev_disc
);
653 // this version of the code is for broken scsiglue implementation in some kernels
654 // do not use unless there're problems
656 DIR *scsi_dir
=NULL
, *usb_dir
=NULL
;
657 struct dirent
*scsi_dirent
;
659 /* find all attached USB storage devices */
660 scsi_dir
= opendir(PROC_SCSI_ROOT
);
661 while (scsi_dir
&& (scsi_dirent
= readdir(scsi_dir
)))
663 if (!strncmp(USB_STORAGE
, scsi_dirent
->d_name
, strlen(USB_STORAGE
)))
665 sprintf(line
, "%s/%s", PROC_SCSI_ROOT
, scsi_dirent
->d_name
);
666 usb_dir
= opendir(line
);
667 while (usb_dir
&& (dp
= readdir(usb_dir
)))
669 if (!strcmp(dp
->d_name
, "..") || !strcmp(dp
->d_name
, "."))
671 sprintf(line
, "%s/%s/%s", PROC_SCSI_ROOT
, scsi_dirent
->d_name
, dp
->d_name
);
673 fp
= fopen(line
, "r");
677 g_usb_product
[0] = 0;
681 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
682 if (strstr(line
, "Attached: Yes")) {
685 else if (strstr(line
, "Vendor")) {
686 tmp
= strtok(line
, " ");
687 tmp
= strtok(NULL
, "\n");
688 strcpy(g_usb_vendor
, tmp
);
691 else if (strstr(line
, "Product")) {
692 tmp
= strtok(line
, " ");
693 tmp
= strtok(NULL
, "\n");
694 strcpy(g_usb_product
, tmp
);
697 else if (strstr(line
, "Serial Number")) {
698 tmp
= strtok(line
, " ");
699 tmp
= strtok(NULL
, " ");
700 tmp
= strtok(NULL
, "\n");
701 strcpy(g_usb_serial
, tmp
);
707 web_printf("%s['Storage','%d','%s','%s','%s', %d]", i
? "," : "",
708 host_no
, g_usb_vendor
, g_usb_product
, g_usb_serial
, is_host_mounted(host_no
));
722 /* now look for a printer */
723 if (f_exists("/dev/usb/lp0") && (fp
= fopen("/proc/usblp/usblpid", "r"))) {
725 g_usb_product
[0] = 0;
728 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
729 if (strstr(line
, "Manufacturer")) {
730 tmp
= strtok(line
, "=");
731 tmp
= strtok(NULL
, "\n");
732 strcpy(g_usb_vendor
, tmp
);
735 else if (strstr(line
, "Model")) {
736 tmp
= strtok(line
, "=");
737 tmp
= strtok(NULL
, "\n");
738 strcpy(g_usb_product
, tmp
);
742 if ((strlen(g_usb_product
) > 0) || (strlen(g_usb_vendor
) > 0)) {
743 web_printf("%s['Printer','','%s','%s','']", i
? "," : "",
744 g_usb_vendor
, g_usb_product
);
755 void wo_usbcommand(char *url
)
759 web_puts("\nusb = [\n");
760 if ((p
= webcgi_get("remove")) != NULL
) {
761 nvram_set("usb_web_umount", p
);
764 for (i
= 0; i
< 10; i
++) {
766 if (!nvram_invmatch("usb_web_umount", "")) break;
768 web_printf("%d", is_host_mounted(atoi(p
)));