allow to compile without CMON
[tomato.git] / release / src / router / rc / services.c
blob07d5837054b956314be6dfd01ac42178390a463f
1 /*
3 Copyright 2003, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Copyright 2005, Broadcom Corporation
22 All Rights Reserved.
24 THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
25 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
26 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
27 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
32 Modified for Tomato Firmware
33 Portions, Copyright (C) 2006-2009 Jonathan Zarate
36 #include "rc.h"
38 #include <arpa/inet.h>
39 #include <time.h>
40 #include <sys/time.h>
41 #include <errno.h>
43 // !!TB
44 #include <sys/mount.h>
45 #include <mntent.h>
46 #include <dirent.h>
48 // Pop an alarm to recheck pids in 500 msec.
49 static const struct itimerval pop_tv = { {0,0}, {0, 500 * 1000} };
51 // Pop an alarm to reap zombies.
52 static const struct itimerval zombie_tv = { {0,0}, {307, 0} };
54 // -----------------------------------------------------------------------------
56 static const char dmhosts[] = "/etc/dnsmasq/hosts";
57 static const char dmdhcp[] = "/etc/dnsmasq/dhcp";
58 static const char dmresolv[] = "/etc/resolv.dnsmasq";
60 static pid_t pid_dnsmasq = -1;
62 static int is_wet(int idx, int unit, int subunit, void *param)
64 return nvram_match(wl_nvname("mode", unit, subunit), "wet");
67 void start_dnsmasq()
69 FILE *f;
70 const char *nv;
71 char buf[512];
72 char lan[24];
73 const char *router_ip;
74 const char *lan_ifname;
75 char sdhcp_lease[32];
76 char *e;
77 int n;
78 char *mac, *ip, *name;
79 char *p;
80 int ipn;
81 char ipbuf[32];
82 FILE *hf, *df;
83 int dhcp_start;
84 int dhcp_count;
85 int dhcp_lease;
86 int do_dhcpd;
87 int do_dns;
89 TRACE_PT("begin\n");
91 if (getpid() != 1) {
92 start_service("dnsmasq");
93 return;
96 stop_dnsmasq();
98 if (foreach_wif(1, NULL, is_wet)) return;
100 if ((f = fopen("/etc/dnsmasq.conf", "w")) == NULL) return;
102 lan_ifname = nvram_safe_get("lan_ifname");
103 router_ip = nvram_safe_get("lan_ipaddr");
104 strlcpy(lan, router_ip, sizeof(lan));
105 if ((p = strrchr(lan, '.')) != NULL) *(p + 1) = 0;
107 fprintf(f,
108 "pid-file=/var/run/dnsmasq.pid\n"
109 "interface=%s\n",
110 lan_ifname);
111 if (((nv = nvram_get("wan_domain")) != NULL) || ((nv = nvram_get("wan_get_domain")) != NULL)) {
112 if (*nv) fprintf(f, "domain=%s\n", nv);
115 // dns
116 const dns_list_t *dns = get_dns(); // this always points to a static buffer
118 if (((nv = nvram_get("dns_minport")) != NULL) && (*nv)) n = atoi(nv);
119 else n = 4096;
120 fprintf(f,
121 "resolv-file=%s\n" // the real stuff is here
122 "addn-hosts=%s\n" // directory with additional hosts files
123 "dhcp-hostsfile=%s\n" // directory with dhcp hosts files
124 "expand-hosts\n" // expand hostnames in hosts file
125 "min-port=%u\n", // min port used for random src port
126 dmresolv, dmhosts, dmdhcp, n);
127 do_dns = nvram_match("dhcpd_dmdns", "1");
129 // DNS rebinding protection, will discard upstream RFC1918 responses
130 if (nvram_get_int("dns_norebind")) {
131 fprintf(f,
132 "stop-dns-rebind\n"
133 "rebind-localhost-ok\n");
134 // allow RFC1918 responses for server domain
135 switch (get_wan_proto()) {
136 case WP_PPTP:
137 nv = nvram_get("pptp_server_ip");
138 break;
139 case WP_L2TP:
140 nv = nvram_get("l2tp_server_ip");
141 break;
142 default:
143 nv = NULL;
144 break;
146 if (nv && *nv) fprintf(f, "rebind-domain-ok=%s\n", nv);
149 for (n = 0 ; n < dns->count; ++n) {
150 if (dns->dns[n].port != 53) {
151 fprintf(f, "server=%s#%u\n", inet_ntoa(dns->dns[n].addr), dns->dns[n].port);
155 // dhcp
156 do_dhcpd = nvram_match("lan_proto", "dhcp");
157 if (do_dhcpd) {
158 dhcp_lease = nvram_get_int("dhcp_lease");
159 if (dhcp_lease <= 0) dhcp_lease = 1440;
161 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
162 if (n < 0) strcpy(sdhcp_lease, "infinite");
163 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
165 if (!do_dns) {
166 // if not using dnsmasq for dns
168 if ((dns->count == 0) && (nvram_get_int("dhcpd_llndns"))) {
169 // no DNS might be temporary. use a low lease time to force clients to update.
170 dhcp_lease = 2;
171 strcpy(sdhcp_lease, "2m");
172 do_dns = 1;
174 else {
175 // pass the dns directly
176 buf[0] = 0;
177 for (n = 0 ; n < dns->count; ++n) {
178 if (dns->dns[n].port == 53) { // check: option 6 doesn't seem to support other ports
179 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n].addr));
182 fprintf(f, "dhcp-option=6%s\n", buf);
186 if ((p = nvram_get("dhcpd_startip")) && (*p) && (e = nvram_get("dhcpd_endip")) && (*e)) {
187 fprintf(f, "dhcp-range=%s,%s,%s,%dm\n", p, e, nvram_safe_get("lan_netmask"), dhcp_lease);
189 else {
190 // for compatibility
191 dhcp_start = nvram_get_int("dhcp_start");
192 dhcp_count = nvram_get_int("dhcp_num");
193 fprintf(f, "dhcp-range=%s%d,%s%d,%s,%dm\n",
194 lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get("lan_netmask"), dhcp_lease);
197 nv = router_ip;
198 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED)) {
199 p = nvram_safe_get("lan_gateway");
200 if ((*p) && (strcmp(p, "0.0.0.0") != 0)) nv = p;
203 n = nvram_get_int("dhcpd_lmax");
204 fprintf(f,
205 "dhcp-option=3,%s\n" // gateway
206 "dhcp-lease-max=%d\n",
208 (n > 0) ? n : 255);
210 if (nvram_get_int("dhcpd_auth") >= 0) {
211 fprintf(f, "dhcp-authoritative\n");
214 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
215 fprintf(f, "dhcp-option=44,%s\n", nv);
217 #ifdef TCONFIG_SAMBASRV
218 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
219 if ((nv == NULL) || (*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
220 // Samba will serve as a WINS server
221 fprintf(f, "dhcp-option=44,0.0.0.0\n");
224 #endif
226 else {
227 fprintf(f, "no-dhcp-interface=%s\n", lan_ifname);
230 // write static lease entries & create hosts file
232 mkdir_if_none(dmhosts);
233 snprintf(buf, sizeof(buf), "%s/hosts", dmhosts);
234 if ((hf = fopen(buf, "w")) != NULL) {
235 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
236 fprintf(hf, "%s %s\n", router_ip, nv);
237 #ifdef TCONFIG_SAMBASRV
238 else if (((nv = nvram_get("lan_hostname")) != NULL) && (*nv))
239 fprintf(hf, "%s %s\n", router_ip, nv);
240 #endif
241 p = (char *)get_wanip();
242 if ((*p == 0) || strcmp(p, "0.0.0.0") == 0)
243 p = "127.0.0.1";
244 fprintf(hf, "%s wan-ip\n", p);
245 if (nv && (*nv))
246 fprintf(hf, "%s %s-wan\n", p, nv);
249 mkdir_if_none(dmdhcp);
250 snprintf(buf, sizeof(buf), "%s/dhcp-hosts", dmdhcp);
251 df = fopen(buf, "w");
253 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
254 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
255 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 106 w/ delim
256 p = nvram_safe_get("dhcpd_static");
257 while ((e = strchr(p, '>')) != NULL) {
258 n = (e - p);
259 if (n > 105) {
260 p = e + 1;
261 continue;
264 strncpy(buf, p, n);
265 buf[n] = 0;
266 p = e + 1;
268 if ((e = strchr(buf, '<')) == NULL) continue;
269 *e = 0;
270 mac = buf;
272 ip = e + 1;
273 if ((e = strchr(ip, '<')) == NULL) continue;
274 *e = 0;
275 if (strchr(ip, '.') == NULL) {
276 ipn = atoi(ip);
277 if ((ipn <= 0) || (ipn > 255)) continue;
278 sprintf(ipbuf, "%s%d", lan, ipn);
279 ip = ipbuf;
281 else {
282 if (inet_addr(ip) == INADDR_NONE) continue;
285 name = e + 1;
287 if ((hf) && (*name != 0)) {
288 fprintf(hf, "%s %s\n", ip, name);
291 if ((do_dhcpd) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
292 if (df)
293 fprintf(df, "%s,%s,%s\n", mac, ip, sdhcp_lease);
294 else
295 fprintf(f, "dhcp-host=%s,%s,%s\n", mac, ip, sdhcp_lease);
299 if (df) fclose(df);
300 if (hf) fclose(hf);
304 #ifdef TCONFIG_OPENVPN
305 write_vpn_dnsmasq_config(f);
306 #endif
308 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
310 fappend(f, "/etc/dnsmasq.custom");
314 fclose(f);
316 if (do_dns) {
317 unlink("/etc/resolv.conf");
318 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
321 TRACE_PT("run dnsmasq\n");
323 // Default to some values we like, but allow the user to override them.
324 eval("dnsmasq", "-c", "1500", "--log-async");
326 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
327 pid_dnsmasq = -2;
330 TRACE_PT("end\n");
333 void stop_dnsmasq(void)
335 TRACE_PT("begin\n");
337 if (getpid() != 1) {
338 stop_service("dnsmasq");
339 return;
342 pid_dnsmasq = -1;
344 unlink("/etc/resolv.conf");
345 symlink(dmresolv, "/etc/resolv.conf");
347 killall_tk("dnsmasq");
349 TRACE_PT("end\n");
352 void clear_resolv(void)
354 f_write(dmresolv, NULL, 0, 0, 0); // blank
357 #ifdef TCONFIG_IPV6
358 static int write_ipv6_dns_servers(FILE *f, const char *prefix, char *dns, const char *suffix, int once)
360 char p[INET6_ADDRSTRLEN + 1], *next = NULL;
361 struct in6_addr addr;
362 int cnt = 0;
364 foreach(p, dns, next) {
365 // verify that this is a valid IPv6 address
366 if (inet_pton(AF_INET6, p, &addr) == 1) {
367 fprintf(f, "%s%s%s", (once && cnt) ? "" : prefix, p, suffix);
368 ++cnt;
372 return cnt;
374 #endif
376 void dns_to_resolv(void)
378 FILE *f;
379 const dns_list_t *dns;
380 int i;
381 mode_t m;
383 m = umask(022); // 077 from pppoecd
384 if ((f = fopen(dmresolv, "w")) != NULL) {
385 // Check for VPN DNS entries
386 if (!write_vpn_resolv(f)) {
387 #ifdef TCONFIG_IPV6
388 if (write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_dns"), "\n", 0) == 0 || nvram_get_int("dns_addget"))
389 write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_get_dns"), "\n", 0);
390 #endif
391 dns = get_dns(); // static buffer
392 if (dns->count == 0) {
393 // Put a pseudo DNS IP to trigger Connect On Demand
394 if (nvram_match("ppp_demand", "1")) {
395 switch (get_wan_proto()) {
396 case WP_PPPOE:
397 case WP_PPTP:
398 case WP_L2TP:
399 fprintf(f, "nameserver 1.1.1.1\n");
400 break;
404 else {
405 for (i = 0; i < dns->count; i++) {
406 if (dns->dns[i].port == 53) { // resolv.conf doesn't allow for an alternate port
407 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i].addr));
412 fclose(f);
414 umask(m);
417 // -----------------------------------------------------------------------------
419 void start_httpd(void)
421 if (getpid() != 1) {
422 start_service("httpd");
423 return;
426 stop_httpd();
427 chdir("/www");
428 eval("httpd");
429 chdir("/");
432 void stop_httpd(void)
434 if (getpid() != 1) {
435 stop_service("httpd");
436 return;
439 killall_tk("httpd");
442 // -----------------------------------------------------------------------------
443 #ifdef TCONFIG_IPV6
445 static void add_ip6_lanaddr(void)
447 char ip[INET6_ADDRSTRLEN + 4];
448 const char *p;
450 p = ipv6_router_address(NULL);
451 if (*p) {
452 snprintf(ip, sizeof(ip), "%s/%d", p, nvram_get_int("ipv6_prefix_length") ? : 64);
453 eval("ip", "-6", "addr", "add", ip, "dev", nvram_safe_get("lan_ifname"));
457 void start_ipv6_tunnel(void)
459 char ip[INET6_ADDRSTRLEN + 4];
460 struct in_addr addr4;
461 struct in6_addr addr;
462 const char *wanip, *mtu, *tun_dev;
463 int service;
465 service = get_ipv6_service();
466 tun_dev = get_wan6face();
467 wanip = get_wanip();
468 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
469 modprobe("sit");
471 if (service == IPV6_ANYCAST_6TO4)
472 snprintf(ip, sizeof(ip), "192.88.99.%d", nvram_get_int("ipv6_relay"));
473 else
474 strlcpy(ip, (char *)nvram_safe_get("ipv6_tun_v4end"), sizeof(ip));
475 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit",
476 "remote", ip,
477 "local", (char *)wanip,
478 "ttl", nvram_safe_get("ipv6_tun_ttl"));
480 eval("ip", "link", "set", (char *)tun_dev, "mtu", (char *)mtu, "up");
481 nvram_set("ipv6_ifname", (char *)tun_dev);
483 if (service == IPV6_ANYCAST_6TO4) {
484 add_ip6_lanaddr();
485 addr4.s_addr = 0;
486 memset(&addr, 0, sizeof(addr));
487 inet_aton(wanip, &addr4);
488 addr.s6_addr16[0] = htons(0x2002);
489 ipv6_mapaddr4(&addr, 16, &addr4, 0);
490 addr.s6_addr16[7] = htons(0x0001);
491 inet_ntop(AF_INET6, &addr, ip, sizeof(ip));
492 strncat(ip, "/16", sizeof(ip));
494 else {
495 snprintf(ip, sizeof(ip), "%s/%d",
496 nvram_safe_get("ipv6_tun_addr"),
497 nvram_get_int("ipv6_tun_addrlen") ? : 64);
499 eval("ip", "addr", "add", ip, "dev", (char *)tun_dev);
500 eval("ip", "route", "add", "::/0", "dev", (char *)tun_dev);
502 // (re)start radvd
503 if (service == IPV6_ANYCAST_6TO4)
504 start_radvd();
507 void stop_ipv6_tunnel(void)
509 eval("ip", "tunnel", "del", (char *)get_wan6face());
510 if (get_ipv6_service() == IPV6_ANYCAST_6TO4) {
511 // get rid of old IPv6 address from lan iface
512 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
514 modprobe_r("sit");
517 static pid_t pid_radvd = -1;
519 void start_radvd(void)
521 FILE *f;
522 char *prefix, *ip, *mtu;
523 int do_dns, do_6to4;
524 char *argv[] = { "radvd", NULL, NULL, NULL };
525 int pid, argc, service, cnt;
527 if (getpid() != 1) {
528 start_service("radvd");
529 return;
532 stop_radvd();
534 if (ipv6_enabled() && nvram_get_int("ipv6_radvd")) {
535 service = get_ipv6_service();
536 do_6to4 = (service == IPV6_ANYCAST_6TO4);
537 mtu = NULL;
539 switch (service) {
540 case IPV6_NATIVE_DHCP:
541 prefix = "::";
542 break;
543 case IPV6_ANYCAST_6TO4:
544 case IPV6_6IN4:
545 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
546 // fall through
547 default:
548 prefix = do_6to4 ? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
549 break;
551 if (!(*prefix)) prefix = "::";
553 // Create radvd.conf
554 if ((f = fopen("/etc/radvd.conf", "w")) == NULL) return;
556 ip = (char *)ipv6_router_address(NULL);
557 do_dns = (*ip) && nvram_match("dhcpd_dmdns", "1");
559 fprintf(f,
560 "interface %s\n"
561 "{\n"
562 " IgnoreIfMissing on;\n"
563 " AdvSendAdvert on;\n"
564 " MaxRtrAdvInterval 60;\n"
565 " AdvHomeAgentFlag off;\n"
566 " AdvManagedFlag off;\n"
567 "%s%s%s"
568 " prefix %s/64 \n"
569 " {\n"
570 " AdvOnLink on;\n"
571 " AdvAutonomous on;\n"
572 "%s"
573 "%s%s%s"
574 " };\n",
575 nvram_safe_get("lan_ifname"),
576 mtu ? " AdvLinkMTU " : "", mtu ? : "", mtu ? ";\n" : "",
577 prefix,
578 do_6to4 ? " AdvValidLifetime 300;\n AdvPreferredLifetime 120;\n" : "",
579 do_6to4 ? " Base6to4Interface " : "",
580 do_6to4 ? get_wanface() : "",
581 do_6to4 ? ";\n" : "");
583 if (do_dns) {
584 fprintf(f, " RDNSS %s {};\n", ip);
586 else {
587 cnt = write_ipv6_dns_servers(f, " RDNSS ", nvram_safe_get("ipv6_dns"), " ", 1);
588 if (cnt == 0 || nvram_get_int("dns_addget"))
589 cnt += write_ipv6_dns_servers(f, (cnt) ? "" : " RDNSS ", nvram_safe_get("ipv6_get_dns"), " ", 1);
590 if (cnt) fprintf(f, "{};\n");
593 fprintf(f,
594 "};\n"); // close "interface" section
595 fclose(f);
597 // Start radvd
598 argc = 1;
599 if (nvram_get_int("debug_ipv6")) {
600 argv[argc++] = "-d";
601 argv[argc++] = "10";
603 argv[argc] = NULL;
604 _eval(argv, NULL, 0, &pid);
606 if (!nvram_contains_word("debug_norestart", "radvd")) {
607 pid_radvd = -2;
612 void stop_radvd(void)
614 if (getpid() != 1) {
615 stop_service("radvd");
616 return;
619 pid_radvd = -1;
620 killall_tk("radvd");
623 void start_ipv6(void)
625 int service;
627 service = get_ipv6_service();
628 enable_ip_forward();
630 // Check if turned on
631 switch (service) {
632 case IPV6_NATIVE:
633 case IPV6_6IN4:
634 case IPV6_MANUAL:
635 add_ip6_lanaddr();
636 break;
637 case IPV6_NATIVE_DHCP:
638 case IPV6_ANYCAST_6TO4:
639 nvram_set("ipv6_rtr_addr", "");
640 nvram_set("ipv6_prefix", "");
641 break;
644 if (service != IPV6_DISABLED) {
645 if ((nvram_get_int("ipv6_accept_ra") & 2) != 0 && !nvram_get_int("ipv6_radvd"))
646 accept_ra(nvram_safe_get("lan_ifname"));
650 void stop_ipv6(void)
652 stop_ipv6_tunnel();
653 stop_dhcp6c();
654 eval("ip", "-6", "addr", "flush", "scope", "global");
657 #endif
659 // -----------------------------------------------------------------------------
661 void start_upnp(void)
663 if (getpid() != 1) {
664 start_service("upnp");
665 return;
668 if (get_wan_proto() == WP_DISABLED) return;
670 int enable;
671 FILE *f;
672 int upnp_port;
674 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
675 mkdir("/etc/upnp", 0777);
676 if (f_exists("/etc/upnp/config.alt")) {
677 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
679 else {
680 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
681 upnp_port = nvram_get_int("upnp_port");
682 if ((upnp_port < 0) || (upnp_port >= 0xFFFF)) upnp_port = 0;
684 char *lanip = nvram_safe_get("lan_ipaddr");
685 char *lanmask = nvram_safe_get("lan_netmask");
687 fprintf(f,
688 "ext_ifname=%s\n"
689 "listening_ip=%s/%s\n"
690 "port=%d\n"
691 "enable_upnp=%s\n"
692 "enable_natpmp=%s\n"
693 "secure_mode=%s\n"
694 "upnp_forward_chain=upnp\n"
695 "upnp_nat_chain=upnp\n"
696 "notify_interval=%d\n"
697 "system_uptime=yes\n"
698 "\n"
700 get_wanface(),
701 lanip, lanmask,
702 upnp_port,
703 (enable & 1) ? "yes" : "no", // upnp enable
704 (enable & 2) ? "yes" : "no", // natpmp enable
705 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
706 nvram_get_int("upnp_ssdp_interval")
709 if (nvram_get_int("upnp_clean")) {
710 int interval = nvram_get_int("upnp_clean_interval");
711 if (interval < 60) interval = 60;
712 fprintf(f,
713 "clean_ruleset_interval=%d\n"
714 "clean_ruleset_threshold=%d\n",
715 interval,
716 nvram_get_int("upnp_clean_threshold")
719 else
720 fprintf(f,"clean_ruleset_interval=0\n");
722 if (nvram_match("upnp_mnp", "1")) {
723 int https = nvram_get_int("https_enable");
724 fprintf(f, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
725 https ? "s" : "", lanip,
726 nvram_safe_get(https ? "https_lanport" : "http_lanport"));
728 else {
729 // Empty parameters are not included into XML service description
730 fprintf(f, "presentation_url=\n");
733 char uuid[45];
734 f_read_string("/proc/sys/kernel/random/uuid", uuid, sizeof(uuid));
735 fprintf(f, "uuid=%s\n", uuid);
737 int ports[4];
738 if ((ports[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
739 (ports[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
740 (ports[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
741 (ports[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
742 fprintf(f,
743 "allow %d-%d %s/%s %d-%d\n",
744 ports[0], ports[1],
745 lanip, lanmask,
746 ports[2], ports[3]
749 else {
750 // by default allow only redirection of ports above 1024
751 fprintf(f, "allow 1024-65535 %s/%s 1024-65535\n", lanip, lanmask);
754 fappend(f, "/etc/upnp/config.custom");
755 fprintf(f, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
756 fclose(f);
758 xstart("miniupnpd", "-f", "/etc/upnp/config");
764 void stop_upnp(void)
766 if (getpid() != 1) {
767 stop_service("upnp");
768 return;
771 killall_tk("miniupnpd");
774 // -----------------------------------------------------------------------------
776 static pid_t pid_crond = -1;
778 void start_cron(void)
780 stop_cron();
782 eval("crond", nvram_contains_word("log_events", "crond") ? NULL : "-l", "9");
783 if (!nvram_contains_word("debug_norestart", "crond")) {
784 pid_crond = -2;
788 void stop_cron(void)
790 pid_crond = -1;
791 killall_tk("crond");
794 // -----------------------------------------------------------------------------
795 #ifdef LINUX26
797 static pid_t pid_hotplug2 = -1;
799 void start_hotplug2()
801 stop_hotplug2();
803 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE, 0);
804 xstart("hotplug2", "--persistent", "--no-coldplug");
805 // FIXME: Don't remember exactly why I put "sleep" here -
806 // but it was not for a race with check_services()... - TB
807 sleep(1);
809 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
810 pid_hotplug2 = -2;
814 void stop_hotplug2(void)
816 pid_hotplug2 = -1;
817 killall_tk("hotplug2");
820 #endif /* LINUX26 */
821 // -----------------------------------------------------------------------------
823 // Written by Sparq in 2002/07/16
824 void start_zebra(void)
826 #ifdef TCONFIG_ZEBRA
827 if (getpid() != 1) {
828 start_service("zebra");
829 return;
832 FILE *fp;
834 char *lan_tx = nvram_safe_get("dr_lan_tx");
835 char *lan_rx = nvram_safe_get("dr_lan_rx");
836 char *wan_tx = nvram_safe_get("dr_wan_tx");
837 char *wan_rx = nvram_safe_get("dr_wan_rx");
839 if ((*lan_tx == '0') && (*lan_rx == '0') && (*wan_tx == '0') && (*wan_rx == '0')) {
840 return;
843 // empty
844 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
845 fclose(fp);
849 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
850 char *lan_ifname = nvram_safe_get("lan_ifname");
851 char *wan_ifname = nvram_safe_get("wan_ifname");
853 fprintf(fp, "router rip\n");
854 fprintf(fp, "network %s\n", lan_ifname);
855 fprintf(fp, "network %s\n", wan_ifname);
856 fprintf(fp, "redistribute connected\n");
857 //fprintf(fp, "redistribute static\n");
859 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
860 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
862 fprintf(fp, "interface %s\n", lan_ifname);
863 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
864 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
866 fprintf(fp, "interface %s\n", wan_ifname);
867 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
868 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
870 fprintf(fp, "router rip\n");
871 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
872 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
873 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
874 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
875 fprintf(fp, "access-list private deny any\n");
877 //fprintf(fp, "debug rip events\n");
878 //fprintf(fp, "log file /etc/ripd.log\n");
879 fclose(fp);
882 xstart("zebra", "-d");
883 xstart("ripd", "-d");
884 #endif
887 void stop_zebra(void)
889 #ifdef TCONFIG_ZEBRA
890 if (getpid() != 1) {
891 stop_service("zebra");
892 return;
895 killall("zebra", SIGTERM);
896 killall("ripd", SIGTERM);
898 unlink("/etc/zebra.conf");
899 unlink("/etc/ripd.conf");
900 #endif
903 // -----------------------------------------------------------------------------
905 void start_syslog(void)
907 char *argv[16];
908 int argc;
909 char *nv;
910 char *b_opt = "";
911 char rem[256];
912 int n;
913 char s[64];
914 char cfg[256];
915 char *rot_siz = "50";
916 char *log_file_path;
918 argv[0] = "syslogd";
919 argc = 1;
921 if (nvram_match("log_remote", "1")) {
922 nv = nvram_safe_get("log_remoteip");
923 if (*nv) {
924 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
925 argv[argc++] = "-R";
926 argv[argc++] = rem;
930 if (nvram_match("log_file", "1")) {
931 argv[argc++] = "-L";
933 // log to custom path - shibby
934 if (nvram_match("log_file_custom", "1")) {
935 log_file_path = nvram_safe_get("log_file_path");
936 argv[argc++] = "-s";
937 argv[argc++] = "5000";
938 argv[argc++] = "-b";
939 argv[argc++] = "5";
940 argv[argc++] = "-O";
941 argv[argc++] = log_file_path;
942 remove("/var/log/messages");
943 symlink(log_file_path, "/var/log/messages");
945 else
947 /* Read options: rotate_size(kb) num_backups logfilename.
948 * Ignore these settings and use defaults if the logfile cannot be written to.
950 if (f_read_string("/etc/syslogd.cfg", cfg, sizeof(cfg)) > 0) {
951 if ((nv = strchr(cfg, '\n')))
952 *nv = 0;
954 if ((nv = strtok(cfg, " \t"))) {
955 if (isdigit(*nv))
956 rot_siz = nv;
959 if ((nv = strtok(NULL, " \t")))
960 b_opt = nv;
962 if ((nv = strtok(NULL, " \t")) && *nv == '/') {
963 if (f_write(nv, cfg, 0, FW_APPEND, 0) >= 0) {
964 argv[argc++] = "-O";
965 argv[argc++] = nv;
967 else {
968 rot_siz = "50";
969 b_opt = "";
974 if (nvram_match("log_file_custom", "0")) {
975 argv[argc++] = "-s";
976 argv[argc++] = rot_siz;
977 remove("/var/log/messages");
980 if (isdigit(*b_opt)) {
981 argv[argc++] = "-b";
982 argv[argc++] = b_opt;
986 if (argc > 1) {
987 argv[argc] = NULL;
988 _eval(argv, NULL, 0, NULL);
990 argv[0] = "klogd";
991 argv[1] = NULL;
992 _eval(argv, NULL, 0, NULL);
994 // used to be available in syslogd -m
995 n = nvram_get_int("log_mark");
996 if (n > 0) {
997 // n is in minutes
998 if (n < 60)
999 sprintf(rem, "*/%d * * * *", n);
1000 else if (n < 60 * 24)
1001 sprintf(rem, "0 */%d * * *", n / 60);
1002 else
1003 sprintf(rem, "0 0 */%d * *", n / (60 * 24));
1004 sprintf(s, "%s logger -p syslog.info -- -- MARK --", rem);
1005 eval("cru", "a", "syslogdmark", s);
1007 else {
1008 eval("cru", "d", "syslogdmark");
1013 void stop_syslog(void)
1015 killall("klogd", SIGTERM);
1016 killall("syslogd", SIGTERM);
1019 // -----------------------------------------------------------------------------
1021 static pid_t pid_igmp = -1;
1023 void start_igmp_proxy(void)
1025 FILE *fp;
1027 pid_igmp = -1;
1028 if (nvram_match("multicast_pass", "1")) {
1029 if (get_wan_proto() == WP_DISABLED)
1030 return;
1032 if (f_exists("/etc/igmp.alt")) {
1033 eval("igmpproxy", "/etc/igmp.alt");
1035 else if ((fp = fopen("/etc/igmp.conf", "w")) != NULL) {
1036 fprintf(fp,
1037 "quickleave\n"
1038 "phyint %s upstream\n"
1039 "\taltnet %s\n"
1040 "phyint %s downstream ratelimit 0\n",
1041 nvram_safe_get("wan_ifname"),
1042 nvram_get("multicast_altnet") ? : "0.0.0.0/0",
1043 nvram_safe_get("lan_ifname"));
1044 fclose(fp);
1045 eval("igmpproxy", "/etc/igmp.conf");
1047 else {
1048 return;
1050 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1051 pid_igmp = -2;
1056 void stop_igmp_proxy(void)
1058 pid_igmp = -1;
1059 killall_tk("igmpproxy");
1062 #ifdef TCONFIG_NOCAT
1064 static pid_t pid_splashd = -1;
1065 void start_splashd(void)
1067 pid_splashd = -1;
1068 start_nocat();
1069 if (!nvram_contains_word("debug_norestart", "splashd")) {
1070 pid_splashd = -2;
1074 void stop_splashd(void)
1076 pid_splashd = -1;
1077 stop_nocat();
1078 start_wan(BOOT);
1080 #endif
1082 // -----------------------------------------------------------------------------
1084 void set_tz(void)
1086 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
1089 void start_ntpc(void)
1091 set_tz();
1093 stop_ntpc();
1095 if (nvram_get_int("ntp_updates") >= 0) {
1096 xstart("ntpsync", "--init");
1100 void stop_ntpc(void)
1102 killall("ntpsync", SIGTERM);
1105 // -----------------------------------------------------------------------------
1107 static void stop_rstats(void)
1109 int n;
1110 int pid;
1112 n = 60;
1113 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
1114 if (kill(pid, SIGTERM) != 0) break;
1115 sleep(1);
1119 static void start_rstats(int new)
1121 if (nvram_match("rstats_enable", "1")) {
1122 stop_rstats();
1123 if (new) xstart("rstats", "--new");
1124 else xstart("rstats");
1128 // -----------------------------------------------------------------------------
1130 // !!TB - FTP Server
1132 #ifdef TCONFIG_FTP
1133 static char *get_full_storage_path(char *val)
1135 static char buf[128];
1136 int len;
1138 if (val[0] == '/')
1139 len = sprintf(buf, "%s", val);
1140 else
1141 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
1143 if (len > 1 && buf[len - 1] == '/')
1144 buf[len - 1] = 0;
1146 return buf;
1149 static char *nvram_storage_path(char *var)
1151 char *val = nvram_safe_get(var);
1152 return get_full_storage_path(val);
1155 char vsftpd_conf[] = "/etc/vsftpd.conf";
1156 char vsftpd_users[] = "/etc/vsftpd.users";
1157 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
1159 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1161 static void start_ftpd(void)
1163 char tmp[256];
1164 FILE *fp, *f;
1165 char *buf;
1166 char *p, *q;
1167 char *user, *pass, *rights;
1169 if (getpid() != 1) {
1170 start_service("ftpd");
1171 return;
1174 if (!nvram_get_int("ftp_enable")) return;
1176 mkdir_if_none(vsftpd_users);
1177 mkdir_if_none("/var/run/vsftpd");
1179 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
1180 return;
1182 if (nvram_get_int("ftp_super"))
1184 /* rights */
1185 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
1186 if ((f = fopen(tmp, "w")))
1188 fprintf(f,
1189 "dirlist_enable=yes\n"
1190 "write_enable=yes\n"
1191 "download_enable=yes\n");
1192 fclose(f);
1196 #ifdef TCONFIG_SAMBASRV
1197 if (nvram_match("smbd_cset", "utf8"))
1198 fprintf(fp, "utf8=yes\n");
1199 #endif
1201 if (nvram_invmatch("ftp_anonymous", "0"))
1203 fprintf(fp,
1204 "anon_allow_writable_root=yes\n"
1205 "anon_world_readable_only=no\n"
1206 "anon_umask=022\n");
1208 /* rights */
1209 sprintf(tmp, "%s/ftp", vsftpd_users);
1210 if ((f = fopen(tmp, "w")))
1212 if (nvram_match("ftp_dirlist", "0"))
1213 fprintf(f, "dirlist_enable=yes\n");
1214 if (nvram_match("ftp_anonymous", "1") ||
1215 nvram_match("ftp_anonymous", "3"))
1216 fprintf(f, "write_enable=yes\n");
1217 if (nvram_match("ftp_anonymous", "1") ||
1218 nvram_match("ftp_anonymous", "2"))
1219 fprintf(f, "download_enable=yes\n");
1220 fclose(f);
1222 if (nvram_match("ftp_anonymous", "1") ||
1223 nvram_match("ftp_anonymous", "3"))
1224 fprintf(fp,
1225 "anon_upload_enable=yes\n"
1226 "anon_mkdir_write_enable=yes\n"
1227 "anon_other_write_enable=yes\n");
1228 } else {
1229 fprintf(fp, "anonymous_enable=no\n");
1232 fprintf(fp,
1233 "dirmessage_enable=yes\n"
1234 "download_enable=no\n"
1235 "dirlist_enable=no\n"
1236 "hide_ids=yes\n"
1237 "syslog_enable=yes\n"
1238 "local_enable=yes\n"
1239 "local_umask=022\n"
1240 "chmod_enable=no\n"
1241 "chroot_local_user=yes\n"
1242 "check_shell=no\n"
1243 "log_ftp_protocol=%s\n"
1244 "user_config_dir=%s\n"
1245 "passwd_file=%s\n"
1246 "listen%s=yes\n"
1247 "listen_port=%s\n"
1248 "background=yes\n"
1249 "isolate=no\n"
1250 "max_clients=%d\n"
1251 "max_per_ip=%d\n"
1252 "max_login_fails=1\n"
1253 "idle_session_timeout=%s\n"
1254 "use_sendfile=no\n"
1255 "anon_max_rate=%d\n"
1256 "local_max_rate=%d\n"
1257 "%s\n",
1258 nvram_get_int("log_ftp") ? "yes" : "no",
1259 vsftpd_users, vsftpd_passwd,
1260 #ifdef TCONFIG_IPV6
1261 ipv6_enabled() ? "_ipv6" : "",
1262 #else
1264 #endif
1265 nvram_get("ftp_port") ? : "21",
1266 nvram_get_int("ftp_max"),
1267 nvram_get_int("ftp_ipmax"),
1268 nvram_get("ftp_staytimeout") ? : "300",
1269 nvram_get_int("ftp_anonrate") * 1024,
1270 nvram_get_int("ftp_rate") * 1024,
1271 nvram_safe_get("ftp_custom"));
1273 fclose(fp);
1275 /* prepare passwd file and default users */
1276 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
1277 return;
1279 if (((user = nvram_get("http_username")) == NULL) || (*user == 0)) user = "admin";
1280 if (((pass = nvram_get("http_passwd")) == NULL) || (*pass == 0)) pass = "admin";
1282 fprintf(fp, /* anonymous, admin, nobody */
1283 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1284 "%s:%s:0:0:root:/:/sbin/nologin\n"
1285 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1286 nvram_storage_path("ftp_anonroot"), user,
1287 nvram_get_int("ftp_super") ? crypt(pass, "$1$") : "x",
1288 MOUNT_ROOT);
1290 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
1293 username<password<rights
1294 rights:
1295 Read/Write
1296 Read Only
1297 View Only
1298 Private
1300 p = buf;
1301 while ((q = strsep(&p, ">")) != NULL) {
1302 if (vstrsep(q, "<", &user, &pass, &rights) != 3) continue;
1303 if (!user || !pass) continue;
1305 /* directory */
1306 if (strncmp(rights, "Private", 7) == 0)
1308 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
1309 mkdir_if_none(tmp);
1311 else
1312 sprintf(tmp, "%s", nvram_storage_path("ftp_pubroot"));
1314 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1315 user, crypt(pass, "$1$"), user, tmp);
1317 /* rights */
1318 sprintf(tmp, "%s/%s", vsftpd_users, user);
1319 if ((f = fopen(tmp, "w")))
1321 tmp[0] = 0;
1322 if (nvram_invmatch("ftp_dirlist", "1"))
1323 strcat(tmp, "dirlist_enable=yes\n");
1324 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
1325 strcat(tmp, "download_enable=yes\n");
1326 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
1327 strcat(tmp, "write_enable=yes\n");
1329 fputs(tmp, f);
1330 fclose(f);
1333 free(buf);
1336 fclose(fp);
1337 killall("vsftpd", SIGHUP);
1339 /* start vsftpd if it's not already running */
1340 if (pidof("vsftpd") <= 0)
1341 xstart("vsftpd");
1344 static void stop_ftpd(void)
1346 if (getpid() != 1) {
1347 stop_service("ftpd");
1348 return;
1351 killall_tk("vsftpd");
1352 unlink(vsftpd_passwd);
1353 unlink(vsftpd_conf);
1354 eval("rm", "-rf", vsftpd_users);
1356 #endif // TCONFIG_FTP
1358 // -----------------------------------------------------------------------------
1360 // !!TB - Samba
1362 #ifdef TCONFIG_SAMBASRV
1363 static void kill_samba(int sig)
1365 if (sig == SIGTERM) {
1366 killall_tk("smbd");
1367 killall_tk("nmbd");
1369 else {
1370 killall("smbd", sig);
1371 killall("nmbd", sig);
1375 static void start_samba(void)
1377 FILE *fp;
1378 DIR *dir = NULL;
1379 struct dirent *dp;
1380 char nlsmod[15];
1381 int mode;
1382 char *nv;
1384 if (getpid() != 1) {
1385 start_service("smbd");
1386 return;
1389 mode = nvram_get_int("smbd_enable");
1390 if (!mode || !nvram_invmatch("lan_hostname", ""))
1391 return;
1393 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
1394 return;
1396 fprintf(fp, "[global]\n"
1397 " interfaces = %s\n"
1398 " bind interfaces only = yes\n"
1399 " workgroup = %s\n"
1400 " netbios name = %s\n"
1401 " server string = %s\n"
1402 " guest account = nobody\n"
1403 " security = user\n"
1404 " %s\n"
1405 " guest ok = %s\n"
1406 " guest only = no\n"
1407 " browseable = yes\n"
1408 " syslog only = yes\n"
1409 " timestamp logs = no\n"
1410 " syslog = 1\n"
1411 " encrypt passwords = yes\n"
1412 " preserve case = yes\n"
1413 " short preserve case = yes\n",
1414 nvram_safe_get("lan_ifname"),
1415 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1416 nvram_safe_get("lan_hostname"),
1417 nvram_get("router_name") ? : "Tomato",
1418 mode == 2 ? "" : "map to guest = Bad User",
1419 mode == 2 ? "no" : "yes" // guest ok
1422 if (nvram_get_int("smbd_wins")) {
1423 nv = nvram_safe_get("wan_wins");
1424 if ((*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
1425 fprintf(fp, " wins support = yes\n");
1429 if (nvram_get_int("smbd_master")) {
1430 fprintf(fp,
1431 " domain master = yes\n"
1432 " local master = yes\n"
1433 " preferred master = yes\n"
1434 " os level = 65\n");
1437 nv = nvram_safe_get("smbd_cpage");
1438 if (*nv) {
1439 #ifndef TCONFIG_SAMBA3
1440 fprintf(fp, " client code page = %s\n", nv);
1441 #endif
1442 sprintf(nlsmod, "nls_cp%s", nv);
1444 nv = nvram_safe_get("smbd_nlsmod");
1445 if ((*nv) && (strcmp(nv, nlsmod) != 0))
1446 modprobe_r(nv);
1448 modprobe(nlsmod);
1449 nvram_set("smbd_nlsmod", nlsmod);
1452 #ifndef TCONFIG_SAMBA3
1453 if (nvram_match("smbd_cset", "utf8"))
1454 fprintf(fp, " coding system = utf8\n");
1455 else if (nvram_invmatch("smbd_cset", ""))
1456 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1457 #endif
1459 nv = nvram_safe_get("smbd_custom");
1460 /* add socket options unless overriden by the user */
1461 if (strstr(nv, "socket options") == NULL) {
1462 fprintf(fp, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1464 fprintf(fp, "%s\n\n", nv);
1466 /* configure shares */
1468 char *buf;
1469 char *p, *q;
1470 char *name, *path, *comment, *writeable, *hidden;
1471 int cnt = 0;
1473 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1475 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1477 p = buf;
1478 while ((q = strsep(&p, ">")) != NULL) {
1479 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1480 if (!path || !name) continue;
1482 /* share name */
1483 fprintf(fp, "\n[%s]\n", name);
1485 /* path */
1486 fprintf(fp, " path = %s\n", path);
1488 /* access level */
1489 if (!strcmp(writeable, "1"))
1490 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1491 if (!strcmp(hidden, "1"))
1492 fprintf(fp, " browseable = no\n");
1494 /* comment */
1495 if (comment)
1496 fprintf(fp, " comment = %s\n", comment);
1498 cnt++;
1500 free(buf);
1503 /* Share every mountpoint below MOUNT_ROOT */
1504 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1505 while ((dp = readdir(dir))) {
1506 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1508 /* Only if is a directory and is mounted */
1509 if (!dir_is_mountpoint(MOUNT_ROOT, dp->d_name))
1510 continue;
1512 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1513 fprintf(fp, "\n[%s]\n path = %s/%s\n comment = %s\n",
1514 dp->d_name, MOUNT_ROOT, dp->d_name, dp->d_name);
1515 if (nvram_match("smbd_autoshare", "3")) // Hidden
1516 fprintf(fp, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1517 dp->d_name, MOUNT_ROOT, dp->d_name);
1518 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1519 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1521 cnt++;
1525 if (dir) closedir(dir);
1527 if (cnt == 0) {
1528 /* by default share MOUNT_ROOT as read-only */
1529 fprintf(fp, "\n[share]\n"
1530 " path = %s\n"
1531 " writable = no\n",
1532 MOUNT_ROOT);
1535 fclose(fp);
1537 mkdir_if_none("/var/run/samba");
1538 mkdir_if_none("/etc/samba");
1540 /* write smbpasswd */
1541 #ifdef TCONFIG_SAMBA3
1542 eval("smbpasswd", "nobody", "\"\"");
1543 #else
1544 eval("smbpasswd", "-a", "nobody", "\"\"");
1545 #endif
1546 if (mode == 2) {
1547 char *smbd_user;
1548 if (((smbd_user = nvram_get("smbd_user")) == NULL) || (*smbd_user == 0) || !strcmp(smbd_user, "root"))
1549 smbd_user = "nas";
1550 #ifdef TCONFIG_SAMBA3
1551 eval("smbpasswd", smbd_user, nvram_safe_get("smbd_passwd"));
1552 #else
1553 eval("smbpasswd", "-a", smbd_user, nvram_safe_get("smbd_passwd"));
1554 #endif
1557 kill_samba(SIGHUP);
1558 int ret1 = 0, ret2 = 0;
1559 /* start samba if it's not already running */
1560 if (pidof("nmbd") <= 0)
1561 ret1 = xstart("nmbd", "-D");
1562 if (pidof("smbd") <= 0)
1563 ret2 = xstart("smbd", "-D");
1565 if (ret1 || ret2) kill_samba(SIGTERM);
1568 static void stop_samba(void)
1570 if (getpid() != 1) {
1571 stop_service("smbd");
1572 return;
1575 kill_samba(SIGTERM);
1576 /* clean up */
1577 unlink("/var/log/smb");
1578 unlink("/var/log/nmb");
1579 eval("rm", "-rf", "/var/run/samba");
1581 #endif // TCONFIG_SAMBASRV
1583 #ifdef TCONFIG_MEDIA_SERVER
1584 #define MEDIA_SERVER_APP "minidlna"
1586 static void start_media_server(void)
1588 FILE *f;
1589 int port, pid, https;
1590 char *dbdir;
1591 char *argv[] = { MEDIA_SERVER_APP, "-f", "/etc/"MEDIA_SERVER_APP".conf", "-R", NULL };
1592 static int once = 1;
1594 if (getpid() != 1) {
1595 start_service("media");
1596 return;
1599 if (nvram_get_int("ms_sas") == 0)
1600 once = 0;
1602 if (nvram_get_int("ms_enable") != 0) {
1603 if ((!once) && (nvram_get_int("ms_rescan") == 0)) {
1604 // no forced rescan
1605 argv[3] = NULL;
1607 nvram_unset("ms_rescan");
1609 if (f_exists("/etc/"MEDIA_SERVER_APP".alt")) {
1610 argv[2] = "/etc/"MEDIA_SERVER_APP".alt";
1612 else {
1613 if ((f = fopen(argv[2], "w")) != NULL) {
1614 port = nvram_get_int("ms_port");
1615 https = nvram_get_int("https_enable");
1616 dbdir = nvram_safe_get("ms_dbdir");
1617 if (!(*dbdir)) dbdir = NULL;
1618 mkdir_if_none(dbdir ? : "/var/run/"MEDIA_SERVER_APP);
1620 fprintf(f,
1621 "network_interface=%s\n"
1622 "port=%d\n"
1623 "friendly_name=%s\n"
1624 "db_dir=%s/.db\n"
1625 "enable_tivo=%s\n"
1626 "strict_dlna=%s\n"
1627 "presentation_url=http%s://%s:%s/nas-media.asp\n"
1628 "inotify=yes\n"
1629 "notify_interval=600\n"
1630 "album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg/AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg/Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg\n"
1631 "\n",
1632 nvram_safe_get("lan_ifname"),
1633 (port < 0) || (port >= 0xffff) ? 0 : port,
1634 nvram_get("router_name") ? : "Tomato",
1635 dbdir ? : "/var/run/"MEDIA_SERVER_APP,
1636 nvram_get_int("ms_tivo") ? "yes" : "no",
1637 nvram_get_int("ms_stdlna") ? "yes" : "no",
1638 https ? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https ? "https_lanport" : "http_lanport")
1641 // media directories
1642 char *buf, *p, *q;
1643 char *path, *restrict;
1645 if ((buf = strdup(nvram_safe_get("ms_dirs"))) != NULL) {
1646 /* path<restrict[A|V|P|] */
1648 p = buf;
1649 while ((q = strsep(&p, ">")) != NULL) {
1650 if (vstrsep(q, "<", &path, &restrict) < 1 || !path || !(*path))
1651 continue;
1652 fprintf(f, "media_dir=%s%s%s\n",
1653 restrict ? : "", (restrict && *restrict) ? "," : "", path);
1655 free(buf);
1658 fclose(f);
1662 /* start media server if it's not already running */
1663 if (pidof(MEDIA_SERVER_APP) <= 0) {
1664 if ((_eval(argv, NULL, 0, &pid) == 0) && (once)) {
1665 /* If we started the media server successfully, wait 1 sec
1666 * to let it die if it can't open the database file.
1667 * If it's still alive after that, assume it's running and
1668 * disable forced once-after-reboot rescan.
1670 sleep(1);
1671 if (pidof(MEDIA_SERVER_APP) > 0)
1672 once = 0;
1678 static void stop_media_server(void)
1680 if (getpid() != 1) {
1681 stop_service("media");
1682 return;
1685 killall_tk(MEDIA_SERVER_APP);
1687 #endif // TCONFIG_MEDIA_SERVER
1689 #ifdef TCONFIG_USB
1690 static void start_nas_services(void)
1692 if (getpid() != 1) {
1693 start_service("usbapps");
1694 return;
1697 #ifdef TCONFIG_SAMBASRV
1698 start_samba();
1699 #endif
1700 #ifdef TCONFIG_FTP
1701 start_ftpd();
1702 #endif
1703 #ifdef TCONFIG_MEDIA_SERVER
1704 start_media_server();
1705 #endif
1708 static void stop_nas_services(void)
1710 if (getpid() != 1) {
1711 stop_service("usbapps");
1712 return;
1715 #ifdef TCONFIG_MEDIA_SERVER
1716 stop_media_server();
1717 #endif
1718 #ifdef TCONFIG_FTP
1719 stop_ftpd();
1720 #endif
1721 #ifdef TCONFIG_SAMBASRV
1722 stop_samba();
1723 #endif
1726 void restart_nas_services(int stop, int start)
1728 int fd = file_lock("usb");
1729 /* restart all NAS applications */
1730 if (stop)
1731 stop_nas_services();
1732 if (start)
1733 start_nas_services();
1734 file_unlock(fd);
1736 #endif // TCONFIG_USB
1738 // -----------------------------------------------------------------------------
1740 /* -1 = Don't check for this program, it is not expected to be running.
1741 * Other = This program has been started and should be kept running. If no
1742 * process with the name is running, call func to restart it.
1743 * Note: At startup, dnsmasq forks a short-lived child which forks a
1744 * long-lived (grand)child. The parents terminate.
1745 * Many daemons use this technique.
1747 static void _check(pid_t pid, const char *name, void (*func)(void))
1749 if (pid == -1) return;
1751 if (pidof(name) > 0) return;
1753 syslog(LOG_DEBUG, "%s terminated unexpectedly, restarting.\n", name);
1754 func();
1756 // Force recheck in 500 msec
1757 setitimer(ITIMER_REAL, &pop_tv, NULL);
1760 void check_services(void)
1762 TRACE_PT("keep alive\n");
1764 // Periodically reap any zombies
1765 setitimer(ITIMER_REAL, &zombie_tv, NULL);
1767 #ifdef LINUX26
1768 _check(pid_hotplug2, "hotplug2", start_hotplug2);
1769 #endif
1770 _check(pid_dnsmasq, "dnsmasq", start_dnsmasq);
1771 _check(pid_crond, "crond", start_cron);
1772 _check(pid_igmp, "igmpproxy", start_igmp_proxy);
1773 #ifdef TCONFIG_IPV6
1774 _check(pid_radvd, "radvd", start_radvd);
1775 #endif
1777 //#ifdef TCONFIG_NOCAT
1778 // if (nvram_get_int("NC_enable"))
1779 // _check(&pid_splashd, "splashd", start_splashd);
1780 //#endif
1784 // -----------------------------------------------------------------------------
1786 void start_services(void)
1788 static int once = 1;
1790 if (once) {
1791 once = 0;
1793 if (nvram_get_int("telnetd_eas")) start_telnetd();
1794 if (nvram_get_int("sshd_eas")) start_sshd();
1797 // start_syslog();
1798 start_nas();
1799 start_zebra();
1800 start_dnsmasq();
1801 start_cifs();
1802 start_httpd();
1803 start_cron();
1804 // start_upnp();
1805 start_rstats(0);
1806 start_sched();
1807 #ifdef TCONFIG_IPV6
1808 /* note: starting radvd here might be too early in case of
1809 * DHCPv6 or 6to4 because we won't have received a prefix and
1810 * so it will disable advertisements. To restart them, we have
1811 * to send radvd a SIGHUP, or restart it.
1813 start_radvd();
1814 #endif
1815 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
1817 #ifdef TCONFIG_SNMP
1818 start_snmp();
1819 #endif
1821 #ifdef TCONFIG_BT
1822 start_bittorrent();
1823 #endif
1825 #ifdef TCONFIG_NFS
1826 start_nfs();
1827 #endif
1830 void stop_services(void)
1832 clear_resolv();
1834 #ifdef TCONFIG_BT
1835 stop_bittorrent();
1836 #endif
1838 #ifdef TCONFIG_SNMP
1839 stop_snmp();
1840 #endif
1842 #ifdef TCONFIG_NFS
1843 stop_nfs();
1844 #endif
1845 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
1846 #ifdef TCONFIG_IPV6
1847 stop_radvd();
1848 #endif
1849 stop_sched();
1850 stop_rstats();
1851 // stop_upnp();
1852 stop_cron();
1853 stop_httpd();
1854 stop_cifs();
1855 stop_dnsmasq();
1856 stop_zebra();
1857 stop_nas();
1858 // stop_syslog();
1861 // -----------------------------------------------------------------------------
1863 /* nvram "action_service" is: "service-action[-modifier]"
1864 * action is something like "stop" or "start" or "restart"
1865 * optional modifier is "c" for the "service" command-line command
1867 void exec_service(void)
1869 const int A_START = 1;
1870 const int A_STOP = 2;
1871 const int A_RESTART = 1|2;
1872 char buffer[128];
1873 char *service;
1874 char *act;
1875 char *next;
1876 char *modifier;
1877 int action, user;
1878 int i;
1880 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
1881 next = buffer;
1883 TOP:
1884 act = strsep(&next, ",");
1885 service = strsep(&act, "-");
1886 if (act == NULL) {
1887 next = NULL;
1888 goto CLEAR;
1890 modifier = act;
1891 strsep(&modifier, "-");
1893 TRACE_PT("service=%s action=%s modifier=%s\n", service, act, modifier ? : "");
1895 if (strcmp(act, "start") == 0) action = A_START;
1896 else if (strcmp(act, "stop") == 0) action = A_STOP;
1897 else if (strcmp(act, "restart") == 0) action = A_RESTART;
1898 else action = 0;
1899 user = (modifier != NULL && *modifier == 'c');
1901 if (strcmp(service, "dhcpc") == 0) {
1902 if (action & A_STOP) stop_dhcpc();
1903 if (action & A_START) start_dhcpc();
1904 goto CLEAR;
1907 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
1908 if (action & A_STOP) stop_dnsmasq();
1909 if (action & A_START) {
1910 dns_to_resolv();
1911 start_dnsmasq();
1913 goto CLEAR;
1916 if (strcmp(service, "firewall") == 0) {
1917 if (action & A_STOP) {
1918 stop_firewall();
1919 stop_igmp_proxy();
1921 if (action & A_START) {
1922 start_firewall();
1923 start_igmp_proxy();
1925 goto CLEAR;
1928 if (strcmp(service, "restrict") == 0) {
1929 if (action & A_STOP) {
1930 stop_firewall();
1932 if (action & A_START) {
1933 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
1935 start_firewall();
1937 // if radio was disabled by access restriction, but no rule is handling it now, enable it
1938 if (i == 1) {
1939 if (nvram_get_int("rrules_radio") < 0) {
1940 eval("radio", "on");
1944 goto CLEAR;
1947 if (strcmp(service, "qos") == 0) {
1948 if (action & A_STOP) {
1949 stop_qos();
1951 stop_firewall(); start_firewall(); // always restarted
1952 if (action & A_START) {
1953 #ifdef TCONFIG_CMON
1954 start_cmon(); // cmon start also qos
1955 #else
1956 start_qos();
1957 #endif
1958 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
1960 goto CLEAR;
1963 if (strcmp(service, "qoslimit") == 0) {
1964 if (action & A_STOP) {
1965 new_qoslimit_stop();
1967 stop_firewall(); start_firewall(); // always restarted
1968 if (action & A_START) {
1969 #ifdef TCONFIG_CMON
1970 start_cmon(); //cmon start also qoslimit
1971 #else
1972 new_qoslimit_start();
1973 #endif
1975 goto CLEAR;
1978 if (strcmp(service, "arpbind") == 0) {
1979 if (action & A_STOP) new_arpbind_stop();
1980 if (action & A_START) new_arpbind_start();
1981 goto CLEAR;
1984 #ifdef TCONFIG_CMON
1985 if (strcmp(service, "cmon") == 0) {
1986 if (action & A_STOP) { stop_cmon(); }
1988 start_qos(); new_qoslimit_start(); // start features after firewall restart
1990 if (action & A_START) { start_cmon(); }
1991 goto CLEAR;
1993 #endif
1995 if (strcmp(service, "upnp") == 0) {
1996 if (action & A_STOP) {
1997 stop_upnp();
1999 stop_firewall(); start_firewall(); // always restarted
2000 if (action & A_START) {
2001 start_upnp();
2003 goto CLEAR;
2006 if (strcmp(service, "telnetd") == 0) {
2007 if (action & A_STOP) stop_telnetd();
2008 if (action & A_START) start_telnetd();
2009 goto CLEAR;
2012 if (strcmp(service, "sshd") == 0) {
2013 if (action & A_STOP) stop_sshd();
2014 if (action & A_START) start_sshd();
2015 goto CLEAR;
2018 if (strcmp(service, "httpd") == 0) {
2019 if (action & A_STOP) stop_httpd();
2020 if (action & A_START) start_httpd();
2021 goto CLEAR;
2024 #ifdef TCONFIG_IPV6
2025 if (strcmp(service, "ipv6") == 0) {
2026 if (action & A_STOP) {
2027 stop_radvd();
2028 stop_ipv6();
2030 if (action & A_START) {
2031 start_ipv6();
2032 start_radvd();
2034 goto CLEAR;
2037 if (strcmp(service, "radvd") == 0) {
2038 if (action & A_STOP) {
2039 stop_radvd();
2041 if (action & A_START) {
2042 start_radvd();
2044 goto CLEAR;
2047 if (strncmp(service, "dhcp6", 5) == 0) {
2048 if (action & A_STOP) {
2049 stop_dhcp6c();
2051 if (action & A_START) {
2052 start_dhcp6c();
2054 goto CLEAR;
2056 #endif
2058 if (strcmp(service, "admin") == 0) {
2059 if (action & A_STOP) {
2060 stop_sshd();
2061 stop_telnetd();
2062 stop_httpd();
2064 stop_firewall(); start_firewall(); // always restarted
2065 if (action & A_START) {
2066 start_httpd();
2067 create_passwd();
2068 if (nvram_match("telnetd_eas", "1")) start_telnetd();
2069 if (nvram_match("sshd_eas", "1")) start_sshd();
2071 goto CLEAR;
2074 if (strcmp(service, "ddns") == 0) {
2075 if (action & A_STOP) stop_ddns();
2076 if (action & A_START) start_ddns();
2077 goto CLEAR;
2080 if (strcmp(service, "ntpc") == 0) {
2081 if (action & A_STOP) stop_ntpc();
2082 if (action & A_START) start_ntpc();
2083 goto CLEAR;
2086 if (strcmp(service, "logging") == 0) {
2087 if (action & A_STOP) {
2088 stop_syslog();
2090 if (action & A_START) {
2091 start_syslog();
2093 if (!user) {
2094 // always restarted except from "service" command
2095 stop_cron(); start_cron();
2096 stop_firewall(); start_firewall();
2098 goto CLEAR;
2101 if (strcmp(service, "crond") == 0) {
2102 if (action & A_STOP) {
2103 stop_cron();
2105 if (action & A_START) {
2106 start_cron();
2108 goto CLEAR;
2111 #ifdef LINUX26
2112 if (strncmp(service, "hotplug", 7) == 0) {
2113 if (action & A_STOP) {
2114 stop_hotplug2();
2116 if (action & A_START) {
2117 start_hotplug2(1);
2119 goto CLEAR;
2121 #endif
2123 if (strcmp(service, "upgrade") == 0) {
2124 if (action & A_START) {
2125 #if TOMATO_SL
2126 stop_usbevent();
2127 stop_smbd();
2128 #endif
2129 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2130 stop_jffs2();
2131 // stop_cifs();
2132 stop_zebra();
2133 stop_cron();
2134 stop_ntpc();
2135 stop_upnp();
2136 // stop_dhcpc();
2137 killall("rstats", SIGTERM);
2138 killall("buttons", SIGTERM);
2139 stop_syslog();
2140 remove_storage_main(1); // !!TB - USB Support
2141 stop_usb(); // !!TB - USB Support
2143 goto CLEAR;
2146 #ifdef TCONFIG_CIFS
2147 if (strcmp(service, "cifs") == 0) {
2148 if (action & A_STOP) stop_cifs();
2149 if (action & A_START) start_cifs();
2150 goto CLEAR;
2152 #endif
2154 #ifdef TCONFIG_JFFS2
2155 if (strncmp(service, "jffs", 4) == 0) {
2156 if (action & A_STOP) stop_jffs2();
2157 if (action & A_START) start_jffs2();
2158 goto CLEAR;
2160 #endif
2162 if (strcmp(service, "zebra") == 0) {
2163 if (action & A_STOP) stop_zebra();
2164 if (action & A_START) start_zebra();
2165 goto CLEAR;
2168 if (strcmp(service, "routing") == 0) {
2169 if (action & A_STOP) {
2170 stop_zebra();
2171 do_static_routes(0); // remove old '_saved'
2172 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2174 stop_firewall();
2175 start_firewall();
2176 if (action & A_START) {
2177 do_static_routes(1); // add new
2178 start_zebra();
2179 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2181 goto CLEAR;
2184 if (strcmp(service, "ctnf") == 0) {
2185 if (action & A_START) {
2186 setup_conntrack();
2187 stop_firewall();
2188 start_firewall();
2190 goto CLEAR;
2193 if (strcmp(service, "wan") == 0) {
2194 if (action & A_STOP) {
2195 stop_wan();
2198 if (action & A_START) {
2199 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2200 start_wan(BOOT);
2201 sleep(2);
2202 force_to_dial();
2204 goto CLEAR;
2207 if (strcmp(service, "net") == 0) {
2208 if (action & A_STOP) {
2209 #ifdef TCONFIG_USB
2210 stop_nas_services();
2211 #endif
2212 #ifdef TCONFIG_IPV6
2213 stop_radvd();
2214 #endif
2215 stop_httpd();
2216 stop_dnsmasq();
2217 stop_nas();
2218 stop_wan();
2219 stop_lan();
2220 stop_vlan();
2222 if (action & A_START) {
2223 start_vlan();
2224 start_lan();
2225 start_wan(BOOT);
2226 start_nas();
2227 start_dnsmasq();
2228 start_httpd();
2229 #ifdef TCONFIG_IPV6
2230 start_radvd();
2231 #endif
2232 start_wl();
2233 #ifdef TCONFIG_USB
2234 start_nas_services();
2235 #endif
2237 goto CLEAR;
2240 if (strcmp(service, "nas") == 0) {
2241 if (action & A_STOP) {
2242 stop_nas();
2244 if (action & A_START) {
2245 start_nas();
2246 start_wl();
2248 goto CLEAR;
2251 if (strcmp(service, "rstats") == 0) {
2252 if (action & A_STOP) stop_rstats();
2253 if (action & A_START) start_rstats(0);
2254 goto CLEAR;
2257 if (strcmp(service, "rstatsnew") == 0) {
2258 if (action & A_STOP) stop_rstats();
2259 if (action & A_START) start_rstats(1);
2260 goto CLEAR;
2263 if (strcmp(service, "sched") == 0) {
2264 if (action & A_STOP) stop_sched();
2265 if (action & A_START) start_sched();
2266 goto CLEAR;
2269 #ifdef TCONFIG_BT
2270 if (strcmp(service, "bittorrent") == 0) {
2271 if (action & A_STOP) {
2272 stop_bittorrent();
2274 stop_firewall(); start_firewall(); // always restarted
2275 if (action & A_START) {
2276 start_bittorrent();
2278 goto CLEAR;
2280 #endif
2282 #ifdef TCONFIG_NFS
2283 if (strcmp(service, "nfs") == 0) {
2284 if (action & A_STOP) stop_nfs();
2285 if (action & A_START) start_nfs();
2286 goto CLEAR;
2288 #endif
2290 #ifdef TCONFIG_SNMP
2291 if (strcmp(service, "snmp") == 0) {
2292 if (action & A_STOP) stop_snmp();
2293 if (action & A_START) start_snmp();
2294 goto CLEAR;
2296 #endif
2298 #ifdef TCONFIG_USB
2299 // !!TB - USB Support
2300 if (strcmp(service, "usb") == 0) {
2301 if (action & A_STOP) stop_usb();
2302 if (action & A_START) {
2303 start_usb();
2304 // restart Samba and ftp since they may be killed by stop_usb()
2305 restart_nas_services(0, 1);
2306 // remount all partitions by simulating hotplug event
2307 add_remove_usbhost("-1", 1);
2309 goto CLEAR;
2312 if (strcmp(service, "usbapps") == 0) {
2313 if (action & A_STOP) stop_nas_services();
2314 if (action & A_START) start_nas_services();
2315 goto CLEAR;
2317 #endif
2319 #ifdef TCONFIG_FTP
2320 // !!TB - FTP Server
2321 if (strcmp(service, "ftpd") == 0) {
2322 if (action & A_STOP) stop_ftpd();
2323 setup_conntrack();
2324 stop_firewall();
2325 start_firewall();
2326 if (action & A_START) start_ftpd();
2327 goto CLEAR;
2329 #endif
2331 #ifdef TCONFIG_MEDIA_SERVER
2332 if (strcmp(service, "media") == 0 || strcmp(service, "dlna") == 0) {
2333 if (action & A_STOP) stop_media_server();
2334 if (action & A_START) start_media_server();
2335 goto CLEAR;
2337 #endif
2339 #ifdef TCONFIG_SAMBASRV
2340 // !!TB - Samba
2341 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
2342 if (action & A_STOP) stop_samba();
2343 if (action & A_START) {
2344 create_passwd();
2345 stop_dnsmasq();
2346 start_dnsmasq();
2347 start_samba();
2349 goto CLEAR;
2351 #endif
2353 #ifdef TCONFIG_OPENVPN
2354 if (strncmp(service, "vpnclient", 9) == 0) {
2355 if (action & A_STOP) stop_vpnclient(atoi(&service[9]));
2356 if (action & A_START) start_vpnclient(atoi(&service[9]));
2357 goto CLEAR;
2360 if (strncmp(service, "vpnserver", 9) == 0) {
2361 if (action & A_STOP) stop_vpnserver(atoi(&service[9]));
2362 if (action & A_START) start_vpnserver(atoi(&service[9]));
2363 goto CLEAR;
2365 #endif
2367 #ifdef TCONFIG_NOCAT
2368 if (strcmp(service, "splashd") == 0) {
2369 if (action & A_STOP) stop_splashd();
2370 if (action & A_START) start_splashd();
2371 goto CLEAR;
2373 #endif
2375 CLEAR:
2376 if (next) goto TOP;
2378 // some functions check action_service and must be cleared at end -- zzz
2379 nvram_set("action_service", "");
2381 // Force recheck in 500 msec
2382 setitimer(ITIMER_REAL, &pop_tv, NULL);
2385 static void do_service(const char *name, const char *action, int user)
2387 int n;
2388 char s[64];
2390 n = 150;
2391 while (!nvram_match("action_service", "")) {
2392 if (user) {
2393 putchar('*');
2394 fflush(stdout);
2396 else if (--n < 0) break;
2397 usleep(100 * 1000);
2400 snprintf(s, sizeof(s), "%s-%s%s", name, action, (user ? "-c" : ""));
2401 nvram_set("action_service", s);
2402 kill(1, SIGUSR1);
2404 n = 150;
2405 while (nvram_match("action_service", s)) {
2406 if (user) {
2407 putchar('.');
2408 fflush(stdout);
2410 else if (--n < 0) {
2411 break;
2413 usleep(100 * 1000);
2417 int service_main(int argc, char *argv[])
2419 if (argc != 3) usage_exit(argv[0], "<service> <action>");
2420 do_service(argv[1], argv[2], 1);
2421 printf("\nDone.\n");
2422 return 0;
2425 void start_service(const char *name)
2427 do_service(name, "start", 0);
2430 void stop_service(const char *name)
2432 do_service(name, "stop", 0);
2436 void restart_service(const char *name)
2438 do_service(name, "restart", 0);