Merge branch 'tomato-shibby' into tomato-shibby-RT-AC
[tomato.git] / release / src / router / rc / services.c
blobbe464ec6c217c550ec1986e39c3047ff37ee1142
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 char sdhcp_lease[32];
75 char *e;
76 int n;
77 char *mac, *ip, *name;
78 char *p;
79 int ipn;
80 char ipbuf[32];
81 FILE *hf, *df;
82 int dhcp_start;
83 int dhcp_count;
84 int dhcp_lease;
85 int do_dhcpd;
86 int do_dns;
87 int do_dhcpd_hosts;
89 #ifdef TCONFIG_IPV6
90 char *prefix, *ipv6, *mtu;
91 int do_6to4, do_6rd;
92 int service;
93 #endif
95 TRACE_PT("begin\n");
97 if (getpid() != 1) {
98 start_service("dnsmasq");
99 return;
102 stop_dnsmasq();
104 if (foreach_wif(1, NULL, is_wet)) return;
106 if ((f = fopen("/etc/dnsmasq.conf", "w")) == NULL) return;
108 router_ip = nvram_safe_get("lan_ipaddr");
110 fprintf(f,
111 "pid-file=/var/run/dnsmasq.pid\n");
112 if (((nv = nvram_get("wan_domain")) != NULL) || ((nv = nvram_get("wan_get_domain")) != NULL)) {
113 if (*nv) fprintf(f, "domain=%s\n", nv);
116 // dns
117 const dns_list_t *dns = get_dns(); // this always points to a static buffer
119 if (((nv = nvram_get("dns_minport")) != NULL) && (*nv)) n = atoi(nv);
120 else n = 4096;
121 fprintf(f,
122 "resolv-file=%s\n" // the real stuff is here
123 "addn-hosts=%s\n" // directory with additional hosts files
124 "dhcp-hostsfile=%s\n" // directory with dhcp hosts files
125 "expand-hosts\n" // expand hostnames in hosts file
126 "min-port=%u\n", // min port used for random src port
127 dmresolv, dmhosts, dmdhcp, n);
128 do_dns = nvram_match("dhcpd_dmdns", "1");
130 // DNS rebinding protection, will discard upstream RFC1918 responses
131 if (nvram_get_int("dns_norebind")) {
132 fprintf(f,
133 "stop-dns-rebind\n"
134 "rebind-localhost-ok\n");
135 // allow RFC1918 responses for server domain
136 switch (get_wan_proto()) {
137 case WP_PPTP:
138 nv = nvram_get("pptp_server_ip");
139 break;
140 case WP_L2TP:
141 nv = nvram_get("l2tp_server_ip");
142 break;
143 default:
144 nv = NULL;
145 break;
147 if (nv && *nv) fprintf(f, "rebind-domain-ok=%s\n", nv);
150 #ifdef TCONFIG_DNSCRYPT
151 if (nvram_match("dnscrypt_proxy", "1")) {
152 fprintf(f, "server=127.0.0.1#%s\n", nvram_safe_get("dnscrypt_port") );
154 #endif
156 for (n = 0 ; n < dns->count; ++n) {
157 if (dns->dns[n].port != 53) {
158 fprintf(f, "server=%s#%u\n", inet_ntoa(dns->dns[n].addr), dns->dns[n].port);
162 if (nvram_get_int("dhcpd_static_only")) {
163 fprintf(f, "dhcp-ignore=tag:!known\n");
166 if ((n = nvram_get_int("dnsmasq_q"))) { //process quiet flags
167 if (n & 1) fprintf(f, "quiet-dhcp\n");
168 if (n & 2) fprintf(f, "quiet-dhcp6\n");
169 if (n & 4) fprintf(f, "quiet-ra\n");
172 // dhcp
173 do_dhcpd_hosts=0;
174 char lanN_proto[] = "lanXX_proto";
175 char lanN_ifname[] = "lanXX_ifname";
176 char lanN_ipaddr[] = "lanXX_ipaddr";
177 char lanN_netmask[] = "lanXX_netmask";
178 char dhcpdN_startip[] = "dhcpdXX_startip";
179 char dhcpdN_endip[] = "dhcpdXX_endip";
180 char dhcpN_start[] = "dhcpXX_start";
181 char dhcpN_num[] = "dhcpXX_num";
182 char dhcpN_lease[] = "dhcpXX_lease";
183 char br;
184 for(br=0 ; br<=3 ; br++) {
185 char bridge[2] = "0";
186 if (br!=0)
187 bridge[0]+=br;
188 else
189 strcpy(bridge, "");
191 sprintf(lanN_proto, "lan%s_proto", bridge);
192 sprintf(lanN_ifname, "lan%s_ifname", bridge);
193 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
194 do_dhcpd = nvram_match(lanN_proto, "dhcp");
195 if (do_dhcpd) {
196 do_dhcpd_hosts++;
198 router_ip = nvram_safe_get(lanN_ipaddr);
199 strlcpy(lan, router_ip, sizeof(lan));
200 if ((p = strrchr(lan, '.')) != NULL) *(p + 1) = 0;
202 fprintf(f,
203 "interface=%s\n",
204 nvram_safe_get(lanN_ifname));
206 sprintf(dhcpN_lease, "dhcp%s_lease", bridge);
207 dhcp_lease = nvram_get_int(dhcpN_lease);
209 if (dhcp_lease <= 0) dhcp_lease = 1440;
211 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
212 if (n < 0) strcpy(sdhcp_lease, "infinite");
213 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
215 if (!do_dns) {
216 // if not using dnsmasq for dns
218 if ((dns->count == 0) && (nvram_get_int("dhcpd_llndns"))) {
219 // no DNS might be temporary. use a low lease time to force clients to update.
220 dhcp_lease = 2;
221 strcpy(sdhcp_lease, "2m");
222 do_dns = 1;
224 else {
225 // pass the dns directly
226 buf[0] = 0;
227 for (n = 0 ; n < dns->count; ++n) {
228 if (dns->dns[n].port == 53) { // check: option 6 doesn't seem to support other ports
229 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n].addr));
232 fprintf(f, "dhcp-option=tag:%s,6%s\n", nvram_safe_get(lanN_ifname), buf);
236 sprintf(dhcpdN_startip, "dhcpd%s_startip", bridge);
237 sprintf(dhcpdN_endip, "dhcpd%s_endip", bridge);
238 sprintf(lanN_netmask, "lan%s_netmask", bridge);
240 if ((p = nvram_get(dhcpdN_startip)) && (*p) && (e = nvram_get(dhcpdN_endip)) && (*e)) {
241 fprintf(f, "dhcp-range=tag:%s,%s,%s,%s,%dm\n", nvram_safe_get(lanN_ifname), p, e, nvram_safe_get(lanN_netmask), dhcp_lease);
243 else {
244 // for compatibility
245 sprintf(dhcpN_start, "dhcp%s_start", bridge);
246 sprintf(dhcpN_num, "dhcp%s_num", bridge);
247 sprintf(lanN_netmask, "lan%s_netmask", bridge);
248 dhcp_start = nvram_get_int(dhcpN_start);
249 dhcp_count = nvram_get_int(dhcpN_num);
250 fprintf(f, "dhcp-range=tag:%s,%s%d,%s%d,%s,%dm\n",
251 nvram_safe_get(lanN_ifname), lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get(lanN_netmask), dhcp_lease);
254 nv = nvram_safe_get(lanN_ipaddr);
255 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED)) {
256 p = nvram_safe_get("lan_gateway");
257 if ((*p) && (strcmp(p, "0.0.0.0") != 0)) nv = p;
260 fprintf(f,
261 "dhcp-option=tag:%s,3,%s\n", // gateway
262 nvram_safe_get(lanN_ifname), nv);
264 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
265 fprintf(f, "dhcp-option=tag:%s,44,%s\n", nvram_safe_get(lanN_ifname), nv);
267 #ifdef TCONFIG_SAMBASRV
268 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
269 if ((nv == NULL) || (*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
270 // Samba will serve as a WINS server
271 fprintf(f, "dhcp-option=tag:%s,44,%s\n", nvram_safe_get(lanN_ifname), nvram_safe_get(lanN_ipaddr));
274 #endif
275 } else {
276 if (strcmp(nvram_safe_get(lanN_ifname),"")!=0) {
277 fprintf(f, "interface=%s\n", nvram_safe_get(lanN_ifname));
278 // if no dhcp range is set then no dhcp service will be offered so following
279 // line is superflous.
280 // fprintf(f, "no-dhcp-interface=%s\n", nvram_safe_get(lanN_ifname));
284 // write static lease entries & create hosts file
286 mkdir_if_none(dmhosts);
287 snprintf(buf, sizeof(buf), "%s/hosts", dmhosts);
288 if ((hf = fopen(buf, "w")) != NULL) {
289 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
290 fprintf(hf, "%s %s\n", router_ip, nv);
291 #ifdef TCONFIG_SAMBASRV
292 else if (((nv = nvram_get("lan_hostname")) != NULL) && (*nv))
293 fprintf(hf, "%s %s\n", router_ip, nv);
294 #endif
295 p = (char *)get_wanip();
296 if ((*p == 0) || strcmp(p, "0.0.0.0") == 0)
297 p = "127.0.0.1";
298 fprintf(hf, "%s wan-ip\n", p);
299 if (nv && (*nv))
300 fprintf(hf, "%s %s-wan\n", p, nv);
303 mkdir_if_none(dmdhcp);
304 snprintf(buf, sizeof(buf), "%s/dhcp-hosts", dmdhcp);
305 df = fopen(buf, "w");
307 // PREVIOUS/OLD FORMAT:
308 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
309 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
310 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 106 w/ delim
312 // NEW FORMAT (+static ARP binding after hostname):
313 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 55 w/ delim
314 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 87 w/ delim
315 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 108 w/ delim
317 p = nvram_safe_get("dhcpd_static");
318 while ((e = strchr(p, '>')) != NULL) {
319 n = (e - p);
320 if (n > 107) {
321 p = e + 1;
322 continue;
325 strncpy(buf, p, n);
326 buf[n] = 0;
327 p = e + 1;
329 if ((e = strchr(buf, '<')) == NULL) continue;
330 *e = 0;
331 mac = buf;
333 ip = e + 1;
334 if ((e = strchr(ip, '<')) == NULL) continue;
335 *e = 0;
336 if (strchr(ip, '.') == NULL) {
337 ipn = atoi(ip);
338 if ((ipn <= 0) || (ipn > 255)) continue;
339 sprintf(ipbuf, "%s%d", lan, ipn);
340 ip = ipbuf;
342 else {
343 if (inet_addr(ip) == INADDR_NONE) continue;
346 name = e + 1;
348 if ((e = strchr(name, '<')) != NULL) {
349 *e = 0;
352 if ((hf) && (*name != 0)) {
353 fprintf(hf, "%s %s\n", ip, name);
356 if ((do_dhcpd_hosts > 0) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
357 if (nvram_get_int("dhcpd_slt") == 0) {
358 fprintf(f, "dhcp-host=%s,%s\n", mac, ip);
359 } else {
360 fprintf(f, "dhcp-host=%s,%s,%s\n", mac, ip, sdhcp_lease);
365 if (df) fclose(df);
366 if (hf) fclose(hf);
368 n = nvram_get_int("dhcpd_lmax");
369 fprintf(f,
370 "dhcp-lease-max=%d\n",
371 (n > 0) ? n : 255);
372 if (nvram_get_int("dhcpd_auth") >= 0) {
373 fprintf(f, "dhcp-authoritative\n");
376 #ifdef TCONFIG_DNSCRYPT
377 if (nvram_match("dnscrypt_proxy", "1")) {
378 fprintf(f, "strict-order\n");
380 #endif
384 #ifdef TCONFIG_OPENVPN
385 write_vpn_dnsmasq_config(f);
386 #endif
388 #ifdef TCONFIG_PPTPD
389 write_pptpd_dnsmasq_config(f);
390 #endif
392 #ifdef TCONFIG_IPV6
393 if (ipv6_enabled() && nvram_get_int("ipv6_radvd")) {
395 service = get_ipv6_service();
396 do_6to4 = (service == IPV6_ANYCAST_6TO4);
397 do_6rd = (service == IPV6_6RD || service == IPV6_6RD_DHCP);
398 mtu = NULL;
400 switch (service) {
401 case IPV6_NATIVE_DHCP:
402 case IPV6_ANYCAST_6TO4:
403 case IPV6_6IN4:
404 case IPV6_6RD:
405 case IPV6_6RD_DHCP:
406 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
407 // fall through
408 default:
409 prefix = do_6to4 ? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
410 break;
412 if (!(*prefix)) prefix = "::";
413 ipv6 = (char *)ipv6_router_address(NULL);
415 fprintf(f, "enable-ra\ndhcp-range=tag:br0,%s, slaac, ra-names, 64\n", prefix);
417 fprintf(f,"enable-ra\ndhcp-range=::1, ::FFFF:FFFF, constructor:br*, ra-names, 64, 12h\n");
420 #endif
422 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
424 fappend(f, "/etc/dnsmasq.custom");
428 fclose(f);
430 if (do_dns) {
431 unlink("/etc/resolv.conf");
432 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
435 TRACE_PT("run dnsmasq\n");
437 // Default to some values we like, but allow the user to override them.
438 eval("dnsmasq", "-c", "1500", "--log-async");
440 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
441 pid_dnsmasq = -2;
444 TRACE_PT("end\n");
446 #ifdef TCONFIG_DNSCRYPT
447 //start dnscrypt-proxy
448 if (nvram_match("dnscrypt_proxy", "1")) {
449 char dnscrypt_local[30];
450 sprintf(dnscrypt_local, "127.0.0.1:%s", nvram_safe_get("dnscrypt_port") );
452 eval("ntp2ip");
453 eval("dnscrypt-proxy", "-d", "-a", dnscrypt_local, nvram_safe_get("dnscrypt_cmd") );
455 #ifdef TCONFIG_IPV6
456 char dnscrypt_local_ipv6[30];
457 sprintf(dnscrypt_local_ipv6, "::1:%s", nvram_safe_get("dnscrypt_port") );
459 if (get_ipv6_service() != NULL) //if ipv6 enabled
460 eval("dnscrypt-proxy", "-d", "-a", dnscrypt_local_ipv6, nvram_safe_get("dnscrypt_cmd") );
461 #endif
463 #endif
467 void stop_dnsmasq(void)
469 TRACE_PT("begin\n");
471 if (getpid() != 1) {
472 stop_service("dnsmasq");
473 return;
476 pid_dnsmasq = -1;
478 unlink("/etc/resolv.conf");
479 symlink(dmresolv, "/etc/resolv.conf");
481 killall_tk("dnsmasq");
482 #ifdef TCONFIG_DNSCRYPT
483 killall_tk("dnscrypt-proxy");
484 #endif
486 TRACE_PT("end\n");
489 void clear_resolv(void)
491 f_write(dmresolv, NULL, 0, 0, 0); // blank
494 #ifdef TCONFIG_IPV6
495 static int write_ipv6_dns_servers(FILE *f, const char *prefix, char *dns, const char *suffix, int once)
497 char p[INET6_ADDRSTRLEN + 1], *next = NULL;
498 struct in6_addr addr;
499 int cnt = 0;
501 foreach(p, dns, next) {
502 // verify that this is a valid IPv6 address
503 if (inet_pton(AF_INET6, p, &addr) == 1) {
504 fprintf(f, "%s%s%s", (once && cnt) ? "" : prefix, p, suffix);
505 ++cnt;
509 return cnt;
511 #endif
513 void dns_to_resolv(void)
515 FILE *f;
516 const dns_list_t *dns;
517 int i;
518 mode_t m;
520 m = umask(022); // 077 from pppoecd
521 if ((f = fopen(dmresolv, "w")) != NULL) {
522 // Check for VPN DNS entries
523 if (!write_pptpvpn_resolv(f) && !write_vpn_resolv(f)) {
524 #ifdef TCONFIG_IPV6
525 if (write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_dns"), "\n", 0) == 0 || nvram_get_int("dns_addget"))
526 write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_get_dns"), "\n", 0);
527 #endif
528 dns = get_dns(); // static buffer
529 if (dns->count == 0) {
530 // Put a pseudo DNS IP to trigger Connect On Demand
531 if (nvram_match("ppp_demand", "1")) {
532 switch (get_wan_proto()) {
533 case WP_PPPOE:
534 case WP_PPP3G:
535 case WP_PPTP:
536 case WP_L2TP:
537 fprintf(f, "nameserver 1.1.1.1\n");
538 break;
542 else {
543 for (i = 0; i < dns->count; i++) {
544 if (dns->dns[i].port == 53) { // resolv.conf doesn't allow for an alternate port
545 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i].addr));
550 fclose(f);
552 umask(m);
555 // -----------------------------------------------------------------------------
557 void start_httpd(void)
559 if (getpid() != 1) {
560 start_service("httpd");
561 return;
564 if( nvram_match( "web_css", "online" ) )
565 xstart( "/usr/sbin/ttb" );
567 stop_httpd();
568 chdir("/www");
569 eval("httpd");
570 chdir("/");
573 void stop_httpd(void)
575 if (getpid() != 1) {
576 stop_service("httpd");
577 return;
580 killall_tk("httpd");
583 // -----------------------------------------------------------------------------
584 #ifdef TCONFIG_IPV6
586 static void add_ip6_lanaddr(void)
588 char ip[INET6_ADDRSTRLEN + 4];
589 const char *p;
591 p = ipv6_router_address(NULL);
592 if (*p) {
593 snprintf(ip, sizeof(ip), "%s/%d", p, nvram_get_int("ipv6_prefix_length") ? : 64);
594 eval("ip", "-6", "addr", "add", ip, "dev", nvram_safe_get("lan_ifname"));
598 void start_ipv6_tunnel(void)
600 char ip[INET6_ADDRSTRLEN + 4];
601 struct in_addr addr4;
602 struct in6_addr addr;
603 const char *wanip, *mtu, *tun_dev;
604 int service;
606 service = get_ipv6_service();
607 tun_dev = get_wan6face();
608 wanip = get_wanip();
609 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
610 modprobe("sit");
612 if (service == IPV6_ANYCAST_6TO4)
613 snprintf(ip, sizeof(ip), "192.88.99.%d", nvram_get_int("ipv6_relay"));
614 else
615 strlcpy(ip, (char *)nvram_safe_get("ipv6_tun_v4end"), sizeof(ip));
616 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit",
617 "remote", ip,
618 "local", (char *)wanip,
619 "ttl", nvram_safe_get("ipv6_tun_ttl"));
621 eval("ip", "link", "set", (char *)tun_dev, "mtu", (char *)mtu, "up");
622 nvram_set("ipv6_ifname", (char *)tun_dev);
624 if (service == IPV6_ANYCAST_6TO4) {
625 add_ip6_lanaddr();
626 addr4.s_addr = 0;
627 memset(&addr, 0, sizeof(addr));
628 inet_aton(wanip, &addr4);
629 addr.s6_addr16[0] = htons(0x2002);
630 ipv6_mapaddr4(&addr, 16, &addr4, 0);
631 addr.s6_addr16[7] = htons(0x0001);
632 inet_ntop(AF_INET6, &addr, ip, sizeof(ip));
633 strncat(ip, "/16", sizeof(ip));
635 else {
636 snprintf(ip, sizeof(ip), "%s/%d",
637 nvram_safe_get("ipv6_tun_addr"),
638 nvram_get_int("ipv6_tun_addrlen") ? : 64);
640 eval("ip", "addr", "add", ip, "dev", (char *)tun_dev);
641 eval("ip", "route", "add", "::/0", "dev", (char *)tun_dev);
643 // (re)start radvd - now dnsmasq provided
644 if (service == IPV6_ANYCAST_6TO4)
645 start_dnsmasq();
648 void stop_ipv6_tunnel(void)
650 eval("ip", "tunnel", "del", (char *)get_wan6face());
651 if (get_ipv6_service() == IPV6_ANYCAST_6TO4) {
652 // get rid of old IPv6 address from lan iface
653 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
655 modprobe_r("sit");
658 void start_6rd_tunnel(void)
660 const char *tun_dev, *wanip;
661 int service, mask_len, prefix_len, local_prefix_len;
662 char mtu[10], prefix[INET6_ADDRSTRLEN], relay[INET_ADDRSTRLEN];
663 struct in_addr netmask_addr, relay_addr, relay_prefix_addr, wanip_addr;
664 struct in6_addr prefix_addr, local_prefix_addr;
665 char local_prefix[INET6_ADDRSTRLEN];
666 char tmp_ipv6[INET6_ADDRSTRLEN + 4], tmp_ipv4[INET_ADDRSTRLEN + 4];
667 char tmp[256];
668 FILE *f;
670 service = get_ipv6_service();
671 wanip = get_wanip();
672 tun_dev = get_wan6face();
673 sprintf(mtu, "%d", (nvram_get_int("wan_mtu") > 0) ? (nvram_get_int("wan_mtu") - 20) : 1280);
675 // maybe we can merge the ipv6_6rd_* variables into a single ipv_6rd_string (ala wan_6rd)
676 // to save nvram space?
677 if (service == IPV6_6RD) {
678 _dprintf("starting 6rd tunnel using manual settings.\n");
679 mask_len = nvram_get_int("ipv6_6rd_ipv4masklen");
680 prefix_len = nvram_get_int("ipv6_6rd_prefix_length");
681 strcpy(prefix, nvram_safe_get("ipv6_6rd_prefix"));
682 strcpy(relay, nvram_safe_get("ipv6_6rd_borderrelay"));
684 else {
685 _dprintf("starting 6rd tunnel using automatic settings.\n");
686 char *wan_6rd = nvram_safe_get("wan_6rd");
687 if (sscanf(wan_6rd, "%d %d %s %s", &mask_len, &prefix_len, prefix, relay) < 4) {
688 _dprintf("wan_6rd string is missing or invalid (%s)\n", wan_6rd);
689 return;
693 // validate values that were passed
694 if (mask_len < 0 || mask_len > 32) {
695 _dprintf("invalid mask_len value (%d)\n", mask_len);
696 return;
698 if (prefix_len < 0 || prefix_len > 128) {
699 _dprintf("invalid prefix_len value (%d)\n", prefix_len);
700 return;
702 if ((32 - mask_len) + prefix_len > 128) {
703 _dprintf("invalid combination of mask_len and prefix_len!\n");
704 return;
707 sprintf(tmp, "ping -q -c 2 %s | grep packet", relay);
708 if ((f = popen(tmp, "r")) == NULL) {
709 _dprintf("error obtaining data\n");
710 return;
712 fgets(tmp, sizeof(tmp), f);
713 pclose(f);
714 if (strstr(tmp, " 0% packet loss") == NULL) {
715 _dprintf("failed to ping border relay\n");
716 return;
719 // get relay prefix from border relay address and mask
720 netmask_addr.s_addr = htonl(0xffffffff << (32 - mask_len));
721 inet_aton(relay, &relay_addr);
722 relay_prefix_addr.s_addr = relay_addr.s_addr & netmask_addr.s_addr;
724 // calculate the local prefix
725 inet_pton(AF_INET6, prefix, &prefix_addr);
726 inet_pton(AF_INET, wanip, &wanip_addr);
727 if (calc_6rd_local_prefix(&prefix_addr, prefix_len, mask_len,
728 &wanip_addr, &local_prefix_addr, &local_prefix_len) == 0) {
729 _dprintf("error calculating local prefix.");
730 return;
732 inet_ntop(AF_INET6, &local_prefix_addr, local_prefix, sizeof(local_prefix));
734 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1", local_prefix);
735 nvram_set("ipv6_rtr_addr", tmp_ipv6);
736 nvram_set("ipv6_prefix", local_prefix);
738 // load sit module needed for the 6rd tunnel
739 modprobe("sit");
741 // creating the 6rd tunnel
742 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit", "local", (char *)wanip, "ttl", nvram_safe_get("ipv6_tun_ttl"));
744 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s/%d", prefix, prefix_len);
745 snprintf(tmp_ipv4, sizeof(tmp_ipv4), "%s/%d", inet_ntoa(relay_prefix_addr), mask_len);
746 eval("ip", "tunnel" "6rd", "dev", (char *)tun_dev, "6rd-prefix", tmp_ipv6, "6rd-relay_prefix", tmp_ipv4);
748 // bringing up the link
749 eval("ip", "link", "set", "dev", (char *)tun_dev, "mtu", (char *)mtu, "up");
751 // setting the WAN address Note: IPv6 WAN CIDR should be: ((32 - ip6rd_ipv4masklen) + ip6rd_prefixlen)
752 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1/%d", local_prefix, local_prefix_len);
753 eval("ip", "-6", "addr", "add", tmp_ipv6, "dev", (char *)tun_dev);
755 // setting the LAN address Note: IPv6 LAN CIDR should be 64
756 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1/%d", local_prefix, nvram_get_int("ipv6_prefix_length") ? : 64);
757 eval("ip", "-6", "addr", "add", tmp_ipv6, "dev", nvram_safe_get("lan_ifname"));
759 // adding default route via the border relay
760 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "::%s", relay);
761 eval("ip", "-6", "route", "add", "default", "via", tmp_ipv6, "dev", (char *)tun_dev);
763 nvram_set("ipv6_ifname", (char *)tun_dev);
765 // (re)start radvd now dnsmasq
766 start_dnsmasq();
768 printf("6rd end\n");
771 void stop_6rd_tunnel(void)
773 eval("ip", "tunnel", "del", (char *)get_wan6face());
774 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
775 modprobe_r("sit");
779 void start_ipv6(void)
781 int service;
783 service = get_ipv6_service();
784 enable_ip6_forward();
786 // Check if turned on
787 switch (service) {
788 case IPV6_NATIVE:
789 case IPV6_6IN4:
790 case IPV6_MANUAL:
791 add_ip6_lanaddr();
792 break;
793 case IPV6_NATIVE_DHCP:
794 case IPV6_ANYCAST_6TO4:
795 nvram_set("ipv6_rtr_addr", "");
796 nvram_set("ipv6_prefix", "");
797 break;
800 if (service != IPV6_DISABLED) {
801 if ((nvram_get_int("ipv6_accept_ra") & 2) != 0 && !nvram_get_int("ipv6_radvd"))
802 accept_ra(nvram_safe_get("lan_ifname"));
806 void stop_ipv6(void)
808 stop_ipv6_tunnel();
809 stop_dhcp6c();
810 eval("ip", "-6", "addr", "flush", "scope", "global");
813 #endif
815 // -----------------------------------------------------------------------------
817 void start_upnp(void)
819 if (getpid() != 1) {
820 start_service("upnp");
821 return;
824 if (get_wan_proto() == WP_DISABLED) return;
826 int enable;
827 FILE *f;
828 int upnp_port;
830 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
831 mkdir("/etc/upnp", 0777);
832 if (f_exists("/etc/upnp/config.alt")) {
833 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
835 else {
836 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
837 upnp_port = nvram_get_int("upnp_port");
838 if ((upnp_port < 0) || (upnp_port >= 0xFFFF)) upnp_port = 0;
841 fprintf(f,
842 "ext_ifname=%s\n"
843 "port=%d\n"
844 "enable_upnp=%s\n"
845 "enable_natpmp=%s\n"
846 "secure_mode=%s\n"
847 "upnp_forward_chain=upnp\n"
848 "upnp_nat_chain=upnp\n"
849 "notify_interval=%d\n"
850 "system_uptime=yes\n"
851 "\n"
853 get_wanface(),
854 upnp_port,
855 (enable & 1) ? "yes" : "no", // upnp enable
856 (enable & 2) ? "yes" : "no", // natpmp enable
857 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
858 nvram_get_int("upnp_ssdp_interval")
861 if (nvram_get_int("upnp_clean")) {
862 int interval = nvram_get_int("upnp_clean_interval");
863 if (interval < 60) interval = 60;
864 fprintf(f,
865 "clean_ruleset_interval=%d\n"
866 "clean_ruleset_threshold=%d\n",
867 interval,
868 nvram_get_int("upnp_clean_threshold")
871 else
872 fprintf(f,"clean_ruleset_interval=0\n");
874 if (nvram_match("upnp_mnp", "1")) {
875 int https = nvram_get_int("https_enable");
876 fprintf(f, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
877 https ? "s" : "", nvram_safe_get("lan_ipaddr"),
878 nvram_safe_get(https ? "https_lanport" : "http_lanport"));
880 else {
881 // Empty parameters are not included into XML service description
882 fprintf(f, "presentation_url=\n");
885 char uuid[45];
886 f_read_string("/proc/sys/kernel/random/uuid", uuid, sizeof(uuid));
887 fprintf(f, "uuid=%s\n", uuid);
889 char lanN_ipaddr[] = "lanXX_ipaddr";
890 char lanN_netmask[] = "lanXX_netmask";
891 char upnp_lanN[] = "upnp_lanXX";
892 char br;
894 for(br=0 ; br<4 ; br++) {
895 char bridge[2] = "0";
896 if (br!=0)
897 bridge[0]+=br;
898 else
899 strcpy(bridge, "");
901 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
902 sprintf(lanN_netmask, "lan%s_netmask", bridge);
903 sprintf(upnp_lanN, "upnp_lan%s", bridge);
905 char *lanip = nvram_safe_get(lanN_ipaddr);
906 char *lanmask = nvram_safe_get(lanN_netmask);
907 char *lanlisten = nvram_safe_get(upnp_lanN);
909 if((strcmp(lanlisten,"1")==0) && (strcmp(lanip,"")!=0) && (strcmp(lanip,"0.0.0.0")!=0)) {
910 fprintf(f,
911 "listening_ip=%s/%s\n",
912 lanip, lanmask);
913 int ports[4];
914 if ((ports[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
915 (ports[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
916 (ports[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
917 (ports[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
918 fprintf(f,
919 "allow %d-%d %s/%s %d-%d\n",
920 ports[0], ports[1],
921 lanip, lanmask,
922 ports[2], ports[3]
925 else {
926 // by default allow only redirection of ports above 1024
927 fprintf(f, "allow 1024-65535 %s/%s 1024-65535\n", lanip, lanmask);
932 fappend(f, "/etc/upnp/config.custom");
933 fprintf(f, "%s\n", nvram_safe_get("upnp_custom"));
934 fprintf(f, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
936 fclose(f);
938 xstart("miniupnpd", "-f", "/etc/upnp/config");
944 void stop_upnp(void)
946 if (getpid() != 1) {
947 stop_service("upnp");
948 return;
951 killall_tk("miniupnpd");
954 // -----------------------------------------------------------------------------
956 static pid_t pid_crond = -1;
958 void start_cron(void)
960 stop_cron();
962 eval("crond", nvram_contains_word("log_events", "crond") ? NULL : "-l", "9");
963 if (!nvram_contains_word("debug_norestart", "crond")) {
964 pid_crond = -2;
968 void stop_cron(void)
970 pid_crond = -1;
971 killall_tk("crond");
974 // -----------------------------------------------------------------------------
975 #ifdef LINUX26
977 static pid_t pid_hotplug2 = -1;
979 void start_hotplug2()
981 stop_hotplug2();
983 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE, 0);
984 xstart("hotplug2", "--persistent", "--no-coldplug");
985 // FIXME: Don't remember exactly why I put "sleep" here -
986 // but it was not for a race with check_services()... - TB
987 sleep(1);
989 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
990 pid_hotplug2 = -2;
994 void stop_hotplug2(void)
996 pid_hotplug2 = -1;
997 killall_tk("hotplug2");
1000 #endif /* LINUX26 */
1001 // -----------------------------------------------------------------------------
1003 // Written by Sparq in 2002/07/16
1004 void start_zebra(void)
1006 #ifdef TCONFIG_ZEBRA
1007 if (getpid() != 1) {
1008 start_service("zebra");
1009 return;
1012 FILE *fp;
1014 char *lan_tx = nvram_safe_get("dr_lan_tx");
1015 char *lan_rx = nvram_safe_get("dr_lan_rx");
1016 char *lan1_tx = nvram_safe_get("dr_lan1_tx");
1017 char *lan1_rx = nvram_safe_get("dr_lan1_rx");
1018 char *lan2_tx = nvram_safe_get("dr_lan2_tx");
1019 char *lan2_rx = nvram_safe_get("dr_lan2_rx");
1020 char *lan3_tx = nvram_safe_get("dr_lan3_tx");
1021 char *lan3_rx = nvram_safe_get("dr_lan3_rx");
1022 char *wan_tx = nvram_safe_get("dr_wan_tx");
1023 char *wan_rx = nvram_safe_get("dr_wan_rx");
1025 if ((*lan_tx == '0') && (*lan_rx == '0') &&
1026 (*lan1_tx == '0') && (*lan1_rx == '0') &&
1027 (*lan2_tx == '0') && (*lan2_rx == '0') &&
1028 (*lan3_tx == '0') && (*lan3_rx == '0') &&
1029 (*wan_tx == '0') && (*wan_rx == '0')) {
1030 return;
1033 // empty
1034 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
1035 fclose(fp);
1039 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
1040 char *lan_ifname = nvram_safe_get("lan_ifname");
1041 char *lan1_ifname = nvram_safe_get("lan1_ifname");
1042 char *lan2_ifname = nvram_safe_get("lan2_ifname");
1043 char *lan3_ifname = nvram_safe_get("lan3_ifname");
1044 char *wan_ifname = nvram_safe_get("wan_ifname");
1046 fprintf(fp, "router rip\n");
1047 if(strcmp(lan_ifname,"")!=0)
1048 fprintf(fp, "network %s\n", lan_ifname);
1049 if(strcmp(lan1_ifname,"")!=0)
1050 fprintf(fp, "network %s\n", lan1_ifname);
1051 if(strcmp(lan2_ifname,"")!=0)
1052 fprintf(fp, "network %s\n", lan2_ifname);
1053 if(strcmp(lan3_ifname,"")!=0)
1054 fprintf(fp, "network %s\n", lan3_ifname);
1055 fprintf(fp, "network %s\n", wan_ifname);
1056 fprintf(fp, "redistribute connected\n");
1057 //fprintf(fp, "redistribute static\n");
1059 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
1060 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
1062 if(strcmp(lan_ifname,"")!=0) {
1063 fprintf(fp, "interface %s\n", lan_ifname);
1064 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
1065 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
1067 if(strcmp(lan1_ifname,"")!=0) {
1068 fprintf(fp, "interface %s\n", lan1_ifname);
1069 if (*lan1_tx != '0') fprintf(fp, "ip rip send version %s\n", lan1_tx);
1070 if (*lan1_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan1_rx);
1072 if(strcmp(lan2_ifname,"")!=0) {
1073 fprintf(fp, "interface %s\n", lan2_ifname);
1074 if (*lan2_tx != '0') fprintf(fp, "ip rip send version %s\n", lan2_tx);
1075 if (*lan2_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan2_rx);
1077 if(strcmp(lan3_ifname,"")!=0) {
1078 fprintf(fp, "interface %s\n", lan3_ifname);
1079 if (*lan3_tx != '0') fprintf(fp, "ip rip send version %s\n", lan3_tx);
1080 if (*lan3_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan3_rx);
1082 fprintf(fp, "interface %s\n", wan_ifname);
1083 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
1084 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
1086 fprintf(fp, "router rip\n");
1087 if(strcmp(lan_ifname,"")!=0) {
1088 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
1089 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
1091 if(strcmp(lan1_ifname,"")!=0) {
1092 if (*lan1_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan1_ifname);
1093 if (*lan1_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan1_ifname);
1095 if(strcmp(lan2_ifname,"")!=0) {
1096 if (*lan2_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan2_ifname);
1097 if (*lan2_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan2_ifname);
1099 if(strcmp(lan3_ifname,"")!=0) {
1100 if (*lan3_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan3_ifname);
1101 if (*lan3_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan3_ifname);
1103 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
1104 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
1105 fprintf(fp, "access-list private deny any\n");
1107 //fprintf(fp, "debug rip events\n");
1108 //fprintf(fp, "log file /etc/ripd.log\n");
1109 fclose(fp);
1112 xstart("zebra", "-d");
1113 xstart("ripd", "-d");
1114 #endif
1117 void stop_zebra(void)
1119 #ifdef TCONFIG_ZEBRA
1120 if (getpid() != 1) {
1121 stop_service("zebra");
1122 return;
1125 killall("zebra", SIGTERM);
1126 killall("ripd", SIGTERM);
1128 unlink("/etc/zebra.conf");
1129 unlink("/etc/ripd.conf");
1130 #endif
1133 // -----------------------------------------------------------------------------
1135 void start_syslog(void)
1137 char *argv[16];
1138 int argc;
1139 char *nv;
1140 char *b_opt = "";
1141 char rem[256];
1142 int n;
1143 char s[64];
1144 char cfg[256];
1145 char *rot_siz = "50";
1146 char *rot_keep = "1";
1147 char *log_file_path;
1149 argv[0] = "syslogd";
1150 argc = 1;
1152 if (nvram_match("log_remote", "1")) {
1153 nv = nvram_safe_get("log_remoteip");
1154 if (*nv) {
1155 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
1156 argv[argc++] = "-R";
1157 argv[argc++] = rem;
1161 if (nvram_match("log_file", "1")) {
1162 argv[argc++] = "-L";
1164 if (strcmp(nvram_safe_get("log_file_size"), "") != 0) {
1165 rot_siz = nvram_safe_get("log_file_size");
1167 if (nvram_get_int("log_file_size") > 0) {
1168 rot_keep = nvram_safe_get("log_file_keep");
1171 // log to custom path - shibby
1172 if (nvram_match("log_file_custom", "1")) {
1173 log_file_path = nvram_safe_get("log_file_path");
1174 argv[argc++] = "-s";
1175 argv[argc++] = rot_siz;
1176 argv[argc++] = "-O";
1177 argv[argc++] = log_file_path;
1178 if (strcmp(nvram_safe_get("log_file_path"), "/var/log/messages") != 0) {
1179 remove("/var/log/messages");
1180 symlink(log_file_path, "/var/log/messages");
1183 else
1185 /* Read options: rotate_size(kb) num_backups logfilename.
1186 * Ignore these settings and use defaults if the logfile cannot be written to.
1188 if (f_read_string("/etc/syslogd.cfg", cfg, sizeof(cfg)) > 0) {
1189 if ((nv = strchr(cfg, '\n')))
1190 *nv = 0;
1192 if ((nv = strtok(cfg, " \t"))) {
1193 if (isdigit(*nv))
1194 rot_siz = nv;
1197 if ((nv = strtok(NULL, " \t")))
1198 b_opt = nv;
1200 if ((nv = strtok(NULL, " \t")) && *nv == '/') {
1201 if (f_write(nv, cfg, 0, FW_APPEND, 0) >= 0) {
1202 argv[argc++] = "-O";
1203 argv[argc++] = nv;
1205 else {
1206 rot_siz = "50";
1207 b_opt = "";
1212 if (nvram_match("log_file_custom", "0")) {
1213 argv[argc++] = "-s";
1214 argv[argc++] = rot_siz;
1215 struct stat sb;
1216 if (lstat("/var/log/messages", &sb) != -1)
1217 if (S_ISLNK(sb.st_mode))
1218 remove("/var/log/messages");
1221 if (isdigit(*b_opt)) {
1222 argv[argc++] = "-b";
1223 argv[argc++] = b_opt;
1224 } else
1225 if (nvram_get_int("log_file_size") > 0) {
1226 argv[argc++] = "-b";
1227 argv[argc++] = rot_keep;
1231 if (argc > 1) {
1232 argv[argc] = NULL;
1233 _eval(argv, NULL, 0, NULL);
1235 argv[0] = "klogd";
1236 argv[1] = NULL;
1237 _eval(argv, NULL, 0, NULL);
1239 // used to be available in syslogd -m
1240 n = nvram_get_int("log_mark");
1241 if (n > 0) {
1242 // n is in minutes
1243 if (n < 60)
1244 sprintf(rem, "*/%d * * * *", n);
1245 else if (n < 60 * 24)
1246 sprintf(rem, "0 */%d * * *", n / 60);
1247 else
1248 sprintf(rem, "0 0 */%d * *", n / (60 * 24));
1249 sprintf(s, "%s logger -p syslog.info -- -- MARK --", rem);
1250 eval("cru", "a", "syslogdmark", s);
1252 else {
1253 eval("cru", "d", "syslogdmark");
1258 void stop_syslog(void)
1260 killall("klogd", SIGTERM);
1261 killall("syslogd", SIGTERM);
1264 // -----------------------------------------------------------------------------
1266 static pid_t pid_igmp = -1;
1268 void start_igmp_proxy(void)
1270 FILE *fp;
1272 pid_igmp = -1;
1273 if (nvram_match("multicast_pass", "1")) {
1274 if (get_wan_proto() == WP_DISABLED)
1275 return;
1277 if (f_exists("/etc/igmp.alt")) {
1278 eval("igmpproxy", "/etc/igmp.alt");
1280 else if ((fp = fopen("/etc/igmp.conf", "w")) != NULL) {
1281 fprintf(fp,
1282 "quickleave\n"
1283 "phyint %s upstream\n"
1284 "\taltnet %s\n",
1285 // "phyint %s downstream ratelimit 0\n",
1286 get_wanface(),
1287 nvram_get("multicast_altnet") ? : "0.0.0.0/0");
1288 // nvram_safe_get("lan_ifname"));
1290 char lanN_ifname[] = "lanXX_ifname";
1291 char multicast_lanN[] = "multicast_lanXX";
1292 char br;
1294 for(br=0 ; br<4 ; br++) {
1295 char bridge[2] = "0";
1296 if (br!=0)
1297 bridge[0]+=br;
1298 else
1299 strcpy(bridge, "");
1301 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1302 sprintf(multicast_lanN, "multicast_lan%s", bridge);
1304 if((strcmp(nvram_safe_get(multicast_lanN),"1")==0) && (strcmp(nvram_safe_get(lanN_ifname),"")!=0)) {
1305 fprintf(fp,
1306 "phyint %s downstream ratelimit 0\n",
1307 nvram_safe_get(lanN_ifname));
1310 fclose(fp);
1311 eval("igmpproxy", "/etc/igmp.conf");
1313 else {
1314 return;
1316 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1317 pid_igmp = -2;
1322 void stop_igmp_proxy(void)
1324 pid_igmp = -1;
1325 killall_tk("igmpproxy");
1328 // -----------------------------------------------------------------------------
1330 void start_udpxy(void)
1332 if (nvram_match("udpxy_enable", "1")) {
1333 if (get_wan_proto() == WP_DISABLED)
1334 return;
1335 eval("udpxy", (nvram_get_int("udpxy_stats") ? "-S" : ""), "-p", nvram_safe_get("udpxy_port"), "-c", nvram_safe_get("udpxy_clients"), "-m", nvram_safe_get("wan_ifname") );
1339 void stop_udpxy(void)
1341 killall_tk("udpxy");
1344 // -----------------------------------------------------------------------------
1346 #ifdef TCONFIG_NOCAT
1348 static pid_t pid_splashd = -1;
1349 void start_splashd(void)
1351 pid_splashd = -1;
1352 start_nocat();
1353 if (!nvram_contains_word("debug_norestart", "splashd")) {
1354 pid_splashd = -2;
1358 void stop_splashd(void)
1360 pid_splashd = -1;
1361 stop_nocat();
1362 start_wan(BOOT);
1364 #endif
1366 // -----------------------------------------------------------------------------
1368 void set_tz(void)
1370 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
1373 void start_ntpc(void)
1375 set_tz();
1377 stop_ntpc();
1379 if (nvram_get_int("ntp_updates") >= 0) {
1380 xstart("ntpsync", "--init");
1384 void stop_ntpc(void)
1386 killall("ntpsync", SIGTERM);
1389 // -----------------------------------------------------------------------------
1391 static void stop_rstats(void)
1393 int n, m;
1394 int pid;
1395 int pidz;
1396 int ppidz;
1397 int w = 0;
1399 n = 60;
1400 m = 15;
1401 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
1402 w = 1;
1403 pidz = pidof("gzip");
1404 if (pidz < 1) pidz = pidof("cp");
1405 ppidz = ppid(ppid(pidz));
1406 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1407 syslog(LOG_DEBUG, "rstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1408 --m;
1409 } else {
1410 kill(pid, SIGTERM);
1412 sleep(1);
1414 if ((w == 1) && (n > 0))
1415 syslog(LOG_DEBUG, "rstats stopped.\n");
1418 static void start_rstats(int new)
1420 if (nvram_match("rstats_enable", "1")) {
1421 stop_rstats();
1422 if (new) {
1423 syslog(LOG_DEBUG, "starting rstats (new datafile).\n");
1424 xstart("rstats", "--new");
1425 } else {
1426 syslog(LOG_DEBUG, "starting rstats.\n");
1427 xstart("rstats");
1432 static void stop_cstats(void)
1434 int n, m;
1435 int pid;
1436 int pidz;
1437 int ppidz;
1438 int w = 0;
1440 n = 60;
1441 m = 15;
1442 while ((n-- > 0) && ((pid = pidof("cstats")) > 0)) {
1443 w = 1;
1444 pidz = pidof("gzip");
1445 if (pidz < 1) pidz = pidof("cp");
1446 ppidz = ppid(ppid(pidz));
1447 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1448 syslog(LOG_DEBUG, "cstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1449 --m;
1450 } else {
1451 kill(pid, SIGTERM);
1453 sleep(1);
1455 if ((w == 1) && (n > 0))
1456 syslog(LOG_DEBUG, "cstats stopped.\n");
1459 static void start_cstats(int new)
1461 if (nvram_match("cstats_enable", "1")) {
1462 stop_cstats();
1463 if (new) {
1464 syslog(LOG_DEBUG, "starting cstats (new datafile).\n");
1465 xstart("cstats", "--new");
1466 } else {
1467 syslog(LOG_DEBUG, "starting cstats.\n");
1468 xstart("cstats");
1473 // -----------------------------------------------------------------------------
1475 // !!TB - FTP Server
1477 #ifdef TCONFIG_FTP
1478 static char *get_full_storage_path(char *val)
1480 static char buf[128];
1481 int len;
1483 if (val[0] == '/')
1484 len = sprintf(buf, "%s", val);
1485 else
1486 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
1488 if (len > 1 && buf[len - 1] == '/')
1489 buf[len - 1] = 0;
1491 return buf;
1494 static char *nvram_storage_path(char *var)
1496 char *val = nvram_safe_get(var);
1497 return get_full_storage_path(val);
1500 char vsftpd_conf[] = "/etc/vsftpd.conf";
1501 char vsftpd_users[] = "/etc/vsftpd.users";
1502 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
1504 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1506 static void start_ftpd(void)
1508 char tmp[256];
1509 FILE *fp, *f;
1510 char *buf;
1511 char *p, *q;
1512 char *user, *pass, *rights, *root_dir;
1513 int i;
1515 if (getpid() != 1) {
1516 start_service("ftpd");
1517 return;
1520 if (!nvram_get_int("ftp_enable")) return;
1522 mkdir_if_none(vsftpd_users);
1523 mkdir_if_none("/var/run/vsftpd");
1525 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
1526 return;
1528 if (nvram_get_int("ftp_super"))
1530 /* rights */
1531 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
1532 if ((f = fopen(tmp, "w")))
1534 fprintf(f,
1535 "dirlist_enable=yes\n"
1536 "write_enable=yes\n"
1537 "download_enable=yes\n");
1538 fclose(f);
1542 #ifdef TCONFIG_SAMBASRV
1543 if (nvram_match("smbd_cset", "utf8"))
1544 fprintf(fp, "utf8=yes\n");
1545 #endif
1547 if (nvram_invmatch("ftp_anonymous", "0"))
1549 fprintf(fp,
1550 "anon_allow_writable_root=yes\n"
1551 "anon_world_readable_only=no\n"
1552 "anon_umask=022\n");
1554 /* rights */
1555 sprintf(tmp, "%s/ftp", vsftpd_users);
1556 if ((f = fopen(tmp, "w")))
1558 if (nvram_match("ftp_dirlist", "0"))
1559 fprintf(f, "dirlist_enable=yes\n");
1560 if (nvram_match("ftp_anonymous", "1") ||
1561 nvram_match("ftp_anonymous", "3"))
1562 fprintf(f, "write_enable=yes\n");
1563 if (nvram_match("ftp_anonymous", "1") ||
1564 nvram_match("ftp_anonymous", "2"))
1565 fprintf(f, "download_enable=yes\n");
1566 fclose(f);
1568 if (nvram_match("ftp_anonymous", "1") ||
1569 nvram_match("ftp_anonymous", "3"))
1570 fprintf(fp,
1571 "anon_upload_enable=yes\n"
1572 "anon_mkdir_write_enable=yes\n"
1573 "anon_other_write_enable=yes\n");
1574 } else {
1575 fprintf(fp, "anonymous_enable=no\n");
1578 fprintf(fp,
1579 "dirmessage_enable=yes\n"
1580 "download_enable=no\n"
1581 "dirlist_enable=no\n"
1582 "hide_ids=yes\n"
1583 "syslog_enable=yes\n"
1584 "local_enable=yes\n"
1585 "local_umask=022\n"
1586 "chmod_enable=no\n"
1587 "chroot_local_user=yes\n"
1588 "check_shell=no\n"
1589 "log_ftp_protocol=%s\n"
1590 "user_config_dir=%s\n"
1591 "passwd_file=%s\n"
1592 "listen%s=yes\n"
1593 "listen_port=%s\n"
1594 "background=yes\n"
1595 "isolate=no\n"
1596 "max_clients=%d\n"
1597 "max_per_ip=%d\n"
1598 "max_login_fails=1\n"
1599 "idle_session_timeout=%s\n"
1600 "use_sendfile=no\n"
1601 "anon_max_rate=%d\n"
1602 "local_max_rate=%d\n"
1603 "%s\n",
1604 nvram_get_int("log_ftp") ? "yes" : "no",
1605 vsftpd_users, vsftpd_passwd,
1606 #ifdef TCONFIG_IPV6
1607 ipv6_enabled() ? "_ipv6" : "",
1608 #else
1610 #endif
1611 nvram_get("ftp_port") ? : "21",
1612 nvram_get_int("ftp_max"),
1613 nvram_get_int("ftp_ipmax"),
1614 nvram_get("ftp_staytimeout") ? : "300",
1615 nvram_get_int("ftp_anonrate") * 1024,
1616 nvram_get_int("ftp_rate") * 1024,
1617 nvram_safe_get("ftp_custom"));
1619 fclose(fp);
1621 /* prepare passwd file and default users */
1622 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
1623 return;
1625 if (((user = nvram_get("http_username")) == NULL) || (*user == 0)) user = "admin";
1626 if (((pass = nvram_get("http_passwd")) == NULL) || (*pass == 0)) pass = "admin";
1628 fprintf(fp, /* anonymous, admin, nobody */
1629 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1630 "%s:%s:0:0:root:/:/sbin/nologin\n"
1631 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1632 nvram_storage_path("ftp_anonroot"), user,
1633 nvram_get_int("ftp_super") ? crypt(pass, "$1$") : "x",
1634 MOUNT_ROOT);
1636 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
1639 username<password<rights[<root_dir>]
1640 rights:
1641 Read/Write
1642 Read Only
1643 View Only
1644 Private
1646 p = buf;
1647 while ((q = strsep(&p, ">")) != NULL) {
1648 i = vstrsep(q, "<", &user, &pass, &rights, &root_dir);
1649 if (i < 3 || i > 4) continue;
1650 if (!user || !pass) continue;
1652 if (i == 3 || !root_dir || !(*root_dir))
1654 root_dir = nvram_safe_get("ftp_pubroot");
1656 /* directory */
1657 if (strncmp(rights, "Private", 7) == 0)
1659 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
1660 mkdir_if_none(tmp);
1662 else
1663 sprintf(tmp, "%s", get_full_storage_path(root_dir));
1665 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1666 user, crypt(pass, "$1$"), user, tmp);
1668 /* rights */
1669 sprintf(tmp, "%s/%s", vsftpd_users, user);
1670 if ((f = fopen(tmp, "w")))
1672 tmp[0] = 0;
1673 if (nvram_invmatch("ftp_dirlist", "1"))
1674 strcat(tmp, "dirlist_enable=yes\n");
1675 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
1676 strcat(tmp, "download_enable=yes\n");
1677 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
1678 strcat(tmp, "write_enable=yes\n");
1680 fputs(tmp, f);
1681 fclose(f);
1684 free(buf);
1687 fclose(fp);
1688 killall("vsftpd", SIGHUP);
1690 /* start vsftpd if it's not already running */
1691 if (pidof("vsftpd") <= 0)
1692 xstart("vsftpd");
1695 static void stop_ftpd(void)
1697 if (getpid() != 1) {
1698 stop_service("ftpd");
1699 return;
1702 killall_tk("vsftpd");
1703 unlink(vsftpd_passwd);
1704 unlink(vsftpd_conf);
1705 eval("rm", "-rf", vsftpd_users);
1707 #endif // TCONFIG_FTP
1709 // -----------------------------------------------------------------------------
1711 // !!TB - Samba
1713 #ifdef TCONFIG_SAMBASRV
1714 static void kill_samba(int sig)
1716 if (sig == SIGTERM) {
1717 killall_tk("smbd");
1718 killall_tk("nmbd");
1720 else {
1721 killall("smbd", sig);
1722 killall("nmbd", sig);
1726 static void start_samba(void)
1728 FILE *fp;
1729 DIR *dir = NULL;
1730 struct dirent *dp;
1731 char nlsmod[15];
1732 int mode;
1733 char *nv;
1735 if (getpid() != 1) {
1736 start_service("smbd");
1737 return;
1740 mode = nvram_get_int("smbd_enable");
1741 if (!mode || !nvram_invmatch("lan_hostname", ""))
1742 return;
1744 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
1745 return;
1747 fprintf(fp, "[global]\n"
1748 " interfaces = %s\n"
1749 " bind interfaces only = yes\n"
1750 " workgroup = %s\n"
1751 " netbios name = %s\n"
1752 " server string = %s\n"
1753 " guest account = nobody\n"
1754 " security = user\n"
1755 " %s\n"
1756 " guest ok = %s\n"
1757 " guest only = no\n"
1758 " browseable = yes\n"
1759 " syslog only = yes\n"
1760 " timestamp logs = no\n"
1761 " syslog = 1\n"
1762 " encrypt passwords = yes\n"
1763 " preserve case = yes\n"
1764 " short preserve case = yes\n",
1765 nvram_safe_get("lan_ifname"),
1766 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1767 nvram_safe_get("lan_hostname"),
1768 nvram_get("router_name") ? : "Tomato",
1769 mode == 2 ? "" : "map to guest = Bad User",
1770 mode == 2 ? "no" : "yes" // guest ok
1773 if (nvram_get_int("smbd_wins")) {
1774 nv = nvram_safe_get("wan_wins");
1775 if ((*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
1776 fprintf(fp, " wins support = yes\n");
1780 if (nvram_get_int("smbd_master")) {
1781 fprintf(fp,
1782 " domain master = yes\n"
1783 " local master = yes\n"
1784 " preferred master = yes\n"
1785 " os level = 65\n");
1788 nv = nvram_safe_get("smbd_cpage");
1789 if (*nv) {
1790 #ifndef TCONFIG_SAMBA3
1791 fprintf(fp, " client code page = %s\n", nv);
1792 #endif
1793 sprintf(nlsmod, "nls_cp%s", nv);
1795 nv = nvram_safe_get("smbd_nlsmod");
1796 if ((*nv) && (strcmp(nv, nlsmod) != 0))
1797 modprobe_r(nv);
1799 modprobe(nlsmod);
1800 nvram_set("smbd_nlsmod", nlsmod);
1803 #ifndef TCONFIG_SAMBA3
1804 if (nvram_match("smbd_cset", "utf8"))
1805 fprintf(fp, " coding system = utf8\n");
1806 else if (nvram_invmatch("smbd_cset", ""))
1807 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1808 #endif
1810 nv = nvram_safe_get("smbd_custom");
1811 /* add socket options unless overriden by the user */
1812 if (strstr(nv, "socket options") == NULL) {
1813 fprintf(fp, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1815 fprintf(fp, "%s\n\n", nv);
1817 /* configure shares */
1819 char *buf;
1820 char *p, *q;
1821 char *name, *path, *comment, *writeable, *hidden;
1822 int cnt = 0;
1824 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1826 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1828 p = buf;
1829 while ((q = strsep(&p, ">")) != NULL) {
1830 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1831 if (!path || !name) continue;
1833 /* share name */
1834 fprintf(fp, "\n[%s]\n", name);
1836 /* path */
1837 fprintf(fp, " path = %s\n", path);
1839 /* access level */
1840 if (!strcmp(writeable, "1"))
1841 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1842 if (!strcmp(hidden, "1"))
1843 fprintf(fp, " browseable = no\n");
1845 /* comment */
1846 if (comment)
1847 fprintf(fp, " comment = %s\n", comment);
1849 cnt++;
1851 free(buf);
1854 /* Share every mountpoint below MOUNT_ROOT */
1855 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1856 while ((dp = readdir(dir))) {
1857 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1859 /* Only if is a directory and is mounted */
1860 if (!dir_is_mountpoint(MOUNT_ROOT, dp->d_name))
1861 continue;
1863 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1864 fprintf(fp, "\n[%s]\n path = %s/%s\n comment = %s\n",
1865 dp->d_name, MOUNT_ROOT, dp->d_name, dp->d_name);
1866 if (nvram_match("smbd_autoshare", "3")) // Hidden
1867 fprintf(fp, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1868 dp->d_name, MOUNT_ROOT, dp->d_name);
1869 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1870 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1872 cnt++;
1876 if (dir) closedir(dir);
1878 if (cnt == 0) {
1879 /* by default share MOUNT_ROOT as read-only */
1880 fprintf(fp, "\n[share]\n"
1881 " path = %s\n"
1882 " writable = no\n",
1883 MOUNT_ROOT);
1886 fclose(fp);
1888 mkdir_if_none("/var/run/samba");
1889 mkdir_if_none("/etc/samba");
1891 /* write smbpasswd */
1892 #ifdef TCONFIG_SAMBA3
1893 eval("smbpasswd", "nobody", "\"\"");
1894 #else
1895 eval("smbpasswd", "-a", "nobody", "\"\"");
1896 #endif
1897 if (mode == 2) {
1898 char *smbd_user;
1899 if (((smbd_user = nvram_get("smbd_user")) == NULL) || (*smbd_user == 0) || !strcmp(smbd_user, "root"))
1900 smbd_user = "nas";
1901 #ifdef TCONFIG_SAMBA3
1902 eval("smbpasswd", smbd_user, nvram_safe_get("smbd_passwd"));
1903 #else
1904 eval("smbpasswd", "-a", smbd_user, nvram_safe_get("smbd_passwd"));
1905 #endif
1908 kill_samba(SIGHUP);
1909 int ret1 = 0, ret2 = 0;
1910 /* start samba if it's not already running */
1911 if (pidof("nmbd") <= 0)
1912 ret1 = xstart("nmbd", "-D");
1913 if (pidof("smbd") <= 0)
1914 ret2 = xstart("smbd", "-D");
1916 if (ret1 || ret2) kill_samba(SIGTERM);
1919 static void stop_samba(void)
1921 if (getpid() != 1) {
1922 stop_service("smbd");
1923 return;
1926 kill_samba(SIGTERM);
1927 /* clean up */
1928 unlink("/var/log/smb");
1929 unlink("/var/log/nmb");
1930 eval("rm", "-rf", "/var/run/samba");
1932 #endif // TCONFIG_SAMBASRV
1934 #ifdef TCONFIG_MEDIA_SERVER
1935 #define MEDIA_SERVER_APP "minidlna"
1937 static void start_media_server(void)
1939 FILE *f;
1940 int port, pid, https;
1941 char *dbdir;
1942 char *argv[] = { MEDIA_SERVER_APP, "-f", "/etc/"MEDIA_SERVER_APP".conf", "-R", NULL };
1943 static int once = 1;
1945 if (getpid() != 1) {
1946 start_service("media");
1947 return;
1950 if (nvram_get_int("ms_sas") == 0)
1951 once = 0;
1953 if (nvram_get_int("ms_enable") != 0) {
1954 if ((!once) && (nvram_get_int("ms_rescan") == 0)) {
1955 // no forced rescan
1956 argv[3] = NULL;
1958 nvram_unset("ms_rescan");
1960 if (f_exists("/etc/"MEDIA_SERVER_APP".alt")) {
1961 argv[2] = "/etc/"MEDIA_SERVER_APP".alt";
1963 else {
1964 if ((f = fopen(argv[2], "w")) != NULL) {
1965 port = nvram_get_int("ms_port");
1966 https = nvram_get_int("https_enable");
1967 dbdir = nvram_safe_get("ms_dbdir");
1968 if (!(*dbdir)) dbdir = NULL;
1969 mkdir_if_none(dbdir ? : "/var/run/"MEDIA_SERVER_APP);
1971 fprintf(f,
1972 "network_interface=%s\n"
1973 "port=%d\n"
1974 "friendly_name=%s\n"
1975 "db_dir=%s/.db\n"
1976 "enable_tivo=%s\n"
1977 "strict_dlna=%s\n"
1978 "presentation_url=http%s://%s:%s/nas-media.asp\n"
1979 "inotify=yes\n"
1980 "notify_interval=600\n"
1981 "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"
1982 "\n",
1983 nvram_safe_get("lan_ifname"),
1984 (port < 0) || (port >= 0xffff) ? 0 : port,
1985 nvram_get("router_name") ? : "Tomato",
1986 dbdir ? : "/var/run/"MEDIA_SERVER_APP,
1987 nvram_get_int("ms_tivo") ? "yes" : "no",
1988 nvram_get_int("ms_stdlna") ? "yes" : "no",
1989 https ? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https ? "https_lanport" : "http_lanport")
1992 // media directories
1993 char *buf, *p, *q;
1994 char *path, *restrict;
1996 if ((buf = strdup(nvram_safe_get("ms_dirs"))) != NULL) {
1997 /* path<restrict[A|V|P|] */
1999 p = buf;
2000 while ((q = strsep(&p, ">")) != NULL) {
2001 if (vstrsep(q, "<", &path, &restrict) < 1 || !path || !(*path))
2002 continue;
2003 fprintf(f, "media_dir=%s%s%s\n",
2004 restrict ? : "", (restrict && *restrict) ? "," : "", path);
2006 free(buf);
2009 fclose(f);
2013 /* start media server if it's not already running */
2014 if (pidof(MEDIA_SERVER_APP) <= 0) {
2015 if ((_eval(argv, NULL, 0, &pid) == 0) && (once)) {
2016 /* If we started the media server successfully, wait 1 sec
2017 * to let it die if it can't open the database file.
2018 * If it's still alive after that, assume it's running and
2019 * disable forced once-after-reboot rescan.
2021 sleep(1);
2022 if (pidof(MEDIA_SERVER_APP) > 0)
2023 once = 0;
2029 static void stop_media_server(void)
2031 if (getpid() != 1) {
2032 stop_service("media");
2033 return;
2036 killall_tk(MEDIA_SERVER_APP);
2038 #endif // TCONFIG_MEDIA_SERVER
2040 #ifdef TCONFIG_USB
2041 static void start_nas_services(void)
2043 if (getpid() != 1) {
2044 start_service("usbapps");
2045 return;
2048 #ifdef TCONFIG_SAMBASRV
2049 start_samba();
2050 #endif
2051 #ifdef TCONFIG_FTP
2052 start_ftpd();
2053 #endif
2054 #ifdef TCONFIG_MEDIA_SERVER
2055 start_media_server();
2056 #endif
2059 static void stop_nas_services(void)
2061 if (getpid() != 1) {
2062 stop_service("usbapps");
2063 return;
2066 #ifdef TCONFIG_MEDIA_SERVER
2067 stop_media_server();
2068 #endif
2069 #ifdef TCONFIG_FTP
2070 stop_ftpd();
2071 #endif
2072 #ifdef TCONFIG_SAMBASRV
2073 stop_samba();
2074 #endif
2077 void restart_nas_services(int stop, int start)
2079 int fd = file_lock("usb");
2080 /* restart all NAS applications */
2081 if (stop)
2082 stop_nas_services();
2083 if (start)
2084 start_nas_services();
2085 file_unlock(fd);
2087 #endif // TCONFIG_USB
2089 // -----------------------------------------------------------------------------
2091 /* -1 = Don't check for this program, it is not expected to be running.
2092 * Other = This program has been started and should be kept running. If no
2093 * process with the name is running, call func to restart it.
2094 * Note: At startup, dnsmasq forks a short-lived child which forks a
2095 * long-lived (grand)child. The parents terminate.
2096 * Many daemons use this technique.
2098 static void _check(pid_t pid, const char *name, void (*func)(void))
2100 if (pid == -1) return;
2102 if (pidof(name) > 0) return;
2104 syslog(LOG_DEBUG, "%s terminated unexpectedly, restarting.\n", name);
2105 func();
2107 // Force recheck in 500 msec
2108 setitimer(ITIMER_REAL, &pop_tv, NULL);
2111 void check_services(void)
2113 TRACE_PT("keep alive\n");
2115 // Periodically reap any zombies
2116 setitimer(ITIMER_REAL, &zombie_tv, NULL);
2118 #ifdef LINUX26
2119 _check(pid_hotplug2, "hotplug2", start_hotplug2);
2120 #endif
2121 _check(pid_dnsmasq, "dnsmasq", start_dnsmasq);
2122 _check(pid_crond, "crond", start_cron);
2123 _check(pid_igmp, "igmpproxy", start_igmp_proxy);
2125 //#ifdef TCONFIG_NOCAT
2126 // if (nvram_get_int("NC_enable"))
2127 // _check(&pid_splashd, "splashd", start_splashd);
2128 //#endif
2132 // -----------------------------------------------------------------------------
2134 void start_services(void)
2136 static int once = 1;
2138 if (once) {
2139 once = 0;
2141 if (nvram_get_int("telnetd_eas")) start_telnetd();
2142 if (nvram_get_int("sshd_eas")) start_sshd();
2145 // start_syslog();
2146 start_nas();
2147 start_zebra();
2148 #ifdef TCONFIG_SDHC
2149 start_mmc();
2150 #endif
2151 start_dnsmasq();
2152 start_cifs();
2153 start_httpd();
2154 start_cron();
2155 // start_upnp();
2156 start_rstats(0);
2157 start_cstats(0);
2158 start_sched();
2159 #ifdef TCONFIG_PPTPD
2160 start_pptpd();
2161 #endif
2162 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
2164 #ifdef TCONFIG_SNMP
2165 start_snmp();
2166 #endif
2168 start_tomatoanon();
2170 #ifdef TCONFIG_TOR
2171 start_tor();
2172 #endif
2174 #ifdef TCONFIG_BT
2175 start_bittorrent();
2176 #endif
2178 #ifdef TCONFIG_NOCAT
2179 start_splashd();
2180 #endif
2182 #ifdef TCONFIG_NFS
2183 start_nfs();
2184 #endif
2187 void stop_services(void)
2189 clear_resolv();
2191 #ifdef TCONFIG_BT
2192 stop_bittorrent();
2193 #endif
2195 #ifdef TCONFIG_NOCAT
2196 stop_splashd();
2197 #endif
2199 #ifdef TCONFIG_SNMP
2200 stop_snmp();
2201 #endif
2203 #ifdef TCONFIG_TOR
2204 stop_tor();
2205 #endif
2207 stop_tomatoanon();
2209 #ifdef TCONFIG_NFS
2210 stop_nfs();
2211 #endif
2212 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2213 #ifdef TCONFIG_PPTPD
2214 stop_pptpd();
2215 #endif
2216 stop_sched();
2217 stop_rstats();
2218 stop_cstats();
2219 // stop_upnp();
2220 stop_cron();
2221 stop_httpd();
2222 #ifdef TCONFIG_SDHC
2223 stop_mmc();
2224 #endif
2225 stop_cifs();
2226 stop_dnsmasq();
2227 stop_zebra();
2228 stop_nas();
2229 // stop_syslog();
2232 // -----------------------------------------------------------------------------
2234 /* nvram "action_service" is: "service-action[-modifier]"
2235 * action is something like "stop" or "start" or "restart"
2236 * optional modifier is "c" for the "service" command-line command
2238 void exec_service(void)
2240 const int A_START = 1;
2241 const int A_STOP = 2;
2242 const int A_RESTART = 1|2;
2243 char buffer[128];
2244 char *service;
2245 char *act;
2246 char *next;
2247 char *modifier;
2248 int action, user;
2249 int i;
2251 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
2252 next = buffer;
2254 TOP:
2255 act = strsep(&next, ",");
2256 service = strsep(&act, "-");
2257 if (act == NULL) {
2258 next = NULL;
2259 goto CLEAR;
2261 modifier = act;
2262 strsep(&modifier, "-");
2264 TRACE_PT("service=%s action=%s modifier=%s\n", service, act, modifier ? : "");
2266 if (strcmp(act, "start") == 0) action = A_START;
2267 else if (strcmp(act, "stop") == 0) action = A_STOP;
2268 else if (strcmp(act, "restart") == 0) action = A_RESTART;
2269 else action = 0;
2270 user = (modifier != NULL && *modifier == 'c');
2272 if (strcmp(service, "dhcpc") == 0) {
2273 if (action & A_STOP) stop_dhcpc();
2274 if (action & A_START) start_dhcpc();
2275 goto CLEAR;
2278 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
2279 if (action & A_STOP) stop_dnsmasq();
2280 if (action & A_START) {
2281 dns_to_resolv();
2282 start_dnsmasq();
2284 goto CLEAR;
2287 if (strcmp(service, "firewall") == 0) {
2288 if (action & A_STOP) {
2289 stop_firewall();
2290 stop_igmp_proxy();
2291 stop_udpxy();
2293 if (action & A_START) {
2294 start_firewall();
2295 start_igmp_proxy();
2296 start_udpxy();
2298 goto CLEAR;
2301 if (strcmp(service, "restrict") == 0) {
2302 if (action & A_STOP) {
2303 stop_firewall();
2305 if (action & A_START) {
2306 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
2308 start_firewall();
2310 // if radio was disabled by access restriction, but no rule is handling it now, enable it
2311 if (i == 1) {
2312 if (nvram_get_int("rrules_radio") < 0) {
2313 eval("radio", "on");
2317 goto CLEAR;
2320 if (strcmp(service, "arpbind") == 0) {
2321 if (action & A_STOP) stop_arpbind();
2322 if (action & A_START) start_arpbind();
2323 goto CLEAR;
2326 if (strcmp(service, "qos") == 0) {
2327 if (action & A_STOP) {
2328 stop_qos();
2330 stop_firewall(); start_firewall(); // always restarted
2331 if (action & A_START) {
2332 start_qos();
2333 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
2335 goto CLEAR;
2338 if (strcmp(service, "qoslimit") == 0) {
2339 if (action & A_STOP) {
2340 new_qoslimit_stop();
2342 #ifdef TCONFIG_NOCAT
2343 stop_splashd();
2344 #endif
2345 stop_firewall(); start_firewall(); // always restarted
2346 if (action & A_START) {
2347 new_qoslimit_start();
2349 #ifdef TCONFIG_NOCAT
2350 start_splashd();
2351 #endif
2352 goto CLEAR;
2355 if (strcmp(service, "upnp") == 0) {
2356 if (action & A_STOP) {
2357 stop_upnp();
2359 stop_firewall(); start_firewall(); // always restarted
2360 if (action & A_START) {
2361 start_upnp();
2363 goto CLEAR;
2366 if (strcmp(service, "telnetd") == 0) {
2367 if (action & A_STOP) stop_telnetd();
2368 if (action & A_START) start_telnetd();
2369 goto CLEAR;
2372 if (strcmp(service, "sshd") == 0) {
2373 if (action & A_STOP) stop_sshd();
2374 if (action & A_START) start_sshd();
2375 goto CLEAR;
2378 if (strcmp(service, "httpd") == 0) {
2379 if (action & A_STOP) stop_httpd();
2380 if (action & A_START) start_httpd();
2381 goto CLEAR;
2384 #ifdef TCONFIG_IPV6
2385 if (strcmp(service, "ipv6") == 0) {
2386 if (action & A_STOP) {
2387 stop_dnsmasq();
2388 stop_ipv6();
2390 if (action & A_START) {
2391 start_ipv6();
2392 start_dnsmasq();
2394 goto CLEAR;
2397 if (strncmp(service, "dhcp6", 5) == 0) {
2398 if (action & A_STOP) {
2399 stop_dhcp6c();
2401 if (action & A_START) {
2402 start_dhcp6c();
2404 goto CLEAR;
2406 #endif
2408 if (strcmp(service, "admin") == 0) {
2409 if (action & A_STOP) {
2410 stop_sshd();
2411 stop_telnetd();
2412 stop_httpd();
2414 stop_firewall(); start_firewall(); // always restarted
2415 if (action & A_START) {
2416 start_httpd();
2417 create_passwd();
2418 if (nvram_match("telnetd_eas", "1")) start_telnetd();
2419 if (nvram_match("sshd_eas", "1")) start_sshd();
2421 goto CLEAR;
2424 if (strcmp(service, "ddns") == 0) {
2425 if (action & A_STOP) stop_ddns();
2426 if (action & A_START) start_ddns();
2427 goto CLEAR;
2430 if (strcmp(service, "ntpc") == 0) {
2431 if (action & A_STOP) stop_ntpc();
2432 if (action & A_START) start_ntpc();
2433 goto CLEAR;
2436 if (strcmp(service, "logging") == 0) {
2437 if (action & A_STOP) {
2438 stop_syslog();
2440 if (action & A_START) {
2441 start_syslog();
2443 if (!user) {
2444 // always restarted except from "service" command
2445 stop_cron(); start_cron();
2446 stop_firewall(); start_firewall();
2448 goto CLEAR;
2451 if (strcmp(service, "crond") == 0) {
2452 if (action & A_STOP) {
2453 stop_cron();
2455 if (action & A_START) {
2456 start_cron();
2458 goto CLEAR;
2461 #ifdef LINUX26
2462 if (strncmp(service, "hotplug", 7) == 0) {
2463 if (action & A_STOP) {
2464 stop_hotplug2();
2466 if (action & A_START) {
2467 start_hotplug2(1);
2469 goto CLEAR;
2471 #endif
2473 if (strcmp(service, "upgrade") == 0) {
2474 if (action & A_START) {
2475 #if TOMATO_SL
2476 stop_usbevent();
2477 stop_smbd();
2478 #endif
2479 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2480 stop_jffs2();
2481 // stop_cifs();
2482 stop_zebra();
2483 stop_cron();
2484 stop_ntpc();
2485 stop_upnp();
2486 // stop_dhcpc();
2487 killall("rstats", SIGTERM);
2488 killall("cstats", SIGTERM);
2489 killall("buttons", SIGTERM);
2490 stop_syslog();
2491 remove_storage_main(1); // !!TB - USB Support
2492 stop_usb(); // !!TB - USB Support
2494 goto CLEAR;
2497 #ifdef TCONFIG_CIFS
2498 if (strcmp(service, "cifs") == 0) {
2499 if (action & A_STOP) stop_cifs();
2500 if (action & A_START) start_cifs();
2501 goto CLEAR;
2503 #endif
2505 #ifdef TCONFIG_JFFS2
2506 if (strncmp(service, "jffs", 4) == 0) {
2507 if (action & A_STOP) stop_jffs2();
2508 if (action & A_START) start_jffs2();
2509 goto CLEAR;
2511 #endif
2513 if (strcmp(service, "zebra") == 0) {
2514 if (action & A_STOP) stop_zebra();
2515 if (action & A_START) start_zebra();
2516 goto CLEAR;
2519 #ifdef TCONFIG_SDHC
2520 if (strcmp(service, "mmc") == 0) {
2521 if (action & A_STOP) stop_mmc();
2522 if (action & A_START) start_mmc();
2523 goto CLEAR;
2525 #endif
2527 if (strcmp(service, "routing") == 0) {
2528 if (action & A_STOP) {
2529 stop_zebra();
2530 do_static_routes(0); // remove old '_saved'
2531 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2532 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2533 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), "0");
2534 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2535 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), "0");
2536 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2537 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), "0");
2539 stop_firewall();
2540 start_firewall();
2541 if (action & A_START) {
2542 do_static_routes(1); // add new
2543 start_zebra();
2544 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2545 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2546 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), nvram_safe_get("lan1_stp"));
2547 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2548 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), nvram_safe_get("lan2_stp"));
2549 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2550 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), nvram_safe_get("lan3_stp"));
2552 goto CLEAR;
2555 if (strcmp(service, "ctnf") == 0) {
2556 if (action & A_START) {
2557 setup_conntrack();
2558 stop_firewall();
2559 start_firewall();
2561 goto CLEAR;
2564 if (strcmp(service, "wan") == 0) {
2565 if (action & A_STOP) {
2566 stop_wan();
2569 if (action & A_START) {
2570 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2571 start_wan(BOOT);
2572 sleep(2);
2573 force_to_dial();
2575 goto CLEAR;
2578 if (strcmp(service, "net") == 0) {
2579 if (action & A_STOP) {
2580 #ifdef TCONFIG_USB
2581 stop_nas_services();
2582 #endif
2583 stop_httpd();
2584 stop_dnsmasq();
2585 stop_nas();
2586 stop_wan();
2587 stop_arpbind();
2588 stop_lan();
2589 stop_vlan();
2591 if (action & A_START) {
2592 start_vlan();
2593 start_lan();
2594 start_arpbind();
2595 start_wan(BOOT);
2596 start_nas();
2597 start_dnsmasq();
2598 start_httpd();
2599 start_wl();
2600 #ifdef TCONFIG_USB
2601 start_nas_services();
2602 #endif
2604 goto CLEAR;
2607 if (strcmp(service, "wireless") == 0) {
2608 if(action & A_STOP) {
2609 stop_wireless();
2611 if(action & A_START) {
2612 start_wireless();
2614 goto CLEAR;
2617 if (strcmp(service, "wl") == 0) {
2618 if(action & A_STOP) {
2619 stop_wireless();
2620 unload_wl();
2622 if(action & A_START) {
2623 load_wl();
2624 start_wireless();
2625 stop_wireless();
2626 start_wireless();
2628 goto CLEAR;
2631 if (strcmp(service, "nas") == 0) {
2632 if (action & A_STOP) {
2633 stop_nas();
2635 if (action & A_START) {
2636 start_nas();
2637 start_wl();
2639 goto CLEAR;
2642 if (strcmp(service, "rstats") == 0) {
2643 if (action & A_STOP) stop_rstats();
2644 if (action & A_START) start_rstats(0);
2645 goto CLEAR;
2648 if (strcmp(service, "rstatsnew") == 0) {
2649 if (action & A_STOP) stop_rstats();
2650 if (action & A_START) start_rstats(1);
2651 goto CLEAR;
2654 if (strcmp(service, "cstats") == 0) {
2655 if (action & A_STOP) stop_cstats();
2656 if (action & A_START) start_cstats(0);
2657 goto CLEAR;
2660 if (strcmp(service, "cstatsnew") == 0) {
2661 if (action & A_STOP) stop_cstats();
2662 if (action & A_START) start_cstats(1);
2663 goto CLEAR;
2666 if (strcmp(service, "sched") == 0) {
2667 if (action & A_STOP) stop_sched();
2668 if (action & A_START) start_sched();
2669 goto CLEAR;
2672 #ifdef TCONFIG_BT
2673 if (strcmp(service, "bittorrent") == 0) {
2674 if (action & A_STOP) {
2675 stop_bittorrent();
2677 stop_firewall(); start_firewall(); // always restarted
2678 if (action & A_START) {
2679 start_bittorrent();
2681 goto CLEAR;
2683 #endif
2685 #ifdef TCONFIG_NFS
2686 if (strcmp(service, "nfs") == 0) {
2687 if (action & A_STOP) stop_nfs();
2688 if (action & A_START) start_nfs();
2689 goto CLEAR;
2691 #endif
2693 #ifdef TCONFIG_SNMP
2694 if (strcmp(service, "snmp") == 0) {
2695 if (action & A_STOP) stop_snmp();
2696 if (action & A_START) start_snmp();
2697 goto CLEAR;
2699 #endif
2701 #ifdef TCONFIG_TOR
2702 if (strcmp(service, "tor") == 0) {
2703 if (action & A_STOP) stop_tor();
2705 stop_firewall(); start_firewall(); // always restarted
2707 if (action & A_START) start_tor();
2708 goto CLEAR;
2710 #endif
2712 #ifdef TCONFIG_UPS
2713 if (strcmp(service, "ups") == 0) {
2714 if (action & A_STOP) stop_ups();
2715 if (action & A_START) start_ups();
2716 goto CLEAR;
2718 #endif
2720 if (strcmp(service, "tomatoanon") == 0) {
2721 if (action & A_STOP) stop_tomatoanon();
2722 if (action & A_START) start_tomatoanon();
2723 goto CLEAR;
2726 #ifdef TCONFIG_USB
2727 // !!TB - USB Support
2728 if (strcmp(service, "usb") == 0) {
2729 if (action & A_STOP) stop_usb();
2730 if (action & A_START) {
2731 start_usb();
2732 // restart Samba and ftp since they may be killed by stop_usb()
2733 restart_nas_services(0, 1);
2734 // remount all partitions by simulating hotplug event
2735 add_remove_usbhost("-1", 1);
2737 goto CLEAR;
2740 if (strcmp(service, "usbapps") == 0) {
2741 if (action & A_STOP) stop_nas_services();
2742 if (action & A_START) start_nas_services();
2743 goto CLEAR;
2745 #endif
2747 #ifdef TCONFIG_FTP
2748 // !!TB - FTP Server
2749 if (strcmp(service, "ftpd") == 0) {
2750 if (action & A_STOP) stop_ftpd();
2751 setup_conntrack();
2752 stop_firewall();
2753 start_firewall();
2754 if (action & A_START) start_ftpd();
2755 goto CLEAR;
2757 #endif
2759 #ifdef TCONFIG_MEDIA_SERVER
2760 if (strcmp(service, "media") == 0 || strcmp(service, "dlna") == 0) {
2761 if (action & A_STOP) stop_media_server();
2762 if (action & A_START) start_media_server();
2763 goto CLEAR;
2765 #endif
2767 #ifdef TCONFIG_SAMBASRV
2768 // !!TB - Samba
2769 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
2770 if (action & A_STOP) stop_samba();
2771 if (action & A_START) {
2772 create_passwd();
2773 stop_dnsmasq();
2774 start_dnsmasq();
2775 start_samba();
2777 goto CLEAR;
2779 #endif
2781 #ifdef TCONFIG_OPENVPN
2782 if (strncmp(service, "vpnclient", 9) == 0) {
2783 if (action & A_STOP) stop_vpnclient(atoi(&service[9]));
2784 if (action & A_START) start_vpnclient(atoi(&service[9]));
2785 goto CLEAR;
2788 if (strncmp(service, "vpnserver", 9) == 0) {
2789 if (action & A_STOP) stop_vpnserver(atoi(&service[9]));
2790 if (action & A_START) start_vpnserver(atoi(&service[9]));
2791 goto CLEAR;
2793 #endif
2795 #ifdef TCONFIG_NOCAT
2796 if (strcmp(service, "splashd") == 0) {
2797 if (action & A_STOP) stop_splashd();
2798 if (action & A_START) start_splashd();
2799 goto CLEAR;
2801 #endif
2803 #ifdef TCONFIG_PPTPD
2804 if (strcmp(service, "pptpd") == 0) {
2805 if (action & A_STOP) stop_pptpd();
2806 if (action & A_START) start_pptpd();
2807 goto CLEAR;
2809 #endif
2811 #ifdef TCONFIG_PPTPD
2812 if (strcmp(service, "pptpclient") == 0) {
2813 if (action & A_STOP) stop_pptp_client();
2814 if (action & A_START) start_pptp_client();
2815 if (action & (A_START | A_STOP))
2817 stop_dnsmasq();
2818 dns_to_resolv();
2819 start_dnsmasq();
2820 if ((action & A_START) == 0)
2821 clear_pptp_route();
2823 goto CLEAR;
2825 #endif
2827 CLEAR:
2828 if (next) goto TOP;
2830 // some functions check action_service and must be cleared at end -- zzz
2831 nvram_set("action_service", "");
2833 // Force recheck in 500 msec
2834 setitimer(ITIMER_REAL, &pop_tv, NULL);
2837 static void do_service(const char *name, const char *action, int user)
2839 int n;
2840 char s[64];
2842 n = 150;
2843 while (!nvram_match("action_service", "")) {
2844 if (user) {
2845 putchar('*');
2846 fflush(stdout);
2848 else if (--n < 0) break;
2849 usleep(100 * 1000);
2852 snprintf(s, sizeof(s), "%s-%s%s", name, action, (user ? "-c" : ""));
2853 nvram_set("action_service", s);
2855 if (nvram_match("debug_rc_svc", "1")) {
2856 nvram_unset("debug_rc_svc");
2857 exec_service();
2858 } else {
2859 kill(1, SIGUSR1);
2862 n = 150;
2863 while (nvram_match("action_service", s)) {
2864 if (user) {
2865 putchar('.');
2866 fflush(stdout);
2868 else if (--n < 0) {
2869 break;
2871 usleep(100 * 1000);
2875 int service_main(int argc, char *argv[])
2877 if (argc != 3) usage_exit(argv[0], "<service> <action>");
2878 do_service(argv[1], argv[2], 1);
2879 printf("\nDone.\n");
2880 return 0;
2883 void start_service(const char *name)
2885 do_service(name, "start", 0);
2888 void stop_service(const char *name)
2890 do_service(name, "stop", 0);
2894 void restart_service(const char *name)
2896 do_service(name, "restart", 0);