rc: fix resolving IP addresses when not using Dnsmasq
[tomato.git] / release / src / router / rc / services.c
blob62672fc774cc8aa664b5025f6998a48ab65b49bc
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, "/jffs/upnpconfig.custom");
755 fappend(f, "/etc/upnp/config.custom");
756 fprintf(f, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
757 fclose(f);
759 xstart("miniupnpd", "-f", "/etc/upnp/config");
765 void stop_upnp(void)
767 if (getpid() != 1) {
768 stop_service("upnp");
769 return;
772 killall_tk("miniupnpd");
775 // -----------------------------------------------------------------------------
777 static pid_t pid_crond = -1;
779 void start_cron(void)
781 stop_cron();
783 eval("crond", nvram_contains_word("log_events", "crond") ? NULL : "-l", "9");
784 if (!nvram_contains_word("debug_norestart", "crond")) {
785 pid_crond = -2;
789 void stop_cron(void)
791 pid_crond = -1;
792 killall_tk("crond");
795 // -----------------------------------------------------------------------------
796 #ifdef LINUX26
798 static pid_t pid_hotplug2 = -1;
800 void start_hotplug2()
802 stop_hotplug2();
804 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE, 0);
805 xstart("hotplug2", "--persistent", "--no-coldplug");
806 // FIXME: Don't remember exactly why I put "sleep" here -
807 // but it was not for a race with check_services()... - TB
808 sleep(1);
810 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
811 pid_hotplug2 = -2;
815 void stop_hotplug2(void)
817 pid_hotplug2 = -1;
818 killall_tk("hotplug2");
821 #endif /* LINUX26 */
822 // -----------------------------------------------------------------------------
824 // Written by Sparq in 2002/07/16
825 void start_zebra(void)
827 #ifdef TCONFIG_ZEBRA
828 if (getpid() != 1) {
829 start_service("zebra");
830 return;
833 FILE *fp;
835 char *lan_tx = nvram_safe_get("dr_lan_tx");
836 char *lan_rx = nvram_safe_get("dr_lan_rx");
837 char *wan_tx = nvram_safe_get("dr_wan_tx");
838 char *wan_rx = nvram_safe_get("dr_wan_rx");
840 if ((*lan_tx == '0') && (*lan_rx == '0') && (*wan_tx == '0') && (*wan_rx == '0')) {
841 return;
844 // empty
845 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
846 fclose(fp);
850 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
851 char *lan_ifname = nvram_safe_get("lan_ifname");
852 char *wan_ifname = nvram_safe_get("wan_ifname");
854 fprintf(fp, "router rip\n");
855 fprintf(fp, "network %s\n", lan_ifname);
856 fprintf(fp, "network %s\n", wan_ifname);
857 fprintf(fp, "redistribute connected\n");
858 //fprintf(fp, "redistribute static\n");
860 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
861 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
863 fprintf(fp, "interface %s\n", lan_ifname);
864 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
865 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
867 fprintf(fp, "interface %s\n", wan_ifname);
868 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
869 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
871 fprintf(fp, "router rip\n");
872 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
873 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
874 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
875 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
876 fprintf(fp, "access-list private deny any\n");
878 //fprintf(fp, "debug rip events\n");
879 //fprintf(fp, "log file /etc/ripd.log\n");
880 fclose(fp);
883 xstart("zebra", "-d");
884 xstart("ripd", "-d");
885 #endif
888 void stop_zebra(void)
890 #ifdef TCONFIG_ZEBRA
891 if (getpid() != 1) {
892 stop_service("zebra");
893 return;
896 killall("zebra", SIGTERM);
897 killall("ripd", SIGTERM);
899 unlink("/etc/zebra.conf");
900 unlink("/etc/ripd.conf");
901 #endif
904 // -----------------------------------------------------------------------------
906 void start_syslog(void)
908 char *argv[16];
909 int argc;
910 char *nv;
911 char *b_opt = "";
912 char rem[256];
913 int n;
914 char s[64];
915 char cfg[256];
916 char *rot_siz = "50";
917 char *log_file_path;
919 argv[0] = "syslogd";
920 argc = 1;
922 if (nvram_match("log_remote", "1")) {
923 nv = nvram_safe_get("log_remoteip");
924 if (*nv) {
925 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
926 argv[argc++] = "-R";
927 argv[argc++] = rem;
931 if (nvram_match("log_file", "1")) {
932 argv[argc++] = "-L";
934 // log to custom path - shibby
935 if (nvram_match("log_file_custom", "1")) {
936 log_file_path = nvram_safe_get("log_file_path");
937 argv[argc++] = "-s";
938 argv[argc++] = "5000";
939 argv[argc++] = "-b";
940 argv[argc++] = "5";
941 argv[argc++] = "-O";
942 argv[argc++] = log_file_path;
943 remove("/var/log/messages");
944 symlink(log_file_path, "/var/log/messages");
946 else
948 /* Read options: rotate_size(kb) num_backups logfilename.
949 * Ignore these settings and use defaults if the logfile cannot be written to.
951 if (f_read_string("/etc/syslogd.cfg", cfg, sizeof(cfg)) > 0) {
952 if ((nv = strchr(cfg, '\n')))
953 *nv = 0;
955 if ((nv = strtok(cfg, " \t"))) {
956 if (isdigit(*nv))
957 rot_siz = nv;
960 if ((nv = strtok(NULL, " \t")))
961 b_opt = nv;
963 if ((nv = strtok(NULL, " \t")) && *nv == '/') {
964 if (f_write(nv, cfg, 0, FW_APPEND, 0) >= 0) {
965 argv[argc++] = "-O";
966 argv[argc++] = nv;
968 else {
969 rot_siz = "50";
970 b_opt = "";
975 if (nvram_match("log_file_custom", "0")) {
976 argv[argc++] = "-s";
977 argv[argc++] = rot_siz;
978 remove("/var/log/messages");
982 if (isdigit(*b_opt)) {
983 argv[argc++] = "-b";
984 argv[argc++] = b_opt;
988 if (argc > 1) {
989 argv[argc] = NULL;
990 _eval(argv, NULL, 0, NULL);
992 argv[0] = "klogd";
993 argv[1] = NULL;
994 _eval(argv, NULL, 0, NULL);
996 // used to be available in syslogd -m
997 n = nvram_get_int("log_mark");
998 if (n > 0) {
999 // n is in minutes
1000 if (n < 60)
1001 sprintf(rem, "*/%d * * * *", n);
1002 else if (n < 60 * 24)
1003 sprintf(rem, "0 */%d * * *", n / 60);
1004 else
1005 sprintf(rem, "0 0 */%d * *", n / (60 * 24));
1006 sprintf(s, "%s logger -p syslog.info -- -- MARK --", rem);
1007 eval("cru", "a", "syslogdmark", s);
1009 else {
1010 eval("cru", "d", "syslogdmark");
1015 void stop_syslog(void)
1017 killall("klogd", SIGTERM);
1018 killall("syslogd", SIGTERM);
1021 // -----------------------------------------------------------------------------
1023 static pid_t pid_igmp = -1;
1025 void start_igmp_proxy(void)
1027 FILE *fp;
1029 pid_igmp = -1;
1030 if (nvram_match("multicast_pass", "1")) {
1031 if (get_wan_proto() == WP_DISABLED)
1032 return;
1034 if (f_exists("/etc/igmp.alt")) {
1035 eval("igmpproxy", "/etc/igmp.alt");
1037 else if ((fp = fopen("/etc/igmp.conf", "w")) != NULL) {
1038 fprintf(fp,
1039 "quickleave\n"
1040 "phyint %s upstream\n"
1041 "\taltnet %s\n"
1042 "phyint %s downstream ratelimit 0\n",
1043 nvram_safe_get("wan_ifname"),
1044 nvram_get("multicast_altnet") ? : "0.0.0.0/0",
1045 nvram_safe_get("lan_ifname"));
1046 fclose(fp);
1047 eval("igmpproxy", "/etc/igmp.conf");
1049 else {
1050 return;
1052 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1053 pid_igmp = -2;
1058 void stop_igmp_proxy(void)
1060 pid_igmp = -1;
1061 killall_tk("igmpproxy");
1065 // -----------------------------------------------------------------------------
1067 void set_tz(void)
1069 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
1072 void start_ntpc(void)
1074 set_tz();
1076 stop_ntpc();
1078 if (nvram_get_int("ntp_updates") >= 0) {
1079 xstart("ntpsync", "--init");
1083 void stop_ntpc(void)
1085 killall("ntpsync", SIGTERM);
1088 // -----------------------------------------------------------------------------
1090 static void stop_rstats(void)
1092 int n;
1093 int pid;
1095 n = 60;
1096 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
1097 if (kill(pid, SIGTERM) != 0) break;
1098 sleep(1);
1102 static void start_rstats(int new)
1104 if (nvram_match("rstats_enable", "1")) {
1105 stop_rstats();
1106 if (new) xstart("rstats", "--new");
1107 else xstart("rstats");
1111 // -----------------------------------------------------------------------------
1113 // !!TB - FTP Server
1115 #ifdef TCONFIG_FTP
1116 static char *get_full_storage_path(char *val)
1118 static char buf[128];
1119 int len;
1121 if (val[0] == '/')
1122 len = sprintf(buf, "%s", val);
1123 else
1124 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
1126 if (len > 1 && buf[len - 1] == '/')
1127 buf[len - 1] = 0;
1129 return buf;
1132 static char *nvram_storage_path(char *var)
1134 char *val = nvram_safe_get(var);
1135 return get_full_storage_path(val);
1138 char vsftpd_conf[] = "/etc/vsftpd.conf";
1139 char vsftpd_users[] = "/etc/vsftpd.users";
1140 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
1142 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1144 static void start_ftpd(void)
1146 char tmp[256];
1147 FILE *fp, *f;
1148 char *buf;
1149 char *p, *q;
1150 char *user, *pass, *rights;
1152 if (getpid() != 1) {
1153 start_service("ftpd");
1154 return;
1157 if (!nvram_get_int("ftp_enable")) return;
1159 mkdir_if_none(vsftpd_users);
1160 mkdir_if_none("/var/run/vsftpd");
1162 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
1163 return;
1165 if (nvram_get_int("ftp_super"))
1167 /* rights */
1168 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
1169 if ((f = fopen(tmp, "w")))
1171 fprintf(f,
1172 "dirlist_enable=yes\n"
1173 "write_enable=yes\n"
1174 "download_enable=yes\n");
1175 fclose(f);
1179 #ifdef TCONFIG_SAMBASRV
1180 if (nvram_match("smbd_cset", "utf8"))
1181 fprintf(fp, "utf8=yes\n");
1182 #endif
1184 if (nvram_invmatch("ftp_anonymous", "0"))
1186 fprintf(fp,
1187 "anon_allow_writable_root=yes\n"
1188 "anon_world_readable_only=no\n"
1189 "anon_umask=022\n");
1191 /* rights */
1192 sprintf(tmp, "%s/ftp", vsftpd_users);
1193 if ((f = fopen(tmp, "w")))
1195 if (nvram_match("ftp_dirlist", "0"))
1196 fprintf(f, "dirlist_enable=yes\n");
1197 if (nvram_match("ftp_anonymous", "1") ||
1198 nvram_match("ftp_anonymous", "3"))
1199 fprintf(f, "write_enable=yes\n");
1200 if (nvram_match("ftp_anonymous", "1") ||
1201 nvram_match("ftp_anonymous", "2"))
1202 fprintf(f, "download_enable=yes\n");
1203 fclose(f);
1205 if (nvram_match("ftp_anonymous", "1") ||
1206 nvram_match("ftp_anonymous", "3"))
1207 fprintf(fp,
1208 "anon_upload_enable=yes\n"
1209 "anon_mkdir_write_enable=yes\n"
1210 "anon_other_write_enable=yes\n");
1211 } else {
1212 fprintf(fp, "anonymous_enable=no\n");
1215 fprintf(fp,
1216 "dirmessage_enable=yes\n"
1217 "download_enable=no\n"
1218 "dirlist_enable=no\n"
1219 "hide_ids=yes\n"
1220 "syslog_enable=yes\n"
1221 "local_enable=yes\n"
1222 "local_umask=022\n"
1223 "chmod_enable=no\n"
1224 "chroot_local_user=yes\n"
1225 "check_shell=no\n"
1226 "log_ftp_protocol=%s\n"
1227 "user_config_dir=%s\n"
1228 "passwd_file=%s\n"
1229 "listen%s=yes\n"
1230 "listen_port=%s\n"
1231 "background=yes\n"
1232 "isolate=no\n"
1233 "max_clients=%d\n"
1234 "max_per_ip=%d\n"
1235 "max_login_fails=1\n"
1236 "idle_session_timeout=%s\n"
1237 "use_sendfile=no\n"
1238 "anon_max_rate=%d\n"
1239 "local_max_rate=%d\n"
1240 "%s\n",
1241 nvram_get_int("log_ftp") ? "yes" : "no",
1242 vsftpd_users, vsftpd_passwd,
1243 #ifdef TCONFIG_IPV6
1244 ipv6_enabled() ? "_ipv6" : "",
1245 #else
1247 #endif
1248 nvram_get("ftp_port") ? : "21",
1249 nvram_get_int("ftp_max"),
1250 nvram_get_int("ftp_ipmax"),
1251 nvram_get("ftp_staytimeout") ? : "300",
1252 nvram_get_int("ftp_anonrate") * 1024,
1253 nvram_get_int("ftp_rate") * 1024,
1254 nvram_safe_get("ftp_custom"));
1256 fclose(fp);
1258 /* prepare passwd file and default users */
1259 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
1260 return;
1262 if (((user = nvram_get("http_username")) == NULL) || (*user == 0)) user = "admin";
1263 if (((pass = nvram_get("http_passwd")) == NULL) || (*pass == 0)) pass = "admin";
1265 fprintf(fp, /* anonymous, admin, nobody */
1266 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1267 "%s:%s:0:0:root:/:/sbin/nologin\n"
1268 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1269 nvram_storage_path("ftp_anonroot"), user,
1270 nvram_get_int("ftp_super") ? crypt(pass, "$1$") : "x",
1271 MOUNT_ROOT);
1273 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
1276 username<password<rights
1277 rights:
1278 Read/Write
1279 Read Only
1280 View Only
1281 Private
1283 p = buf;
1284 while ((q = strsep(&p, ">")) != NULL) {
1285 if (vstrsep(q, "<", &user, &pass, &rights) != 3) continue;
1286 if (!user || !pass) continue;
1288 /* directory */
1289 if (strncmp(rights, "Private", 7) == 0)
1291 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
1292 mkdir_if_none(tmp);
1294 else
1295 sprintf(tmp, "%s", nvram_storage_path("ftp_pubroot"));
1297 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1298 user, crypt(pass, "$1$"), user, tmp);
1300 /* rights */
1301 sprintf(tmp, "%s/%s", vsftpd_users, user);
1302 if ((f = fopen(tmp, "w")))
1304 tmp[0] = 0;
1305 if (nvram_invmatch("ftp_dirlist", "1"))
1306 strcat(tmp, "dirlist_enable=yes\n");
1307 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
1308 strcat(tmp, "download_enable=yes\n");
1309 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
1310 strcat(tmp, "write_enable=yes\n");
1312 fputs(tmp, f);
1313 fclose(f);
1316 free(buf);
1319 fclose(fp);
1320 killall("vsftpd", SIGHUP);
1322 /* start vsftpd if it's not already running */
1323 if (pidof("vsftpd") <= 0)
1324 xstart("vsftpd");
1327 static void stop_ftpd(void)
1329 if (getpid() != 1) {
1330 stop_service("ftpd");
1331 return;
1334 killall_tk("vsftpd");
1335 unlink(vsftpd_passwd);
1336 unlink(vsftpd_conf);
1337 eval("rm", "-rf", vsftpd_users);
1339 #endif // TCONFIG_FTP
1341 // -----------------------------------------------------------------------------
1343 // !!TB - Samba
1345 #ifdef TCONFIG_SAMBASRV
1346 static void kill_samba(int sig)
1348 if (sig == SIGTERM) {
1349 killall_tk("smbd");
1350 killall_tk("nmbd");
1352 else {
1353 killall("smbd", sig);
1354 killall("nmbd", sig);
1358 static void start_samba(void)
1360 FILE *fp;
1361 DIR *dir = NULL;
1362 struct dirent *dp;
1363 char nlsmod[15];
1364 int mode;
1365 char *nv;
1367 if (getpid() != 1) {
1368 start_service("smbd");
1369 return;
1372 mode = nvram_get_int("smbd_enable");
1373 if (!mode || !nvram_invmatch("lan_hostname", ""))
1374 return;
1376 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
1377 return;
1379 fprintf(fp, "[global]\n"
1380 " interfaces = %s\n"
1381 " bind interfaces only = yes\n"
1382 " workgroup = %s\n"
1383 " netbios name = %s\n"
1384 " server string = %s\n"
1385 " guest account = nobody\n"
1386 " security = user\n"
1387 " %s\n"
1388 " guest ok = %s\n"
1389 " guest only = no\n"
1390 " browseable = yes\n"
1391 " syslog only = yes\n"
1392 " timestamp logs = no\n"
1393 " syslog = 1\n"
1394 " encrypt passwords = yes\n"
1395 " preserve case = yes\n"
1396 " short preserve case = yes\n",
1397 nvram_safe_get("lan_ifname"),
1398 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1399 nvram_safe_get("lan_hostname"),
1400 nvram_get("router_name") ? : "Tomato",
1401 mode == 2 ? "" : "map to guest = Bad User",
1402 mode == 2 ? "no" : "yes" // guest ok
1405 if (nvram_get_int("smbd_wins")) {
1406 nv = nvram_safe_get("wan_wins");
1407 if ((*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
1408 fprintf(fp, " wins support = yes\n");
1412 if (nvram_get_int("smbd_master")) {
1413 fprintf(fp,
1414 " domain master = yes\n"
1415 " local master = yes\n"
1416 " preferred master = yes\n"
1417 " os level = 65\n");
1420 nv = nvram_safe_get("smbd_cpage");
1421 if (*nv) {
1422 #ifndef TCONFIG_SAMBA3
1423 fprintf(fp, " client code page = %s\n", nv);
1424 #endif
1425 sprintf(nlsmod, "nls_cp%s", nv);
1427 nv = nvram_safe_get("smbd_nlsmod");
1428 if ((*nv) && (strcmp(nv, nlsmod) != 0))
1429 modprobe_r(nv);
1431 modprobe(nlsmod);
1432 nvram_set("smbd_nlsmod", nlsmod);
1435 #ifndef TCONFIG_SAMBA3
1436 if (nvram_match("smbd_cset", "utf8"))
1437 fprintf(fp, " coding system = utf8\n");
1438 else if (nvram_invmatch("smbd_cset", ""))
1439 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1440 #endif
1442 nv = nvram_safe_get("smbd_custom");
1443 /* add socket options unless overriden by the user */
1444 if (strstr(nv, "socket options") == NULL) {
1445 fprintf(fp, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1447 fprintf(fp, "%s\n\n", nv);
1449 /* configure shares */
1451 char *buf;
1452 char *p, *q;
1453 char *name, *path, *comment, *writeable, *hidden;
1454 int cnt = 0;
1456 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1458 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1460 p = buf;
1461 while ((q = strsep(&p, ">")) != NULL) {
1462 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1463 if (!path || !name) continue;
1465 /* share name */
1466 fprintf(fp, "\n[%s]\n", name);
1468 /* path */
1469 fprintf(fp, " path = %s\n", path);
1471 /* access level */
1472 if (!strcmp(writeable, "1"))
1473 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1474 if (!strcmp(hidden, "1"))
1475 fprintf(fp, " browseable = no\n");
1477 /* comment */
1478 if (comment)
1479 fprintf(fp, " comment = %s\n", comment);
1481 cnt++;
1483 free(buf);
1486 /* Share every mountpoint below MOUNT_ROOT */
1487 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1488 while ((dp = readdir(dir))) {
1489 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1491 char path[256];
1492 struct stat sb;
1493 int thisdev;
1495 /* Only if is a directory and is mounted */
1496 sprintf(path, "%s/%s", MOUNT_ROOT, dp->d_name);
1497 sb.st_mode = S_IFDIR; /* failsafe */
1498 stat(path, &sb);
1499 if (!S_ISDIR(sb.st_mode))
1500 continue;
1502 /* If this dir & its parent dir are on the same device, it is not a mountpoint */
1503 strcat(path, "/.");
1504 stat(path, &sb);
1505 thisdev = sb.st_dev;
1506 strcat(path, ".");
1507 ++sb.st_dev; /* failsafe */
1508 stat(path, &sb);
1509 if (thisdev == sb.st_dev)
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
1778 // -----------------------------------------------------------------------------
1780 void start_services(void)
1782 static int once = 1;
1784 if (once) {
1785 once = 0;
1787 if (nvram_get_int("telnetd_eas")) start_telnetd();
1788 if (nvram_get_int("sshd_eas")) start_sshd();
1791 // start_syslog();
1792 start_nas();
1793 start_zebra();
1794 start_dnsmasq();
1795 start_cifs();
1796 start_httpd();
1797 start_cron();
1798 // start_upnp();
1799 start_rstats(0);
1800 start_sched();
1801 #ifdef TCONFIG_IPV6
1802 /* note: starting radvd here might be too early in case of
1803 * DHCPv6 or 6to4 because we won't have received a prefix and
1804 * so it will disable advertisements. To restart them, we have
1805 * to send radvd a SIGHUP, or restart it.
1807 start_radvd();
1808 #endif
1809 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
1812 void stop_services(void)
1814 clear_resolv();
1816 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
1817 #ifdef TCONFIG_IPV6
1818 stop_radvd();
1819 #endif
1820 stop_sched();
1821 stop_rstats();
1822 // stop_upnp();
1823 stop_cron();
1824 stop_httpd();
1825 stop_cifs();
1826 stop_dnsmasq();
1827 stop_zebra();
1828 stop_nas();
1829 // stop_syslog();
1832 // -----------------------------------------------------------------------------
1834 /* nvram "action_service" is: "service-action[-modifier]"
1835 * action is something like "stop" or "start" or "restart"
1836 * optional modifier is "c" for the "service" command-line command
1838 void exec_service(void)
1840 const int A_START = 1;
1841 const int A_STOP = 2;
1842 const int A_RESTART = 1|2;
1843 char buffer[128];
1844 char *service;
1845 char *act;
1846 char *next;
1847 char *modifier;
1848 int action, user;
1849 int i;
1851 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
1852 next = buffer;
1854 TOP:
1855 act = strsep(&next, ",");
1856 service = strsep(&act, "-");
1857 if (act == NULL) {
1858 next = NULL;
1859 goto CLEAR;
1861 modifier = act;
1862 strsep(&modifier, "-");
1864 TRACE_PT("service=%s action=%s modifier=%s\n", service, act, modifier ? : "");
1866 if (strcmp(act, "start") == 0) action = A_START;
1867 else if (strcmp(act, "stop") == 0) action = A_STOP;
1868 else if (strcmp(act, "restart") == 0) action = A_RESTART;
1869 else action = 0;
1870 user = (modifier != NULL && *modifier == 'c');
1872 if (strcmp(service, "dhcpc") == 0) {
1873 if (action & A_STOP) stop_dhcpc();
1874 if (action & A_START) start_dhcpc();
1875 goto CLEAR;
1878 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
1879 if (action & A_STOP) stop_dnsmasq();
1880 if (action & A_START) {
1881 dns_to_resolv();
1882 start_dnsmasq();
1884 goto CLEAR;
1887 if (strcmp(service, "firewall") == 0) {
1888 if (action & A_STOP) {
1889 stop_firewall();
1890 stop_igmp_proxy();
1892 if (action & A_START) {
1893 start_firewall();
1894 start_igmp_proxy();
1896 goto CLEAR;
1899 if (strcmp(service, "restrict") == 0) {
1900 if (action & A_STOP) {
1901 stop_firewall();
1902 start_cmon();
1904 if (action & A_START) {
1905 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
1907 start_firewall();
1908 start_cmon();
1910 // if radio was disabled by access restriction, but no rule is handling it now, enable it
1911 if (i == 1) {
1912 if (nvram_get_int("rrules_radio") < 0) {
1913 eval("radio", "on");
1917 goto CLEAR;
1920 if (strcmp(service, "qos") == 0) {
1921 if (action & A_STOP) {
1922 stop_qos();
1923 start_cmon();
1925 stop_firewall(); start_firewall(); // always restarted
1926 if (action & A_START) {
1927 start_qos();
1928 start_cmon();
1929 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
1931 goto CLEAR;
1934 if (strcmp(service, "qoslimit") == 0) {
1935 if (action & A_STOP) {
1936 stop_qoslimit();
1937 start_cmon();
1939 stop_firewall(); start_firewall(); // always restarted
1940 if (action & A_START) {
1941 start_qoslimit();
1942 start_cmon();
1945 goto CLEAR;
1948 if (strcmp(service, "arpbind") == 0) {
1949 if (action & A_STOP) stop_arpbind();
1950 if (action & A_START) stop_arpbind();
1951 goto CLEAR;
1954 if (strcmp(service, "cmon") == 0) { // TOASTMAN CLIENT MONITOR - EXPERIMENTAL
1955 if (action & A_STOP) {
1956 stop_cmon();
1958 if (action & A_START) {
1959 start_cmon();
1961 goto CLEAR;
1964 if (strcmp(service, "upnp") == 0) {
1965 if (action & A_STOP) {
1966 stop_upnp();
1967 start_cmon();
1969 stop_firewall(); start_firewall(); // always restarted
1970 if (action & A_START) {
1971 start_upnp();
1972 start_cmon();
1974 goto CLEAR;
1977 if (strcmp(service, "telnetd") == 0) {
1978 if (action & A_STOP) stop_telnetd();
1979 if (action & A_START) start_telnetd();
1980 goto CLEAR;
1983 if (strcmp(service, "sshd") == 0) {
1984 if (action & A_STOP) stop_sshd();
1985 if (action & A_START) start_sshd();
1986 goto CLEAR;
1989 if (strcmp(service, "httpd") == 0) {
1990 if (action & A_STOP) stop_httpd();
1991 if (action & A_START) start_httpd();
1992 goto CLEAR;
1995 #ifdef TCONFIG_IPV6
1996 if (strcmp(service, "ipv6") == 0) {
1997 if (action & A_STOP) {
1998 stop_radvd();
1999 stop_ipv6();
2001 if (action & A_START) {
2002 start_ipv6();
2003 start_radvd();
2005 goto CLEAR;
2008 if (strcmp(service, "radvd") == 0) {
2009 if (action & A_STOP) {
2010 stop_radvd();
2012 if (action & A_START) {
2013 start_radvd();
2015 goto CLEAR;
2018 if (strncmp(service, "dhcp6", 5) == 0) {
2019 if (action & A_STOP) {
2020 stop_dhcp6c();
2022 if (action & A_START) {
2023 start_dhcp6c();
2025 goto CLEAR;
2027 #endif
2029 if (strcmp(service, "admin") == 0) {
2030 if (action & A_STOP) {
2031 stop_sshd();
2032 stop_telnetd();
2033 stop_httpd();
2035 stop_firewall(); start_firewall(); // always restarted
2036 if (action & A_START) {
2037 start_httpd();
2038 create_passwd();
2039 if (nvram_match("telnetd_eas", "1")) start_telnetd();
2040 if (nvram_match("sshd_eas", "1")) start_sshd();
2042 goto CLEAR;
2045 if (strcmp(service, "ddns") == 0) {
2046 if (action & A_STOP) stop_ddns();
2047 if (action & A_START) start_ddns();
2048 goto CLEAR;
2051 if (strcmp(service, "ntpc") == 0) {
2052 if (action & A_STOP) stop_ntpc();
2053 if (action & A_START) start_ntpc();
2054 goto CLEAR;
2057 if (strcmp(service, "logging") == 0) {
2058 if (action & A_STOP) {
2059 stop_syslog();
2060 start_cmon();
2062 if (action & A_START) {
2063 start_syslog();
2064 start_cmon();
2066 if (!user) {
2067 // always restarted except from "service" command
2068 stop_cron(); start_cron();
2069 stop_firewall(); start_firewall();
2070 start_cmon();
2072 goto CLEAR;
2075 if (strcmp(service, "crond") == 0) {
2076 if (action & A_STOP) {
2077 stop_cron();
2079 if (action & A_START) {
2080 start_cron();
2082 goto CLEAR;
2085 #ifdef LINUX26
2086 if (strncmp(service, "hotplug", 7) == 0) {
2087 if (action & A_STOP) {
2088 stop_hotplug2();
2090 if (action & A_START) {
2091 start_hotplug2(1);
2093 goto CLEAR;
2095 #endif
2097 if (strcmp(service, "upgrade") == 0) {
2098 if (action & A_START) {
2099 #if TOMATO_SL
2100 stop_usbevent();
2101 stop_smbd();
2102 #endif
2103 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2104 stop_jffs2();
2105 // stop_cifs();
2106 stop_zebra();
2107 stop_cron();
2108 stop_ntpc();
2109 stop_upnp();
2110 // stop_dhcpc();
2111 killall("rstats", SIGTERM);
2112 killall("buttons", SIGTERM);
2113 stop_syslog();
2114 remove_storage_main(1); // !!TB - USB Support
2115 stop_usb(); // !!TB - USB Support
2117 goto CLEAR;
2120 #ifdef TCONFIG_CIFS
2121 if (strcmp(service, "cifs") == 0) {
2122 if (action & A_STOP) stop_cifs();
2123 if (action & A_START) start_cifs();
2124 goto CLEAR;
2126 #endif
2128 #ifdef TCONFIG_JFFS2
2129 if (strncmp(service, "jffs", 4) == 0) {
2130 if (action & A_STOP) stop_jffs2();
2131 if (action & A_START) start_jffs2();
2132 goto CLEAR;
2134 #endif
2136 if (strcmp(service, "zebra") == 0) {
2137 if (action & A_STOP) stop_zebra();
2138 if (action & A_START) start_zebra();
2139 goto CLEAR;
2142 if (strcmp(service, "routing") == 0) {
2143 if (action & A_STOP) {
2144 stop_zebra();
2145 do_static_routes(0); // remove old '_saved'
2146 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2148 stop_firewall();
2149 start_firewall();
2150 if (action & A_START) {
2151 do_static_routes(1); // add new
2152 start_zebra();
2153 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2155 goto CLEAR;
2158 if (strcmp(service, "ctnf") == 0) {
2159 if (action & A_START) {
2160 setup_conntrack();
2161 stop_firewall();
2162 start_firewall();
2164 goto CLEAR;
2167 if (strcmp(service, "wan") == 0) {
2168 if (action & A_STOP) {
2169 stop_wan();
2172 if (action & A_START) {
2173 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2174 start_wan(BOOT);
2175 sleep(2);
2176 force_to_dial();
2178 goto CLEAR;
2181 if (strcmp(service, "net") == 0) {
2182 if (action & A_STOP) {
2183 #ifdef TCONFIG_USB
2184 stop_nas_services();
2185 #endif
2186 #ifdef TCONFIG_IPV6
2187 stop_radvd();
2188 #endif
2189 stop_httpd();
2190 stop_dnsmasq();
2191 stop_nas();
2192 stop_wan();
2193 stop_lan();
2194 stop_vlan();
2196 if (action & A_START) {
2197 start_vlan();
2198 start_lan();
2199 start_wan(BOOT);
2200 start_nas();
2201 start_dnsmasq();
2202 start_httpd();
2203 #ifdef TCONFIG_IPV6
2204 start_radvd();
2205 #endif
2206 start_wl();
2207 #ifdef TCONFIG_USB
2208 start_nas_services();
2209 #endif
2211 goto CLEAR;
2214 if (strcmp(service, "nas") == 0) {
2215 if (action & A_STOP) {
2216 stop_nas();
2218 if (action & A_START) {
2219 start_nas();
2220 start_wl();
2222 goto CLEAR;
2225 if (strcmp(service, "rstats") == 0) {
2226 if (action & A_STOP) stop_rstats();
2227 if (action & A_START) start_rstats(0);
2228 goto CLEAR;
2231 if (strcmp(service, "rstatsnew") == 0) {
2232 if (action & A_STOP) stop_rstats();
2233 if (action & A_START) start_rstats(1);
2234 goto CLEAR;
2237 if (strcmp(service, "sched") == 0) {
2238 if (action & A_STOP) stop_sched();
2239 if (action & A_START) start_sched();
2240 goto CLEAR;
2243 #ifdef TCONFIG_USB
2244 // !!TB - USB Support
2245 if (strcmp(service, "usb") == 0) {
2246 if (action & A_STOP) stop_usb();
2247 if (action & A_START) {
2248 start_usb();
2249 // restart Samba and ftp since they may be killed by stop_usb()
2250 restart_nas_services(0, 1);
2251 // remount all partitions by simulating hotplug event
2252 add_remove_usbhost("-1", 1);
2254 goto CLEAR;
2257 if (strcmp(service, "usbapps") == 0) {
2258 if (action & A_STOP) stop_nas_services();
2259 if (action & A_START) start_nas_services();
2260 goto CLEAR;
2262 #endif
2264 #ifdef TCONFIG_FTP
2265 // !!TB - FTP Server
2266 if (strcmp(service, "ftpd") == 0) {
2267 if (action & A_STOP) stop_ftpd();
2268 setup_conntrack();
2269 stop_firewall();
2270 start_firewall();
2271 if (action & A_START) start_ftpd();
2272 goto CLEAR;
2274 #endif
2276 #ifdef TCONFIG_MEDIA_SERVER
2277 if (strcmp(service, "media") == 0 || strcmp(service, "dlna") == 0) {
2278 if (action & A_STOP) stop_media_server();
2279 if (action & A_START) start_media_server();
2280 goto CLEAR;
2282 #endif
2284 #ifdef TCONFIG_SAMBASRV
2285 // !!TB - Samba
2286 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
2287 if (action & A_STOP) stop_samba();
2288 if (action & A_START) {
2289 create_passwd();
2290 stop_dnsmasq();
2291 start_dnsmasq();
2292 start_samba();
2294 goto CLEAR;
2296 #endif
2298 #ifdef TCONFIG_OPENVPN
2299 if (strncmp(service, "vpnclient", 9) == 0) {
2300 if (action & A_STOP) stop_vpnclient(atoi(&service[9]));
2301 if (action & A_START) start_vpnclient(atoi(&service[9]));
2302 goto CLEAR;
2305 if (strncmp(service, "vpnserver", 9) == 0) {
2306 if (action & A_STOP) stop_vpnserver(atoi(&service[9]));
2307 if (action & A_START) start_vpnserver(atoi(&service[9]));
2308 goto CLEAR;
2310 #endif
2312 CLEAR:
2313 if (next) goto TOP;
2315 // some functions check action_service and must be cleared at end -- zzz
2316 nvram_set("action_service", "");
2318 // Force recheck in 500 msec
2319 setitimer(ITIMER_REAL, &pop_tv, NULL);
2322 static void do_service(const char *name, const char *action, int user)
2324 int n;
2325 char s[64];
2327 n = 150;
2328 while (!nvram_match("action_service", "")) {
2329 if (user) {
2330 putchar('*');
2331 fflush(stdout);
2333 else if (--n < 0) break;
2334 usleep(100 * 1000);
2337 snprintf(s, sizeof(s), "%s-%s%s", name, action, (user ? "-c" : ""));
2338 nvram_set("action_service", s);
2339 kill(1, SIGUSR1);
2341 n = 150;
2342 while (nvram_match("action_service", s)) {
2343 if (user) {
2344 putchar('.');
2345 fflush(stdout);
2347 else if (--n < 0) {
2348 break;
2350 usleep(100 * 1000);
2354 int service_main(int argc, char *argv[])
2356 if (argc != 3) usage_exit(argv[0], "<service> <action>");
2357 do_service(argv[1], argv[2], 1);
2358 printf("\nDone.\n");
2359 return 0;
2362 void start_service(const char *name)
2364 do_service(name, "start", 0);
2367 void stop_service(const char *name)
2369 do_service(name, "stop", 0);
2373 void restart_service(const char *name)
2375 do_service(name, "restart", 0);