Merge commit 'origin/Static-ARP' into tomato-shibby
[tomato.git] / release / src / router / rc / services.c
blob20c3bb4460df13a44560fbba05aa3a8add9534c3
1 /*
3 Copyright 2003, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Copyright 2005, Broadcom Corporation
22 All Rights Reserved.
24 THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
25 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
26 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
27 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
32 Modified for Tomato Firmware
33 Portions, Copyright (C) 2006-2009 Jonathan Zarate
36 #include "rc.h"
38 #include <arpa/inet.h>
39 #include <time.h>
40 #include <sys/time.h>
41 #include <errno.h>
43 // !!TB
44 #include <sys/mount.h>
45 #include <mntent.h>
46 #include <dirent.h>
48 // Pop an alarm to recheck pids in 500 msec.
49 static const struct itimerval pop_tv = { {0,0}, {0, 500 * 1000} };
51 // Pop an alarm to reap zombies.
52 static const struct itimerval zombie_tv = { {0,0}, {307, 0} };
54 // -----------------------------------------------------------------------------
56 static const char dmhosts[] = "/etc/dnsmasq/hosts";
57 static const char dmdhcp[] = "/etc/dnsmasq/dhcp";
58 static const char dmresolv[] = "/etc/resolv.dnsmasq";
60 static pid_t pid_dnsmasq = -1;
62 static int is_wet(int idx, int unit, int subunit, void *param)
64 return nvram_match(wl_nvname("mode", unit, subunit), "wet");
67 void start_dnsmasq()
69 FILE *f;
70 const char *nv;
71 char buf[512];
72 char lan[24];
73 const char *router_ip;
74 const char *lan_ifname;
75 char sdhcp_lease[32];
76 char *e;
77 int n;
78 char *mac, *ip, *name;
79 char *p;
80 int ipn;
81 char ipbuf[32];
82 FILE *hf, *df;
83 int dhcp_start;
84 int dhcp_count;
85 int dhcp_lease;
86 int do_dhcpd;
87 int do_dns;
89 TRACE_PT("begin\n");
91 if (getpid() != 1) {
92 start_service("dnsmasq");
93 return;
96 stop_dnsmasq();
98 if (foreach_wif(1, NULL, is_wet)) return;
100 if ((f = fopen("/etc/dnsmasq.conf", "w")) == NULL) return;
102 lan_ifname = nvram_safe_get("lan_ifname");
103 router_ip = nvram_safe_get("lan_ipaddr");
104 strlcpy(lan, router_ip, sizeof(lan));
105 if ((p = strrchr(lan, '.')) != NULL) *(p + 1) = 0;
107 fprintf(f,
108 "pid-file=/var/run/dnsmasq.pid\n"
109 "interface=%s\n",
110 lan_ifname);
111 if (((nv = nvram_get("wan_domain")) != NULL) || ((nv = nvram_get("wan_get_domain")) != NULL)) {
112 if (*nv) fprintf(f, "domain=%s\n", nv);
115 // dns
116 const dns_list_t *dns = get_dns(); // this always points to a static buffer
118 if (((nv = nvram_get("dns_minport")) != NULL) && (*nv)) n = atoi(nv);
119 else n = 4096;
120 fprintf(f,
121 "resolv-file=%s\n" // the real stuff is here
122 "addn-hosts=%s\n" // directory with additional hosts files
123 "dhcp-hostsfile=%s\n" // directory with dhcp hosts files
124 "expand-hosts\n" // expand hostnames in hosts file
125 "min-port=%u\n", // min port used for random src port
126 dmresolv, dmhosts, dmdhcp, n);
127 do_dns = nvram_match("dhcpd_dmdns", "1");
129 // DNS rebinding protection, will discard upstream RFC1918 responses
130 if (nvram_get_int("dns_norebind")) {
131 fprintf(f,
132 "stop-dns-rebind\n"
133 "rebind-localhost-ok\n");
134 // allow RFC1918 responses for server domain
135 switch (get_wan_proto()) {
136 case WP_PPTP:
137 nv = nvram_get("pptp_server_ip");
138 break;
139 case WP_L2TP:
140 nv = nvram_get("l2tp_server_ip");
141 break;
142 default:
143 nv = NULL;
144 break;
146 if (nv && *nv) fprintf(f, "rebind-domain-ok=%s\n", nv);
149 for (n = 0 ; n < dns->count; ++n) {
150 if (dns->dns[n].port != 53) {
151 fprintf(f, "server=%s#%u\n", inet_ntoa(dns->dns[n].addr), dns->dns[n].port);
155 // dhcp
156 do_dhcpd = nvram_match("lan_proto", "dhcp");
157 if (do_dhcpd) {
158 dhcp_lease = nvram_get_int("dhcp_lease");
159 if (dhcp_lease <= 0) dhcp_lease = 1440;
161 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
162 if (n < 0) strcpy(sdhcp_lease, "infinite");
163 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
165 if (!do_dns) {
166 // if not using dnsmasq for dns
168 if ((dns->count == 0) && (nvram_get_int("dhcpd_llndns"))) {
169 // no DNS might be temporary. use a low lease time to force clients to update.
170 dhcp_lease = 2;
171 strcpy(sdhcp_lease, "2m");
172 do_dns = 1;
174 else {
175 // pass the dns directly
176 buf[0] = 0;
177 for (n = 0 ; n < dns->count; ++n) {
178 if (dns->dns[n].port == 53) { // check: option 6 doesn't seem to support other ports
179 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n].addr));
182 fprintf(f, "dhcp-option=6%s\n", buf);
186 if ((p = nvram_get("dhcpd_startip")) && (*p) && (e = nvram_get("dhcpd_endip")) && (*e)) {
187 fprintf(f, "dhcp-range=%s,%s,%s,%dm\n", p, e, nvram_safe_get("lan_netmask"), dhcp_lease);
189 else {
190 // for compatibility
191 dhcp_start = nvram_get_int("dhcp_start");
192 dhcp_count = nvram_get_int("dhcp_num");
193 fprintf(f, "dhcp-range=%s%d,%s%d,%s,%dm\n",
194 lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get("lan_netmask"), dhcp_lease);
197 nv = router_ip;
198 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED)) {
199 p = nvram_safe_get("lan_gateway");
200 if ((*p) && (strcmp(p, "0.0.0.0") != 0)) nv = p;
203 n = nvram_get_int("dhcpd_lmax");
204 fprintf(f,
205 "dhcp-option=3,%s\n" // gateway
206 "dhcp-lease-max=%d\n",
208 (n > 0) ? n : 255);
210 if (nvram_get_int("dhcpd_auth") >= 0) {
211 fprintf(f, "dhcp-authoritative\n");
214 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
215 fprintf(f, "dhcp-option=44,%s\n", nv);
217 #ifdef TCONFIG_SAMBASRV
218 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
219 if ((nv == NULL) || (*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
220 // Samba will serve as a WINS server
221 fprintf(f, "dhcp-option=44,0.0.0.0\n");
224 #endif
226 else {
227 fprintf(f, "no-dhcp-interface=%s\n", lan_ifname);
230 // write static lease entries & create hosts file
232 mkdir_if_none(dmhosts);
233 snprintf(buf, sizeof(buf), "%s/hosts", dmhosts);
234 if ((hf = fopen(buf, "w")) != NULL) {
235 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
236 fprintf(hf, "%s %s\n", router_ip, nv);
237 #ifdef TCONFIG_SAMBASRV
238 else if (((nv = nvram_get("lan_hostname")) != NULL) && (*nv))
239 fprintf(hf, "%s %s\n", router_ip, nv);
240 #endif
241 p = (char *)get_wanip();
242 if ((*p == 0) || strcmp(p, "0.0.0.0") == 0)
243 p = "127.0.0.1";
244 fprintf(hf, "%s wan-ip\n", p);
245 if (nv && (*nv))
246 fprintf(hf, "%s %s-wan\n", p, nv);
249 mkdir_if_none(dmdhcp);
250 snprintf(buf, sizeof(buf), "%s/dhcp-hosts", dmdhcp);
251 df = fopen(buf, "w");
253 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
254 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
255 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 106 w/ delim
256 p = nvram_safe_get("dhcpd_static");
257 while ((e = strchr(p, '>')) != NULL) {
258 n = (e - p);
259 if (n > 105) {
260 p = e + 1;
261 continue;
264 strncpy(buf, p, n);
265 buf[n] = 0;
266 p = e + 1;
268 if ((e = strchr(buf, '<')) == NULL) continue;
269 *e = 0;
270 mac = buf;
272 ip = e + 1;
273 if ((e = strchr(ip, '<')) == NULL) continue;
274 *e = 0;
275 if (strchr(ip, '.') == NULL) {
276 ipn = atoi(ip);
277 if ((ipn <= 0) || (ipn > 255)) continue;
278 sprintf(ipbuf, "%s%d", lan, ipn);
279 ip = ipbuf;
281 else {
282 if (inet_addr(ip) == INADDR_NONE) continue;
285 name = e + 1;
287 if ((hf) && (*name != 0)) {
288 fprintf(hf, "%s %s\n", ip, name);
291 if ((do_dhcpd) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
292 if (df)
293 fprintf(df, "%s,%s,%s\n", mac, ip, sdhcp_lease);
294 else
295 fprintf(f, "dhcp-host=%s,%s,%s\n", mac, ip, sdhcp_lease);
299 if (df) fclose(df);
300 if (hf) fclose(hf);
304 #ifdef TCONFIG_OPENVPN
305 write_vpn_dnsmasq_config(f);
306 #endif
308 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
310 fappend(f, "/etc/dnsmasq.custom");
314 fclose(f);
316 if (do_dns) {
317 unlink("/etc/resolv.conf");
318 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
321 TRACE_PT("run dnsmasq\n");
323 // Default to some values we like, but allow the user to override them.
324 eval("dnsmasq", "-c", "1500", "--log-async");
326 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
327 pid_dnsmasq = -2;
330 TRACE_PT("end\n");
333 void stop_dnsmasq(void)
335 TRACE_PT("begin\n");
337 if (getpid() != 1) {
338 stop_service("dnsmasq");
339 return;
342 pid_dnsmasq = -1;
344 unlink("/etc/resolv.conf");
345 symlink(dmresolv, "/etc/resolv.conf");
347 killall_tk("dnsmasq");
349 TRACE_PT("end\n");
352 void clear_resolv(void)
354 f_write(dmresolv, NULL, 0, 0, 0); // blank
357 #ifdef TCONFIG_IPV6
358 static int write_ipv6_dns_servers(FILE *f, const char *prefix, char *dns, const char *suffix, int once)
360 char p[INET6_ADDRSTRLEN + 1], *next = NULL;
361 struct in6_addr addr;
362 int cnt = 0;
364 foreach(p, dns, next) {
365 // verify that this is a valid IPv6 address
366 if (inet_pton(AF_INET6, p, &addr) == 1) {
367 fprintf(f, "%s%s%s", (once && cnt) ? "" : prefix, p, suffix);
368 ++cnt;
372 return cnt;
374 #endif
376 void dns_to_resolv(void)
378 FILE *f;
379 const dns_list_t *dns;
380 int i;
381 mode_t m;
383 m = umask(022); // 077 from pppoecd
384 if ((f = fopen(dmresolv, "w")) != NULL) {
385 // Check for VPN DNS entries
386 if (!write_vpn_resolv(f)) {
387 #ifdef TCONFIG_IPV6
388 if (write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_dns"), "\n", 0) == 0 || nvram_get_int("dns_addget"))
389 write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_get_dns"), "\n", 0);
390 #endif
391 dns = get_dns(); // static buffer
392 if (dns->count == 0) {
393 // Put a pseudo DNS IP to trigger Connect On Demand
394 if (nvram_match("ppp_demand", "1")) {
395 switch (get_wan_proto()) {
396 case WP_PPPOE:
397 case WP_PPTP:
398 case WP_L2TP:
399 fprintf(f, "nameserver 1.1.1.1\n");
400 break;
404 else {
405 for (i = 0; i < dns->count; i++) {
406 if (dns->dns[i].port == 53) { // resolv.conf doesn't allow for an alternate port
407 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i].addr));
412 fclose(f);
414 umask(m);
417 // -----------------------------------------------------------------------------
419 void start_httpd(void)
421 if (getpid() != 1) {
422 start_service("httpd");
423 return;
426 stop_httpd();
427 chdir("/www");
428 eval("httpd");
429 chdir("/");
432 void stop_httpd(void)
434 if (getpid() != 1) {
435 stop_service("httpd");
436 return;
439 killall_tk("httpd");
442 // -----------------------------------------------------------------------------
443 #ifdef TCONFIG_IPV6
445 static void add_ip6_lanaddr(void)
447 char ip[INET6_ADDRSTRLEN + 4];
448 const char *p;
450 p = ipv6_router_address(NULL);
451 if (*p) {
452 snprintf(ip, sizeof(ip), "%s/%d", p, nvram_get_int("ipv6_prefix_length") ? : 64);
453 eval("ip", "-6", "addr", "add", ip, "dev", nvram_safe_get("lan_ifname"));
457 void start_ipv6_tunnel(void)
459 char ip[INET6_ADDRSTRLEN + 4];
460 struct in_addr addr4;
461 struct in6_addr addr;
462 const char *wanip, *mtu, *tun_dev;
463 int service;
465 service = get_ipv6_service();
466 tun_dev = get_wan6face();
467 wanip = get_wanip();
468 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
469 modprobe("sit");
471 if (service == IPV6_ANYCAST_6TO4)
472 snprintf(ip, sizeof(ip), "192.88.99.%d", nvram_get_int("ipv6_relay"));
473 else
474 strlcpy(ip, (char *)nvram_safe_get("ipv6_tun_v4end"), sizeof(ip));
475 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit",
476 "remote", ip,
477 "local", (char *)wanip,
478 "ttl", nvram_safe_get("ipv6_tun_ttl"));
480 eval("ip", "link", "set", (char *)tun_dev, "mtu", (char *)mtu, "up");
481 nvram_set("ipv6_ifname", (char *)tun_dev);
483 if (service == IPV6_ANYCAST_6TO4) {
484 add_ip6_lanaddr();
485 addr4.s_addr = 0;
486 memset(&addr, 0, sizeof(addr));
487 inet_aton(wanip, &addr4);
488 addr.s6_addr16[0] = htons(0x2002);
489 ipv6_mapaddr4(&addr, 16, &addr4, 0);
490 addr.s6_addr16[7] = htons(0x0001);
491 inet_ntop(AF_INET6, &addr, ip, sizeof(ip));
492 strncat(ip, "/16", sizeof(ip));
494 else {
495 snprintf(ip, sizeof(ip), "%s/%d",
496 nvram_safe_get("ipv6_tun_addr"),
497 nvram_get_int("ipv6_tun_addrlen") ? : 64);
499 eval("ip", "addr", "add", ip, "dev", (char *)tun_dev);
500 eval("ip", "route", "add", "::/0", "dev", (char *)tun_dev);
502 // (re)start radvd
503 if (service == IPV6_ANYCAST_6TO4)
504 start_radvd();
507 void stop_ipv6_tunnel(void)
509 eval("ip", "tunnel", "del", (char *)get_wan6face());
510 if (get_ipv6_service() == IPV6_ANYCAST_6TO4) {
511 // get rid of old IPv6 address from lan iface
512 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
514 modprobe_r("sit");
517 static pid_t pid_radvd = -1;
519 void start_radvd(void)
521 FILE *f;
522 char *prefix, *ip, *mtu;
523 int do_dns, do_6to4;
524 char *argv[] = { "radvd", NULL, NULL, NULL };
525 int pid, argc, service, cnt;
527 if (getpid() != 1) {
528 start_service("radvd");
529 return;
532 stop_radvd();
534 if (ipv6_enabled() && nvram_get_int("ipv6_radvd")) {
535 service = get_ipv6_service();
536 do_6to4 = (service == IPV6_ANYCAST_6TO4);
537 mtu = NULL;
539 switch (service) {
540 case IPV6_NATIVE_DHCP:
541 prefix = "::";
542 break;
543 case IPV6_ANYCAST_6TO4:
544 case IPV6_6IN4:
545 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
546 // fall through
547 default:
548 prefix = do_6to4 ? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
549 break;
551 if (!(*prefix)) prefix = "::";
553 // Create radvd.conf
554 if ((f = fopen("/etc/radvd.conf", "w")) == NULL) return;
556 ip = (char *)ipv6_router_address(NULL);
557 do_dns = (*ip) && nvram_match("dhcpd_dmdns", "1");
559 fprintf(f,
560 "interface %s\n"
561 "{\n"
562 " IgnoreIfMissing on;\n"
563 " AdvSendAdvert on;\n"
564 " MaxRtrAdvInterval 60;\n"
565 " AdvHomeAgentFlag off;\n"
566 " AdvManagedFlag off;\n"
567 "%s%s%s"
568 " prefix %s/64 \n"
569 " {\n"
570 " AdvOnLink on;\n"
571 " AdvAutonomous on;\n"
572 "%s"
573 "%s%s%s"
574 " };\n",
575 nvram_safe_get("lan_ifname"),
576 mtu ? " AdvLinkMTU " : "", mtu ? : "", mtu ? ";\n" : "",
577 prefix,
578 do_6to4 ? " AdvValidLifetime 300;\n AdvPreferredLifetime 120;\n" : "",
579 do_6to4 ? " Base6to4Interface " : "",
580 do_6to4 ? get_wanface() : "",
581 do_6to4 ? ";\n" : "");
583 if (do_dns) {
584 fprintf(f, " RDNSS %s {};\n", ip);
586 else {
587 cnt = write_ipv6_dns_servers(f, " RDNSS ", nvram_safe_get("ipv6_dns"), " ", 1);
588 if (cnt == 0 || nvram_get_int("dns_addget"))
589 cnt += write_ipv6_dns_servers(f, (cnt) ? "" : " RDNSS ", nvram_safe_get("ipv6_get_dns"), " ", 1);
590 if (cnt) fprintf(f, "{};\n");
593 fprintf(f,
594 "};\n"); // close "interface" section
595 fclose(f);
597 // Start radvd
598 argc = 1;
599 if (nvram_get_int("debug_ipv6")) {
600 argv[argc++] = "-d";
601 argv[argc++] = "10";
603 argv[argc] = NULL;
604 _eval(argv, NULL, 0, &pid);
606 if (!nvram_contains_word("debug_norestart", "radvd")) {
607 pid_radvd = -2;
612 void stop_radvd(void)
614 if (getpid() != 1) {
615 stop_service("radvd");
616 return;
619 pid_radvd = -1;
620 killall_tk("radvd");
623 void start_ipv6(void)
625 int service;
627 service = get_ipv6_service();
628 enable_ip_forward();
630 // Check if turned on
631 switch (service) {
632 case IPV6_NATIVE:
633 case IPV6_6IN4:
634 case IPV6_MANUAL:
635 add_ip6_lanaddr();
636 break;
637 case IPV6_NATIVE_DHCP:
638 case IPV6_ANYCAST_6TO4:
639 nvram_set("ipv6_rtr_addr", "");
640 nvram_set("ipv6_prefix", "");
641 break;
644 if (service != IPV6_DISABLED) {
645 if ((nvram_get_int("ipv6_accept_ra") & 2) != 0 && !nvram_get_int("ipv6_radvd"))
646 accept_ra(nvram_safe_get("lan_ifname"));
650 void stop_ipv6(void)
652 stop_ipv6_tunnel();
653 stop_dhcp6c();
654 eval("ip", "-6", "addr", "flush", "scope", "global");
657 #endif
659 // -----------------------------------------------------------------------------
661 void start_upnp(void)
663 if (getpid() != 1) {
664 start_service("upnp");
665 return;
668 if (get_wan_proto() == WP_DISABLED) return;
670 int enable;
671 FILE *f;
672 int upnp_port;
674 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
675 mkdir("/etc/upnp", 0777);
676 if (f_exists("/etc/upnp/config.alt")) {
677 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
679 else {
680 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
681 upnp_port = nvram_get_int("upnp_port");
682 if ((upnp_port < 0) || (upnp_port >= 0xFFFF)) upnp_port = 0;
684 char *lanip = nvram_safe_get("lan_ipaddr");
685 char *lanmask = nvram_safe_get("lan_netmask");
687 fprintf(f,
688 "ext_ifname=%s\n"
689 "listening_ip=%s/%s\n"
690 "port=%d\n"
691 "enable_upnp=%s\n"
692 "enable_natpmp=%s\n"
693 "secure_mode=%s\n"
694 "upnp_forward_chain=upnp\n"
695 "upnp_nat_chain=upnp\n"
696 "notify_interval=%d\n"
697 "system_uptime=yes\n"
698 "\n"
700 get_wanface(),
701 lanip, lanmask,
702 upnp_port,
703 (enable & 1) ? "yes" : "no", // upnp enable
704 (enable & 2) ? "yes" : "no", // natpmp enable
705 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
706 nvram_get_int("upnp_ssdp_interval")
709 if (nvram_get_int("upnp_clean")) {
710 int interval = nvram_get_int("upnp_clean_interval");
711 if (interval < 60) interval = 60;
712 fprintf(f,
713 "clean_ruleset_interval=%d\n"
714 "clean_ruleset_threshold=%d\n",
715 interval,
716 nvram_get_int("upnp_clean_threshold")
719 else
720 fprintf(f,"clean_ruleset_interval=0\n");
722 if (nvram_match("upnp_mnp", "1")) {
723 int https = nvram_get_int("https_enable");
724 fprintf(f, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
725 https ? "s" : "", lanip,
726 nvram_safe_get(https ? "https_lanport" : "http_lanport"));
728 else {
729 // Empty parameters are not included into XML service description
730 fprintf(f, "presentation_url=\n");
733 char uuid[45];
734 f_read_string("/proc/sys/kernel/random/uuid", uuid, sizeof(uuid));
735 fprintf(f, "uuid=%s\n", uuid);
737 int ports[4];
738 if ((ports[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
739 (ports[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
740 (ports[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
741 (ports[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
742 fprintf(f,
743 "allow %d-%d %s/%s %d-%d\n",
744 ports[0], ports[1],
745 lanip, lanmask,
746 ports[2], ports[3]
749 else {
750 // by default allow only redirection of ports above 1024
751 fprintf(f, "allow 1024-65535 %s/%s 1024-65535\n", lanip, lanmask);
754 fappend(f, "/etc/upnp/config.custom");
755 fprintf(f, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
756 fclose(f);
758 xstart("miniupnpd", "-f", "/etc/upnp/config");
764 void stop_upnp(void)
766 if (getpid() != 1) {
767 stop_service("upnp");
768 return;
771 killall_tk("miniupnpd");
774 // -----------------------------------------------------------------------------
776 static pid_t pid_crond = -1;
778 void start_cron(void)
780 stop_cron();
782 eval("crond", nvram_contains_word("log_events", "crond") ? NULL : "-l", "9");
783 if (!nvram_contains_word("debug_norestart", "crond")) {
784 pid_crond = -2;
788 void stop_cron(void)
790 pid_crond = -1;
791 killall_tk("crond");
794 // -----------------------------------------------------------------------------
795 #ifdef LINUX26
797 static pid_t pid_hotplug2 = -1;
799 void start_hotplug2()
801 stop_hotplug2();
803 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE, 0);
804 xstart("hotplug2", "--persistent", "--no-coldplug");
805 // FIXME: Don't remember exactly why I put "sleep" here -
806 // but it was not for a race with check_services()... - TB
807 sleep(1);
809 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
810 pid_hotplug2 = -2;
814 void stop_hotplug2(void)
816 pid_hotplug2 = -1;
817 killall_tk("hotplug2");
820 #endif /* LINUX26 */
821 // -----------------------------------------------------------------------------
823 // Written by Sparq in 2002/07/16
824 void start_zebra(void)
826 #ifdef TCONFIG_ZEBRA
827 if (getpid() != 1) {
828 start_service("zebra");
829 return;
832 FILE *fp;
834 char *lan_tx = nvram_safe_get("dr_lan_tx");
835 char *lan_rx = nvram_safe_get("dr_lan_rx");
836 char *wan_tx = nvram_safe_get("dr_wan_tx");
837 char *wan_rx = nvram_safe_get("dr_wan_rx");
839 if ((*lan_tx == '0') && (*lan_rx == '0') && (*wan_tx == '0') && (*wan_rx == '0')) {
840 return;
843 // empty
844 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
845 fclose(fp);
849 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
850 char *lan_ifname = nvram_safe_get("lan_ifname");
851 char *wan_ifname = nvram_safe_get("wan_ifname");
853 fprintf(fp, "router rip\n");
854 fprintf(fp, "network %s\n", lan_ifname);
855 fprintf(fp, "network %s\n", wan_ifname);
856 fprintf(fp, "redistribute connected\n");
857 //fprintf(fp, "redistribute static\n");
859 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
860 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
862 fprintf(fp, "interface %s\n", lan_ifname);
863 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
864 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
866 fprintf(fp, "interface %s\n", wan_ifname);
867 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
868 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
870 fprintf(fp, "router rip\n");
871 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
872 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
873 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
874 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
875 fprintf(fp, "access-list private deny any\n");
877 //fprintf(fp, "debug rip events\n");
878 //fprintf(fp, "log file /etc/ripd.log\n");
879 fclose(fp);
882 xstart("zebra", "-d");
883 xstart("ripd", "-d");
884 #endif
887 void stop_zebra(void)
889 #ifdef TCONFIG_ZEBRA
890 if (getpid() != 1) {
891 stop_service("zebra");
892 return;
895 killall("zebra", SIGTERM);
896 killall("ripd", SIGTERM);
898 unlink("/etc/zebra.conf");
899 unlink("/etc/ripd.conf");
900 #endif
903 // -----------------------------------------------------------------------------
905 void start_syslog(void)
907 char *argv[16];
908 int argc;
909 char *nv;
910 char *b_opt = "";
911 char rem[256];
912 int n;
913 char s[64];
914 char cfg[256];
915 char *rot_siz = "50";
917 argv[0] = "syslogd";
918 argc = 1;
920 if (nvram_match("log_remote", "1")) {
921 nv = nvram_safe_get("log_remoteip");
922 if (*nv) {
923 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
924 argv[argc++] = "-R";
925 argv[argc++] = rem;
929 if (nvram_match("log_file", "1")) {
930 argv[argc++] = "-L";
932 /* Read options: rotate_size(kb) num_backups logfilename.
933 * Ignore these settings and use defaults if the logfile cannot be written to.
935 if (f_read_string("/etc/syslogd.cfg", cfg, sizeof(cfg)) > 0) {
936 if ((nv = strchr(cfg, '\n')))
937 *nv = 0;
939 if ((nv = strtok(cfg, " \t"))) {
940 if (isdigit(*nv))
941 rot_siz = nv;
944 if ((nv = strtok(NULL, " \t")))
945 b_opt = nv;
947 if ((nv = strtok(NULL, " \t")) && *nv == '/') {
948 if (f_write(nv, cfg, 0, FW_APPEND, 0) >= 0) {
949 argv[argc++] = "-O";
950 argv[argc++] = nv;
952 else {
953 rot_siz = "50";
954 b_opt = "";
959 argv[argc++] = "-s";
960 argv[argc++] = rot_siz;
962 if (isdigit(*b_opt)) {
963 argv[argc++] = "-b";
964 argv[argc++] = b_opt;
968 if (argc > 1) {
969 argv[argc] = NULL;
970 _eval(argv, NULL, 0, NULL);
972 argv[0] = "klogd";
973 argv[1] = NULL;
974 _eval(argv, NULL, 0, NULL);
976 // used to be available in syslogd -m
977 n = nvram_get_int("log_mark");
978 if (n > 0) {
979 // n is in minutes
980 if (n < 60)
981 sprintf(rem, "*/%d * * * *", n);
982 else if (n < 60 * 24)
983 sprintf(rem, "0 */%d * * *", n / 60);
984 else
985 sprintf(rem, "0 0 */%d * *", n / (60 * 24));
986 sprintf(s, "%s logger -p syslog.info -- -- MARK --", rem);
987 eval("cru", "a", "syslogdmark", s);
989 else {
990 eval("cru", "d", "syslogdmark");
995 void stop_syslog(void)
997 killall("klogd", SIGTERM);
998 killall("syslogd", SIGTERM);
1001 // -----------------------------------------------------------------------------
1003 static pid_t pid_igmp = -1;
1005 void start_igmp_proxy(void)
1007 FILE *fp;
1009 pid_igmp = -1;
1010 if (nvram_match("multicast_pass", "1")) {
1011 if (get_wan_proto() == WP_DISABLED)
1012 return;
1014 if (f_exists("/etc/igmp.alt")) {
1015 eval("igmpproxy", "/etc/igmp.alt");
1017 else if ((fp = fopen("/etc/igmp.conf", "w")) != NULL) {
1018 fprintf(fp,
1019 "quickleave\n"
1020 "phyint %s upstream\n"
1021 "\taltnet %s\n"
1022 "phyint %s downstream ratelimit 0\n",
1023 nvram_safe_get("wan_ifname"),
1024 nvram_get("multicast_altnet") ? : "0.0.0.0/0",
1025 nvram_safe_get("lan_ifname"));
1026 fclose(fp);
1027 eval("igmpproxy", "/etc/igmp.conf");
1029 else {
1030 return;
1032 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1033 pid_igmp = -2;
1038 void stop_igmp_proxy(void)
1040 pid_igmp = -1;
1041 killall_tk("igmpproxy");
1045 // -----------------------------------------------------------------------------
1047 void set_tz(void)
1049 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
1052 void start_ntpc(void)
1054 set_tz();
1056 stop_ntpc();
1058 if (nvram_get_int("ntp_updates") >= 0) {
1059 xstart("ntpsync", "--init");
1063 void stop_ntpc(void)
1065 killall("ntpsync", SIGTERM);
1068 // -----------------------------------------------------------------------------
1070 static void stop_rstats(void)
1072 int n;
1073 int pid;
1075 n = 60;
1076 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
1077 if (kill(pid, SIGTERM) != 0) break;
1078 sleep(1);
1082 static void start_rstats(int new)
1084 if (nvram_match("rstats_enable", "1")) {
1085 stop_rstats();
1086 if (new) xstart("rstats", "--new");
1087 else xstart("rstats");
1091 // -----------------------------------------------------------------------------
1093 // !!TB - FTP Server
1095 #ifdef TCONFIG_FTP
1096 static char *get_full_storage_path(char *val)
1098 static char buf[128];
1099 int len;
1101 if (val[0] == '/')
1102 len = sprintf(buf, "%s", val);
1103 else
1104 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
1106 if (len > 1 && buf[len - 1] == '/')
1107 buf[len - 1] = 0;
1109 return buf;
1112 static char *nvram_storage_path(char *var)
1114 char *val = nvram_safe_get(var);
1115 return get_full_storage_path(val);
1118 char vsftpd_conf[] = "/etc/vsftpd.conf";
1119 char vsftpd_users[] = "/etc/vsftpd.users";
1120 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
1122 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1124 static void start_ftpd(void)
1126 char tmp[256];
1127 FILE *fp, *f;
1128 char *buf;
1129 char *p, *q;
1130 char *user, *pass, *rights;
1132 if (getpid() != 1) {
1133 start_service("ftpd");
1134 return;
1137 if (!nvram_get_int("ftp_enable")) return;
1139 mkdir_if_none(vsftpd_users);
1140 mkdir_if_none("/var/run/vsftpd");
1142 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
1143 return;
1145 if (nvram_get_int("ftp_super"))
1147 /* rights */
1148 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
1149 if ((f = fopen(tmp, "w")))
1151 fprintf(f,
1152 "dirlist_enable=yes\n"
1153 "write_enable=yes\n"
1154 "download_enable=yes\n");
1155 fclose(f);
1159 #ifdef TCONFIG_SAMBASRV
1160 if (nvram_match("smbd_cset", "utf8"))
1161 fprintf(fp, "utf8=yes\n");
1162 #endif
1164 if (nvram_invmatch("ftp_anonymous", "0"))
1166 fprintf(fp,
1167 "anon_allow_writable_root=yes\n"
1168 "anon_world_readable_only=no\n"
1169 "anon_umask=022\n");
1171 /* rights */
1172 sprintf(tmp, "%s/ftp", vsftpd_users);
1173 if ((f = fopen(tmp, "w")))
1175 if (nvram_match("ftp_dirlist", "0"))
1176 fprintf(f, "dirlist_enable=yes\n");
1177 if (nvram_match("ftp_anonymous", "1") ||
1178 nvram_match("ftp_anonymous", "3"))
1179 fprintf(f, "write_enable=yes\n");
1180 if (nvram_match("ftp_anonymous", "1") ||
1181 nvram_match("ftp_anonymous", "2"))
1182 fprintf(f, "download_enable=yes\n");
1183 fclose(f);
1185 if (nvram_match("ftp_anonymous", "1") ||
1186 nvram_match("ftp_anonymous", "3"))
1187 fprintf(fp,
1188 "anon_upload_enable=yes\n"
1189 "anon_mkdir_write_enable=yes\n"
1190 "anon_other_write_enable=yes\n");
1191 } else {
1192 fprintf(fp, "anonymous_enable=no\n");
1195 fprintf(fp,
1196 "dirmessage_enable=yes\n"
1197 "download_enable=no\n"
1198 "dirlist_enable=no\n"
1199 "hide_ids=yes\n"
1200 "syslog_enable=yes\n"
1201 "local_enable=yes\n"
1202 "local_umask=022\n"
1203 "chmod_enable=no\n"
1204 "chroot_local_user=yes\n"
1205 "check_shell=no\n"
1206 "log_ftp_protocol=%s\n"
1207 "user_config_dir=%s\n"
1208 "passwd_file=%s\n"
1209 "listen%s=yes\n"
1210 "listen_port=%s\n"
1211 "background=yes\n"
1212 "isolate=no\n"
1213 "max_clients=%d\n"
1214 "max_per_ip=%d\n"
1215 "max_login_fails=1\n"
1216 "idle_session_timeout=%s\n"
1217 "use_sendfile=no\n"
1218 "anon_max_rate=%d\n"
1219 "local_max_rate=%d\n"
1220 "%s\n",
1221 nvram_get_int("log_ftp") ? "yes" : "no",
1222 vsftpd_users, vsftpd_passwd,
1223 #ifdef TCONFIG_IPV6
1224 ipv6_enabled() ? "_ipv6" : "",
1225 #else
1227 #endif
1228 nvram_get("ftp_port") ? : "21",
1229 nvram_get_int("ftp_max"),
1230 nvram_get_int("ftp_ipmax"),
1231 nvram_get("ftp_staytimeout") ? : "300",
1232 nvram_get_int("ftp_anonrate") * 1024,
1233 nvram_get_int("ftp_rate") * 1024,
1234 nvram_safe_get("ftp_custom"));
1236 fclose(fp);
1238 /* prepare passwd file and default users */
1239 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
1240 return;
1242 if (((user = nvram_get("http_username")) == NULL) || (*user == 0)) user = "admin";
1243 if (((pass = nvram_get("http_passwd")) == NULL) || (*pass == 0)) pass = "admin";
1245 fprintf(fp, /* anonymous, admin, nobody */
1246 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1247 "%s:%s:0:0:root:/:/sbin/nologin\n"
1248 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1249 nvram_storage_path("ftp_anonroot"), user,
1250 nvram_get_int("ftp_super") ? crypt(pass, "$1$") : "x",
1251 MOUNT_ROOT);
1253 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
1256 username<password<rights
1257 rights:
1258 Read/Write
1259 Read Only
1260 View Only
1261 Private
1263 p = buf;
1264 while ((q = strsep(&p, ">")) != NULL) {
1265 if (vstrsep(q, "<", &user, &pass, &rights) != 3) continue;
1266 if (!user || !pass) continue;
1268 /* directory */
1269 if (strncmp(rights, "Private", 7) == 0)
1271 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
1272 mkdir_if_none(tmp);
1274 else
1275 sprintf(tmp, "%s", nvram_storage_path("ftp_pubroot"));
1277 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1278 user, crypt(pass, "$1$"), user, tmp);
1280 /* rights */
1281 sprintf(tmp, "%s/%s", vsftpd_users, user);
1282 if ((f = fopen(tmp, "w")))
1284 tmp[0] = 0;
1285 if (nvram_invmatch("ftp_dirlist", "1"))
1286 strcat(tmp, "dirlist_enable=yes\n");
1287 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
1288 strcat(tmp, "download_enable=yes\n");
1289 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
1290 strcat(tmp, "write_enable=yes\n");
1292 fputs(tmp, f);
1293 fclose(f);
1296 free(buf);
1299 fclose(fp);
1300 killall("vsftpd", SIGHUP);
1302 /* start vsftpd if it's not already running */
1303 if (pidof("vsftpd") <= 0)
1304 xstart("vsftpd");
1307 static void stop_ftpd(void)
1309 if (getpid() != 1) {
1310 stop_service("ftpd");
1311 return;
1314 killall_tk("vsftpd");
1315 unlink(vsftpd_passwd);
1316 unlink(vsftpd_conf);
1317 eval("rm", "-rf", vsftpd_users);
1319 #endif // TCONFIG_FTP
1321 // -----------------------------------------------------------------------------
1323 // !!TB - Samba
1325 #ifdef TCONFIG_SAMBASRV
1326 static void kill_samba(int sig)
1328 if (sig == SIGTERM) {
1329 killall_tk("smbd");
1330 killall_tk("nmbd");
1332 else {
1333 killall("smbd", sig);
1334 killall("nmbd", sig);
1338 static void start_samba(void)
1340 FILE *fp;
1341 DIR *dir = NULL;
1342 struct dirent *dp;
1343 char nlsmod[15];
1344 int mode;
1345 char *nv;
1347 if (getpid() != 1) {
1348 start_service("smbd");
1349 return;
1352 mode = nvram_get_int("smbd_enable");
1353 if (!mode || !nvram_invmatch("lan_hostname", ""))
1354 return;
1356 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
1357 return;
1359 fprintf(fp, "[global]\n"
1360 " interfaces = %s\n"
1361 " bind interfaces only = yes\n"
1362 " workgroup = %s\n"
1363 " netbios name = %s\n"
1364 " server string = %s\n"
1365 " guest account = nobody\n"
1366 " security = user\n"
1367 " %s\n"
1368 " guest ok = %s\n"
1369 " guest only = no\n"
1370 " browseable = yes\n"
1371 " syslog only = yes\n"
1372 " timestamp logs = no\n"
1373 " syslog = 1\n"
1374 " encrypt passwords = yes\n"
1375 " preserve case = yes\n"
1376 " short preserve case = yes\n",
1377 nvram_safe_get("lan_ifname"),
1378 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1379 nvram_safe_get("lan_hostname"),
1380 nvram_get("router_name") ? : "Tomato",
1381 mode == 2 ? "" : "map to guest = Bad User",
1382 mode == 2 ? "no" : "yes" // guest ok
1385 if (nvram_get_int("smbd_wins")) {
1386 nv = nvram_safe_get("wan_wins");
1387 if ((*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
1388 fprintf(fp, " wins support = yes\n");
1392 if (nvram_get_int("smbd_master")) {
1393 fprintf(fp,
1394 " domain master = yes\n"
1395 " local master = yes\n"
1396 " preferred master = yes\n"
1397 " os level = 65\n");
1400 nv = nvram_safe_get("smbd_cpage");
1401 if (*nv) {
1402 #ifndef TCONFIG_SAMBA3
1403 fprintf(fp, " client code page = %s\n", nv);
1404 #endif
1405 sprintf(nlsmod, "nls_cp%s", nv);
1407 nv = nvram_safe_get("smbd_nlsmod");
1408 if ((*nv) && (strcmp(nv, nlsmod) != 0))
1409 modprobe_r(nv);
1411 modprobe(nlsmod);
1412 nvram_set("smbd_nlsmod", nlsmod);
1415 #ifndef TCONFIG_SAMBA3
1416 if (nvram_match("smbd_cset", "utf8"))
1417 fprintf(fp, " coding system = utf8\n");
1418 else if (nvram_invmatch("smbd_cset", ""))
1419 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1420 #endif
1422 nv = nvram_safe_get("smbd_custom");
1423 /* add socket options unless overriden by the user */
1424 if (strstr(nv, "socket options") == NULL) {
1425 fprintf(fp, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1427 fprintf(fp, "%s\n\n", nv);
1429 /* configure shares */
1431 char *buf;
1432 char *p, *q;
1433 char *name, *path, *comment, *writeable, *hidden;
1434 int cnt = 0;
1436 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1438 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1440 p = buf;
1441 while ((q = strsep(&p, ">")) != NULL) {
1442 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1443 if (!path || !name) continue;
1445 /* share name */
1446 fprintf(fp, "\n[%s]\n", name);
1448 /* path */
1449 fprintf(fp, " path = %s\n", path);
1451 /* access level */
1452 if (!strcmp(writeable, "1"))
1453 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1454 if (!strcmp(hidden, "1"))
1455 fprintf(fp, " browseable = no\n");
1457 /* comment */
1458 if (comment)
1459 fprintf(fp, " comment = %s\n", comment);
1461 cnt++;
1463 free(buf);
1466 /* Share every mountpoint below MOUNT_ROOT */
1467 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1468 while ((dp = readdir(dir))) {
1469 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1471 /* Only if is a directory and is mounted */
1472 if (!dir_is_mountpoint(MOUNT_ROOT, dp->d_name))
1473 continue;
1475 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1476 fprintf(fp, "\n[%s]\n path = %s/%s\n comment = %s\n",
1477 dp->d_name, MOUNT_ROOT, dp->d_name, dp->d_name);
1478 if (nvram_match("smbd_autoshare", "3")) // Hidden
1479 fprintf(fp, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1480 dp->d_name, MOUNT_ROOT, dp->d_name);
1481 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1482 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1484 cnt++;
1488 if (dir) closedir(dir);
1490 if (cnt == 0) {
1491 /* by default share MOUNT_ROOT as read-only */
1492 fprintf(fp, "\n[share]\n"
1493 " path = %s\n"
1494 " writable = no\n",
1495 MOUNT_ROOT);
1498 fclose(fp);
1500 mkdir_if_none("/var/run/samba");
1501 mkdir_if_none("/etc/samba");
1503 /* write smbpasswd */
1504 #ifdef TCONFIG_SAMBA3
1505 eval("smbpasswd", "nobody", "\"\"");
1506 #else
1507 eval("smbpasswd", "-a", "nobody", "\"\"");
1508 #endif
1509 if (mode == 2) {
1510 char *smbd_user;
1511 if (((smbd_user = nvram_get("smbd_user")) == NULL) || (*smbd_user == 0) || !strcmp(smbd_user, "root"))
1512 smbd_user = "nas";
1513 #ifdef TCONFIG_SAMBA3
1514 eval("smbpasswd", smbd_user, nvram_safe_get("smbd_passwd"));
1515 #else
1516 eval("smbpasswd", "-a", smbd_user, nvram_safe_get("smbd_passwd"));
1517 #endif
1520 kill_samba(SIGHUP);
1521 int ret1 = 0, ret2 = 0;
1522 /* start samba if it's not already running */
1523 if (pidof("nmbd") <= 0)
1524 ret1 = xstart("nmbd", "-D");
1525 if (pidof("smbd") <= 0)
1526 ret2 = xstart("smbd", "-D");
1528 if (ret1 || ret2) kill_samba(SIGTERM);
1531 static void stop_samba(void)
1533 if (getpid() != 1) {
1534 stop_service("smbd");
1535 return;
1538 kill_samba(SIGTERM);
1539 /* clean up */
1540 unlink("/var/log/smb");
1541 unlink("/var/log/nmb");
1542 eval("rm", "-rf", "/var/run/samba");
1544 #endif // TCONFIG_SAMBASRV
1546 #ifdef TCONFIG_MEDIA_SERVER
1547 #define MEDIA_SERVER_APP "minidlna"
1549 static void start_media_server(void)
1551 FILE *f;
1552 int port, pid, https;
1553 char *dbdir;
1554 char *argv[] = { MEDIA_SERVER_APP, "-f", "/etc/"MEDIA_SERVER_APP".conf", "-R", NULL };
1555 static int once = 1;
1557 if (getpid() != 1) {
1558 start_service("media");
1559 return;
1562 if (nvram_get_int("ms_sas") == 0)
1563 once = 0;
1565 if (nvram_get_int("ms_enable") != 0) {
1566 if ((!once) && (nvram_get_int("ms_rescan") == 0)) {
1567 // no forced rescan
1568 argv[3] = NULL;
1570 nvram_unset("ms_rescan");
1572 if (f_exists("/etc/"MEDIA_SERVER_APP".alt")) {
1573 argv[2] = "/etc/"MEDIA_SERVER_APP".alt";
1575 else {
1576 if ((f = fopen(argv[2], "w")) != NULL) {
1577 port = nvram_get_int("ms_port");
1578 https = nvram_get_int("https_enable");
1579 dbdir = nvram_safe_get("ms_dbdir");
1580 if (!(*dbdir)) dbdir = NULL;
1581 mkdir_if_none(dbdir ? : "/var/run/"MEDIA_SERVER_APP);
1583 fprintf(f,
1584 "network_interface=%s\n"
1585 "port=%d\n"
1586 "friendly_name=%s\n"
1587 "db_dir=%s/.db\n"
1588 "enable_tivo=%s\n"
1589 "strict_dlna=%s\n"
1590 "presentation_url=http%s://%s:%s/nas-media.asp\n"
1591 "inotify=yes\n"
1592 "notify_interval=600\n"
1593 "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"
1594 "\n",
1595 nvram_safe_get("lan_ifname"),
1596 (port < 0) || (port >= 0xffff) ? 0 : port,
1597 nvram_get("router_name") ? : "Tomato",
1598 dbdir ? : "/var/run/"MEDIA_SERVER_APP,
1599 nvram_get_int("ms_tivo") ? "yes" : "no",
1600 nvram_get_int("ms_stdlna") ? "yes" : "no",
1601 https ? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https ? "https_lanport" : "http_lanport")
1604 // media directories
1605 char *buf, *p, *q;
1606 char *path, *restrict;
1608 if ((buf = strdup(nvram_safe_get("ms_dirs"))) != NULL) {
1609 /* path<restrict[A|V|P|] */
1611 p = buf;
1612 while ((q = strsep(&p, ">")) != NULL) {
1613 if (vstrsep(q, "<", &path, &restrict) < 1 || !path || !(*path))
1614 continue;
1615 fprintf(f, "media_dir=%s%s%s\n",
1616 restrict ? : "", (restrict && *restrict) ? "," : "", path);
1618 free(buf);
1621 fclose(f);
1625 /* start media server if it's not already running */
1626 if (pidof(MEDIA_SERVER_APP) <= 0) {
1627 if ((_eval(argv, NULL, 0, &pid) == 0) && (once)) {
1628 /* If we started the media server successfully, wait 1 sec
1629 * to let it die if it can't open the database file.
1630 * If it's still alive after that, assume it's running and
1631 * disable forced once-after-reboot rescan.
1633 sleep(1);
1634 if (pidof(MEDIA_SERVER_APP) > 0)
1635 once = 0;
1641 static void stop_media_server(void)
1643 if (getpid() != 1) {
1644 stop_service("media");
1645 return;
1648 killall_tk(MEDIA_SERVER_APP);
1650 #endif // TCONFIG_MEDIA_SERVER
1652 #ifdef TCONFIG_USB
1653 static void start_nas_services(void)
1655 if (getpid() != 1) {
1656 start_service("usbapps");
1657 return;
1660 #ifdef TCONFIG_SAMBASRV
1661 start_samba();
1662 #endif
1663 #ifdef TCONFIG_FTP
1664 start_ftpd();
1665 #endif
1666 #ifdef TCONFIG_MEDIA_SERVER
1667 start_media_server();
1668 #endif
1671 static void stop_nas_services(void)
1673 if (getpid() != 1) {
1674 stop_service("usbapps");
1675 return;
1678 #ifdef TCONFIG_MEDIA_SERVER
1679 stop_media_server();
1680 #endif
1681 #ifdef TCONFIG_FTP
1682 stop_ftpd();
1683 #endif
1684 #ifdef TCONFIG_SAMBASRV
1685 stop_samba();
1686 #endif
1689 void restart_nas_services(int stop, int start)
1691 int fd = file_lock("usb");
1692 /* restart all NAS applications */
1693 if (stop)
1694 stop_nas_services();
1695 if (start)
1696 start_nas_services();
1697 file_unlock(fd);
1699 #endif // TCONFIG_USB
1701 // -----------------------------------------------------------------------------
1703 /* -1 = Don't check for this program, it is not expected to be running.
1704 * Other = This program has been started and should be kept running. If no
1705 * process with the name is running, call func to restart it.
1706 * Note: At startup, dnsmasq forks a short-lived child which forks a
1707 * long-lived (grand)child. The parents terminate.
1708 * Many daemons use this technique.
1710 static void _check(pid_t pid, const char *name, void (*func)(void))
1712 if (pid == -1) return;
1714 if (pidof(name) > 0) return;
1716 syslog(LOG_DEBUG, "%s terminated unexpectedly, restarting.\n", name);
1717 func();
1719 // Force recheck in 500 msec
1720 setitimer(ITIMER_REAL, &pop_tv, NULL);
1723 void check_services(void)
1725 TRACE_PT("keep alive\n");
1727 // Periodically reap any zombies
1728 setitimer(ITIMER_REAL, &zombie_tv, NULL);
1730 #ifdef LINUX26
1731 _check(pid_hotplug2, "hotplug2", start_hotplug2);
1732 #endif
1733 _check(pid_dnsmasq, "dnsmasq", start_dnsmasq);
1734 _check(pid_crond, "crond", start_cron);
1735 _check(pid_igmp, "igmpproxy", start_igmp_proxy);
1736 #ifdef TCONFIG_IPV6
1737 _check(pid_radvd, "radvd", start_radvd);
1738 #endif
1741 // -----------------------------------------------------------------------------
1743 void start_services(void)
1745 static int once = 1;
1747 if (once) {
1748 once = 0;
1750 if (nvram_get_int("telnetd_eas")) start_telnetd();
1751 if (nvram_get_int("sshd_eas")) start_sshd();
1754 // start_syslog();
1755 start_nas();
1756 start_zebra();
1757 start_dnsmasq();
1758 start_cifs();
1759 start_httpd();
1760 start_cron();
1761 // start_upnp();
1762 start_rstats(0);
1763 start_sched();
1764 #ifdef TCONFIG_IPV6
1765 /* note: starting radvd here might be too early in case of
1766 * DHCPv6 or 6to4 because we won't have received a prefix and
1767 * so it will disable advertisements. To restart them, we have
1768 * to send radvd a SIGHUP, or restart it.
1770 start_radvd();
1771 #endif
1772 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
1774 #ifdef TCONFIG_BT
1775 start_bittorrent();
1776 #endif
1778 #ifdef TCONFIG_NFS
1779 start_nfs();
1780 #endif
1783 void stop_services(void)
1785 clear_resolv();
1787 #ifdef TCONFIG_BT
1788 stop_bittorrent();
1789 #endif
1791 #ifdef TCONFIG_NFS
1792 stop_nfs();
1793 #endif
1794 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
1795 #ifdef TCONFIG_IPV6
1796 stop_radvd();
1797 #endif
1798 stop_sched();
1799 stop_rstats();
1800 // stop_upnp();
1801 stop_cron();
1802 stop_httpd();
1803 stop_cifs();
1804 stop_dnsmasq();
1805 stop_zebra();
1806 stop_nas();
1807 // stop_syslog();
1810 // -----------------------------------------------------------------------------
1812 /* nvram "action_service" is: "service-action[-modifier]"
1813 * action is something like "stop" or "start" or "restart"
1814 * optional modifier is "c" for the "service" command-line command
1816 void exec_service(void)
1818 const int A_START = 1;
1819 const int A_STOP = 2;
1820 const int A_RESTART = 1|2;
1821 char buffer[128];
1822 char *service;
1823 char *act;
1824 char *next;
1825 char *modifier;
1826 int action, user;
1827 int i;
1829 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
1830 next = buffer;
1832 TOP:
1833 act = strsep(&next, ",");
1834 service = strsep(&act, "-");
1835 if (act == NULL) {
1836 next = NULL;
1837 goto CLEAR;
1839 modifier = act;
1840 strsep(&modifier, "-");
1842 TRACE_PT("service=%s action=%s modifier=%s\n", service, act, modifier ? : "");
1844 if (strcmp(act, "start") == 0) action = A_START;
1845 else if (strcmp(act, "stop") == 0) action = A_STOP;
1846 else if (strcmp(act, "restart") == 0) action = A_RESTART;
1847 else action = 0;
1848 user = (modifier != NULL && *modifier == 'c');
1850 if (strcmp(service, "dhcpc") == 0) {
1851 if (action & A_STOP) stop_dhcpc();
1852 if (action & A_START) start_dhcpc();
1853 goto CLEAR;
1856 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
1857 if (action & A_STOP) stop_dnsmasq();
1858 if (action & A_START) {
1859 dns_to_resolv();
1860 start_dnsmasq();
1862 goto CLEAR;
1865 if (strcmp(service, "firewall") == 0) {
1866 if (action & A_STOP) {
1867 stop_firewall();
1868 stop_igmp_proxy();
1870 if (action & A_START) {
1871 start_firewall();
1872 start_igmp_proxy();
1874 goto CLEAR;
1877 if (strcmp(service, "restrict") == 0) {
1878 if (action & A_STOP) {
1879 stop_firewall();
1881 if (action & A_START) {
1882 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
1884 start_firewall();
1886 // if radio was disabled by access restriction, but no rule is handling it now, enable it
1887 if (i == 1) {
1888 if (nvram_get_int("rrules_radio") < 0) {
1889 eval("radio", "on");
1893 goto CLEAR;
1896 if (strcmp(service, "qos") == 0) {
1897 if (action & A_STOP) {
1898 stop_qos();
1900 stop_firewall(); start_firewall(); // always restarted
1901 if (action & A_START) {
1902 start_qos();
1903 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
1905 goto CLEAR;
1908 if (strcmp(service, "qoslimit") == 0) {
1909 if (action & A_STOP) {
1910 new_qoslimit_stop();
1912 stop_firewall(); start_firewall(); // always restarted
1913 if (action & A_START) {
1914 new_qoslimit_start();
1916 goto CLEAR;
1919 if (strcmp(service, "arpbind") == 0) {
1920 if (action & A_STOP) new_arpbind_stop();
1921 if (action & A_START) new_arpbind_start();
1922 goto CLEAR;
1925 if (strcmp(service, "upnp") == 0) {
1926 if (action & A_STOP) {
1927 stop_upnp();
1929 stop_firewall(); start_firewall(); // always restarted
1930 if (action & A_START) {
1931 start_upnp();
1933 goto CLEAR;
1936 if (strcmp(service, "telnetd") == 0) {
1937 if (action & A_STOP) stop_telnetd();
1938 if (action & A_START) start_telnetd();
1939 goto CLEAR;
1942 if (strcmp(service, "sshd") == 0) {
1943 if (action & A_STOP) stop_sshd();
1944 if (action & A_START) start_sshd();
1945 goto CLEAR;
1948 if (strcmp(service, "httpd") == 0) {
1949 if (action & A_STOP) stop_httpd();
1950 if (action & A_START) start_httpd();
1951 goto CLEAR;
1954 #ifdef TCONFIG_IPV6
1955 if (strcmp(service, "ipv6") == 0) {
1956 if (action & A_STOP) {
1957 stop_radvd();
1958 stop_ipv6();
1960 if (action & A_START) {
1961 start_ipv6();
1962 start_radvd();
1964 goto CLEAR;
1967 if (strcmp(service, "radvd") == 0) {
1968 if (action & A_STOP) {
1969 stop_radvd();
1971 if (action & A_START) {
1972 start_radvd();
1974 goto CLEAR;
1977 if (strncmp(service, "dhcp6", 5) == 0) {
1978 if (action & A_STOP) {
1979 stop_dhcp6c();
1981 if (action & A_START) {
1982 start_dhcp6c();
1984 goto CLEAR;
1986 #endif
1988 if (strcmp(service, "admin") == 0) {
1989 if (action & A_STOP) {
1990 stop_sshd();
1991 stop_telnetd();
1992 stop_httpd();
1994 stop_firewall(); start_firewall(); // always restarted
1995 if (action & A_START) {
1996 start_httpd();
1997 create_passwd();
1998 if (nvram_match("telnetd_eas", "1")) start_telnetd();
1999 if (nvram_match("sshd_eas", "1")) start_sshd();
2001 goto CLEAR;
2004 if (strcmp(service, "ddns") == 0) {
2005 if (action & A_STOP) stop_ddns();
2006 if (action & A_START) start_ddns();
2007 goto CLEAR;
2010 if (strcmp(service, "ntpc") == 0) {
2011 if (action & A_STOP) stop_ntpc();
2012 if (action & A_START) start_ntpc();
2013 goto CLEAR;
2016 if (strcmp(service, "logging") == 0) {
2017 if (action & A_STOP) {
2018 stop_syslog();
2020 if (action & A_START) {
2021 start_syslog();
2023 if (!user) {
2024 // always restarted except from "service" command
2025 stop_cron(); start_cron();
2026 stop_firewall(); start_firewall();
2028 goto CLEAR;
2031 if (strcmp(service, "crond") == 0) {
2032 if (action & A_STOP) {
2033 stop_cron();
2035 if (action & A_START) {
2036 start_cron();
2038 goto CLEAR;
2041 #ifdef LINUX26
2042 if (strncmp(service, "hotplug", 7) == 0) {
2043 if (action & A_STOP) {
2044 stop_hotplug2();
2046 if (action & A_START) {
2047 start_hotplug2(1);
2049 goto CLEAR;
2051 #endif
2053 if (strcmp(service, "upgrade") == 0) {
2054 if (action & A_START) {
2055 #if TOMATO_SL
2056 stop_usbevent();
2057 stop_smbd();
2058 #endif
2059 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2060 stop_jffs2();
2061 // stop_cifs();
2062 stop_zebra();
2063 stop_cron();
2064 stop_ntpc();
2065 stop_upnp();
2066 // stop_dhcpc();
2067 killall("rstats", SIGTERM);
2068 killall("buttons", SIGTERM);
2069 stop_syslog();
2070 remove_storage_main(1); // !!TB - USB Support
2071 stop_usb(); // !!TB - USB Support
2073 goto CLEAR;
2076 #ifdef TCONFIG_CIFS
2077 if (strcmp(service, "cifs") == 0) {
2078 if (action & A_STOP) stop_cifs();
2079 if (action & A_START) start_cifs();
2080 goto CLEAR;
2082 #endif
2084 #ifdef TCONFIG_JFFS2
2085 if (strncmp(service, "jffs", 4) == 0) {
2086 if (action & A_STOP) stop_jffs2();
2087 if (action & A_START) start_jffs2();
2088 goto CLEAR;
2090 #endif
2092 if (strcmp(service, "zebra") == 0) {
2093 if (action & A_STOP) stop_zebra();
2094 if (action & A_START) start_zebra();
2095 goto CLEAR;
2098 if (strcmp(service, "routing") == 0) {
2099 if (action & A_STOP) {
2100 stop_zebra();
2101 do_static_routes(0); // remove old '_saved'
2102 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2104 stop_firewall();
2105 start_firewall();
2106 if (action & A_START) {
2107 do_static_routes(1); // add new
2108 start_zebra();
2109 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2111 goto CLEAR;
2114 if (strcmp(service, "ctnf") == 0) {
2115 if (action & A_START) {
2116 setup_conntrack();
2117 stop_firewall();
2118 start_firewall();
2120 goto CLEAR;
2123 if (strcmp(service, "wan") == 0) {
2124 if (action & A_STOP) {
2125 stop_wan();
2128 if (action & A_START) {
2129 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2130 start_wan(BOOT);
2131 sleep(2);
2132 force_to_dial();
2134 goto CLEAR;
2137 if (strcmp(service, "net") == 0) {
2138 if (action & A_STOP) {
2139 #ifdef TCONFIG_USB
2140 stop_nas_services();
2141 #endif
2142 #ifdef TCONFIG_IPV6
2143 stop_radvd();
2144 #endif
2145 stop_httpd();
2146 stop_dnsmasq();
2147 stop_nas();
2148 stop_wan();
2149 stop_lan();
2150 stop_vlan();
2152 if (action & A_START) {
2153 start_vlan();
2154 start_lan();
2155 start_wan(BOOT);
2156 start_nas();
2157 start_dnsmasq();
2158 start_httpd();
2159 #ifdef TCONFIG_IPV6
2160 start_radvd();
2161 #endif
2162 start_wl();
2163 #ifdef TCONFIG_USB
2164 start_nas_services();
2165 #endif
2167 goto CLEAR;
2170 if (strcmp(service, "nas") == 0) {
2171 if (action & A_STOP) {
2172 stop_nas();
2174 if (action & A_START) {
2175 start_nas();
2176 start_wl();
2178 goto CLEAR;
2181 if (strcmp(service, "rstats") == 0) {
2182 if (action & A_STOP) stop_rstats();
2183 if (action & A_START) start_rstats(0);
2184 goto CLEAR;
2187 if (strcmp(service, "rstatsnew") == 0) {
2188 if (action & A_STOP) stop_rstats();
2189 if (action & A_START) start_rstats(1);
2190 goto CLEAR;
2193 if (strcmp(service, "sched") == 0) {
2194 if (action & A_STOP) stop_sched();
2195 if (action & A_START) start_sched();
2196 goto CLEAR;
2199 #ifdef TCONFIG_BT
2200 if (strcmp(service, "bittorrent") == 0) {
2201 if (action & A_STOP) {
2202 stop_bittorrent();
2204 stop_firewall(); start_firewall(); // always restarted
2205 if (action & A_START) {
2206 start_bittorrent();
2208 goto CLEAR;
2210 #endif
2212 #ifdef TCONFIG_NFS
2213 if (strcmp(service, "nfs") == 0) {
2214 if (action & A_STOP) stop_nfs();
2215 if (action & A_START) start_nfs();
2216 goto CLEAR;
2218 #endif
2220 #ifdef TCONFIG_USB
2221 // !!TB - USB Support
2222 if (strcmp(service, "usb") == 0) {
2223 if (action & A_STOP) stop_usb();
2224 if (action & A_START) {
2225 start_usb();
2226 // restart Samba and ftp since they may be killed by stop_usb()
2227 restart_nas_services(0, 1);
2228 // remount all partitions by simulating hotplug event
2229 add_remove_usbhost("-1", 1);
2231 goto CLEAR;
2234 if (strcmp(service, "usbapps") == 0) {
2235 if (action & A_STOP) stop_nas_services();
2236 if (action & A_START) start_nas_services();
2237 goto CLEAR;
2239 #endif
2241 #ifdef TCONFIG_FTP
2242 // !!TB - FTP Server
2243 if (strcmp(service, "ftpd") == 0) {
2244 if (action & A_STOP) stop_ftpd();
2245 setup_conntrack();
2246 stop_firewall();
2247 start_firewall();
2248 if (action & A_START) start_ftpd();
2249 goto CLEAR;
2251 #endif
2253 #ifdef TCONFIG_MEDIA_SERVER
2254 if (strcmp(service, "media") == 0 || strcmp(service, "dlna") == 0) {
2255 if (action & A_STOP) stop_media_server();
2256 if (action & A_START) start_media_server();
2257 goto CLEAR;
2259 #endif
2261 #ifdef TCONFIG_SAMBASRV
2262 // !!TB - Samba
2263 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
2264 if (action & A_STOP) stop_samba();
2265 if (action & A_START) {
2266 create_passwd();
2267 stop_dnsmasq();
2268 start_dnsmasq();
2269 start_samba();
2271 goto CLEAR;
2273 #endif
2275 #ifdef TCONFIG_OPENVPN
2276 if (strncmp(service, "vpnclient", 9) == 0) {
2277 if (action & A_STOP) stop_vpnclient(atoi(&service[9]));
2278 if (action & A_START) start_vpnclient(atoi(&service[9]));
2279 goto CLEAR;
2282 if (strncmp(service, "vpnserver", 9) == 0) {
2283 if (action & A_STOP) stop_vpnserver(atoi(&service[9]));
2284 if (action & A_START) start_vpnserver(atoi(&service[9]));
2285 goto CLEAR;
2287 #endif
2289 CLEAR:
2290 if (next) goto TOP;
2292 // some functions check action_service and must be cleared at end -- zzz
2293 nvram_set("action_service", "");
2295 // Force recheck in 500 msec
2296 setitimer(ITIMER_REAL, &pop_tv, NULL);
2299 static void do_service(const char *name, const char *action, int user)
2301 int n;
2302 char s[64];
2304 n = 150;
2305 while (!nvram_match("action_service", "")) {
2306 if (user) {
2307 putchar('*');
2308 fflush(stdout);
2310 else if (--n < 0) break;
2311 usleep(100 * 1000);
2314 snprintf(s, sizeof(s), "%s-%s%s", name, action, (user ? "-c" : ""));
2315 nvram_set("action_service", s);
2316 kill(1, SIGUSR1);
2318 n = 150;
2319 while (nvram_match("action_service", s)) {
2320 if (user) {
2321 putchar('.');
2322 fflush(stdout);
2324 else if (--n < 0) {
2325 break;
2327 usleep(100 * 1000);
2331 int service_main(int argc, char *argv[])
2333 if (argc != 3) usage_exit(argv[0], "<service> <action>");
2334 do_service(argv[1], argv[2], 1);
2335 printf("\nDone.\n");
2336 return 0;
2339 void start_service(const char *name)
2341 do_service(name, "start", 0);
2344 void stop_service(const char *name)
2346 do_service(name, "stop", 0);
2350 void restart_service(const char *name)
2352 do_service(name, "restart", 0);