dnscrypto-proxy: Support files updated.
[tomato.git] / release / src / router / rc / services.c
blob6497f44870ce6743a96d2fe13842f91dd7c3cd71
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");
171 // dhcp
172 do_dhcpd_hosts=0;
173 char lanN_proto[] = "lanXX_proto";
174 char lanN_ifname[] = "lanXX_ifname";
175 char lanN_ipaddr[] = "lanXX_ipaddr";
176 char lanN_netmask[] = "lanXX_netmask";
177 char dhcpdN_startip[] = "dhcpdXX_startip";
178 char dhcpdN_endip[] = "dhcpdXX_endip";
179 char dhcpN_start[] = "dhcpXX_start";
180 char dhcpN_num[] = "dhcpXX_num";
181 char dhcpN_lease[] = "dhcpXX_lease";
182 char br;
183 for(br=0 ; br<=3 ; br++) {
184 char bridge[2] = "0";
185 if (br!=0)
186 bridge[0]+=br;
187 else
188 strcpy(bridge, "");
190 sprintf(lanN_proto, "lan%s_proto", bridge);
191 sprintf(lanN_ifname, "lan%s_ifname", bridge);
192 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
193 do_dhcpd = nvram_match(lanN_proto, "dhcp");
194 if (do_dhcpd) {
195 do_dhcpd_hosts++;
197 router_ip = nvram_safe_get(lanN_ipaddr);
198 strlcpy(lan, router_ip, sizeof(lan));
199 if ((p = strrchr(lan, '.')) != NULL) *(p + 1) = 0;
201 fprintf(f,
202 "interface=%s\n",
203 nvram_safe_get(lanN_ifname));
205 sprintf(dhcpN_lease, "dhcp%s_lease", bridge);
206 dhcp_lease = nvram_get_int(dhcpN_lease);
208 if (dhcp_lease <= 0) dhcp_lease = 1440;
210 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
211 if (n < 0) strcpy(sdhcp_lease, "infinite");
212 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
214 if (!do_dns) {
215 // if not using dnsmasq for dns
217 if ((dns->count == 0) && (nvram_get_int("dhcpd_llndns"))) {
218 // no DNS might be temporary. use a low lease time to force clients to update.
219 dhcp_lease = 2;
220 strcpy(sdhcp_lease, "2m");
221 do_dns = 1;
223 else {
224 // pass the dns directly
225 buf[0] = 0;
226 for (n = 0 ; n < dns->count; ++n) {
227 if (dns->dns[n].port == 53) { // check: option 6 doesn't seem to support other ports
228 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n].addr));
231 fprintf(f, "dhcp-option=tag:%s,6%s\n", nvram_safe_get(lanN_ifname), buf);
235 sprintf(dhcpdN_startip, "dhcpd%s_startip", bridge);
236 sprintf(dhcpdN_endip, "dhcpd%s_endip", bridge);
237 sprintf(lanN_netmask, "lan%s_netmask", bridge);
239 if ((p = nvram_get(dhcpdN_startip)) && (*p) && (e = nvram_get(dhcpdN_endip)) && (*e)) {
240 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);
242 else {
243 // for compatibility
244 sprintf(dhcpN_start, "dhcp%s_start", bridge);
245 sprintf(dhcpN_num, "dhcp%s_num", bridge);
246 sprintf(lanN_netmask, "lan%s_netmask", bridge);
247 dhcp_start = nvram_get_int(dhcpN_start);
248 dhcp_count = nvram_get_int(dhcpN_num);
249 fprintf(f, "dhcp-range=tag:%s,%s%d,%s%d,%s,%dm\n",
250 nvram_safe_get(lanN_ifname), lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get(lanN_netmask), dhcp_lease);
253 nv = nvram_safe_get(lanN_ipaddr);
254 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED)) {
255 p = nvram_safe_get("lan_gateway");
256 if ((*p) && (strcmp(p, "0.0.0.0") != 0)) nv = p;
258 #ifdef TCONFIG_VLAN
259 fprintf(f,
260 "dhcp-option=tag:%s,3,%s\n", // gateway
261 nvram_safe_get(lanN_ifname), nv);
262 #endif
263 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
264 fprintf(f, "dhcp-option=tag:%s,44,%s\n", nvram_safe_get(lanN_ifname), nv);
266 #ifdef TCONFIG_SAMBASRV
267 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
268 if ((nv == NULL) || (*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
269 // Samba will serve as a WINS server
270 fprintf(f, "dhcp-option=tag:%s,44,%s\n", nvram_safe_get(lanN_ifname), nvram_safe_get(lanN_ipaddr));
273 #endif
274 } else {
275 if (strcmp(nvram_safe_get(lanN_ifname),"")!=0) {
276 fprintf(f, "interface=%s\n", nvram_safe_get(lanN_ifname));
277 // if no dhcp range is set then no dhcp service will be offered so following
278 // line is superflous.
279 // fprintf(f, "no-dhcp-interface=%s\n", nvram_safe_get(lanN_ifname));
283 // write static lease entries & create hosts file
285 mkdir_if_none(dmhosts);
286 snprintf(buf, sizeof(buf), "%s/hosts", dmhosts);
287 if ((hf = fopen(buf, "w")) != NULL) {
288 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
289 fprintf(hf, "%s %s\n", router_ip, nv);
290 #ifdef TCONFIG_SAMBASRV
291 else if (((nv = nvram_get("lan_hostname")) != NULL) && (*nv))
292 fprintf(hf, "%s %s\n", router_ip, nv);
293 #endif
294 p = (char *)get_wanip();
295 if ((*p == 0) || strcmp(p, "0.0.0.0") == 0)
296 p = "127.0.0.1";
297 fprintf(hf, "%s wan-ip\n", p);
298 if (nv && (*nv))
299 fprintf(hf, "%s %s-wan\n", p, nv);
302 mkdir_if_none(dmdhcp);
303 snprintf(buf, sizeof(buf), "%s/dhcp-hosts", dmdhcp);
304 df = fopen(buf, "w");
306 // PREVIOUS/OLD FORMAT:
307 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
308 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
309 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 106 w/ delim
311 // NEW FORMAT (+static ARP binding after hostname):
312 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 55 w/ delim
313 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 87 w/ delim
314 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 108 w/ delim
316 p = nvram_safe_get("dhcpd_static");
317 while ((e = strchr(p, '>')) != NULL) {
318 n = (e - p);
319 if (n > 107) {
320 p = e + 1;
321 continue;
324 strncpy(buf, p, n);
325 buf[n] = 0;
326 p = e + 1;
328 if ((e = strchr(buf, '<')) == NULL) continue;
329 *e = 0;
330 mac = buf;
332 ip = e + 1;
333 if ((e = strchr(ip, '<')) == NULL) continue;
334 *e = 0;
335 if (strchr(ip, '.') == NULL) {
336 ipn = atoi(ip);
337 if ((ipn <= 0) || (ipn > 255)) continue;
338 sprintf(ipbuf, "%s%d", lan, ipn);
339 ip = ipbuf;
341 else {
342 if (inet_addr(ip) == INADDR_NONE) continue;
345 name = e + 1;
347 if ((e = strchr(name, '<')) != NULL) {
348 *e = 0;
351 if ((hf) && (*name != 0)) {
352 fprintf(hf, "%s %s\n", ip, name);
355 if ((do_dhcpd_hosts > 0) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
356 char static_dhcp_lease[32];
357 strcpy(static_dhcp_lease, "");
358 if (nvram_get_int("dhcpd_slt") != 0)
359 sprintf(static_dhcp_lease, ",%s", sdhcp_lease);
360 if (df)
361 fprintf(df, "%s,%s%s\n", mac, ip, static_dhcp_lease);
362 else
363 fprintf(f, "dhcp-host=%s,%s%s\n", mac, ip, static_dhcp_lease);
367 if (df) fclose(df);
368 if (hf) fclose(hf);
370 n = nvram_get_int("dhcpd_lmax");
371 fprintf(f,
372 "dhcp-lease-max=%d\n",
373 (n > 0) ? n : 255);
374 if (nvram_get_int("dhcpd_auth") >= 0) {
375 fprintf(f, "dhcp-authoritative\n");
378 #ifdef TCONFIG_DNSCRYPT
379 if (nvram_match("dnscrypt_proxy", "1")) {
380 fprintf(f, "strict-order\n");
382 #endif
386 #ifdef TCONFIG_OPENVPN
387 write_vpn_dnsmasq_config(f);
388 #endif
390 #ifdef TCONFIG_PPTPD
391 write_pptpd_dnsmasq_config(f);
392 #endif
394 #ifdef TCONFIG_IPV6
395 if (ipv6_enabled() && nvram_get_int("ipv6_radvd")) {
396 service = get_ipv6_service();
397 do_6to4 = (service == IPV6_ANYCAST_6TO4);
398 do_6rd = (service == IPV6_6RD || service == IPV6_6RD_DHCP);
399 mtu = NULL;
401 switch (service) {
402 case IPV6_NATIVE_DHCP:
403 case IPV6_ANYCAST_6TO4:
404 case IPV6_6IN4:
405 case IPV6_6RD:
406 case IPV6_6RD_DHCP:
407 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
408 // fall through
409 default:
410 prefix = do_6to4 ? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
411 break;
413 if (!(*prefix)) prefix = "::";
414 // ipv6 = (char *)ipv6_router_address(NULL);
416 fprintf(f, "enable-ra\ndhcp-range=tag:br0,%s, slaac, ra-names, 64\n", prefix);
419 #endif
421 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
423 fappend(f, "/etc/dnsmasq.custom");
427 fclose(f);
429 if (do_dns) {
430 unlink("/etc/resolv.conf");
431 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
434 TRACE_PT("run dnsmasq\n");
436 // Default to some values we like, but allow the user to override them.
437 eval("dnsmasq", "-c", "1500", "--log-async");
439 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
440 pid_dnsmasq = -2;
443 TRACE_PT("end\n");
445 #ifdef TCONFIG_DNSCRYPT
446 //start dnscrypt-proxy
447 if (nvram_match("dnscrypt_proxy", "1")) {
448 eval("ntp2ip");
450 char dnscrypt_local[30];
451 sprintf(dnscrypt_local, "127.0.0.1:%s", nvram_safe_get("dnscrypt_port") );
452 eval("dnscrypt-proxy", "-d", "-a", dnscrypt_local, nvram_safe_get("dnscrypt_cmd") );
454 #endif
458 void stop_dnsmasq(void)
460 TRACE_PT("begin\n");
462 if (getpid() != 1) {
463 stop_service("dnsmasq");
464 return;
467 pid_dnsmasq = -1;
469 unlink("/etc/resolv.conf");
470 symlink(dmresolv, "/etc/resolv.conf");
472 killall_tk("dnsmasq");
473 #ifdef TCONFIG_DNSCRYPT
474 killall_tk("dnscrypt-proxy");
475 #endif
477 TRACE_PT("end\n");
480 void clear_resolv(void)
482 f_write(dmresolv, NULL, 0, 0, 0); // blank
485 #ifdef TCONFIG_IPV6
486 static int write_ipv6_dns_servers(FILE *f, const char *prefix, char *dns, const char *suffix, int once)
488 char p[INET6_ADDRSTRLEN + 1], *next = NULL;
489 struct in6_addr addr;
490 int cnt = 0;
492 foreach(p, dns, next) {
493 // verify that this is a valid IPv6 address
494 if (inet_pton(AF_INET6, p, &addr) == 1) {
495 fprintf(f, "%s%s%s", (once && cnt) ? "" : prefix, p, suffix);
496 ++cnt;
500 return cnt;
502 #endif
504 void dns_to_resolv(void)
506 FILE *f;
507 const dns_list_t *dns;
508 int i;
509 mode_t m;
511 m = umask(022); // 077 from pppoecd
512 if ((f = fopen(dmresolv, "w")) != NULL) {
513 // Check for VPN DNS entries
514 if (!write_pptpvpn_resolv(f) && !write_vpn_resolv(f)) {
515 #ifdef TCONFIG_IPV6
516 if (write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_dns"), "\n", 0) == 0 || nvram_get_int("dns_addget"))
517 write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_get_dns"), "\n", 0);
518 #endif
519 dns = get_dns(); // static buffer
520 if (dns->count == 0) {
521 // Put a pseudo DNS IP to trigger Connect On Demand
522 if (nvram_match("ppp_demand", "1")) {
523 switch (get_wan_proto()) {
524 case WP_PPPOE:
525 case WP_PPP3G:
526 case WP_PPTP:
527 case WP_L2TP:
528 fprintf(f, "nameserver 1.1.1.1\n");
529 break;
533 else {
534 for (i = 0; i < dns->count; i++) {
535 if (dns->dns[i].port == 53) { // resolv.conf doesn't allow for an alternate port
536 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i].addr));
541 fclose(f);
543 umask(m);
546 // -----------------------------------------------------------------------------
548 void start_httpd(void)
550 if (getpid() != 1) {
551 start_service("httpd");
552 return;
555 stop_httpd();
556 chdir("/www");
557 eval("httpd");
558 chdir("/");
561 void stop_httpd(void)
563 if (getpid() != 1) {
564 stop_service("httpd");
565 return;
568 killall_tk("httpd");
571 // -----------------------------------------------------------------------------
572 #ifdef TCONFIG_IPV6
574 static void add_ip6_lanaddr(void)
576 char ip[INET6_ADDRSTRLEN + 4];
577 const char *p;
579 p = ipv6_router_address(NULL);
580 if (*p) {
581 snprintf(ip, sizeof(ip), "%s/%d", p, nvram_get_int("ipv6_prefix_length") ? : 64);
582 eval("ip", "-6", "addr", "add", ip, "dev", nvram_safe_get("lan_ifname"));
586 void start_ipv6_tunnel(void)
588 char ip[INET6_ADDRSTRLEN + 4];
589 struct in_addr addr4;
590 struct in6_addr addr;
591 const char *wanip, *mtu, *tun_dev;
592 int service;
594 service = get_ipv6_service();
595 tun_dev = get_wan6face();
596 wanip = get_wanip();
597 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
598 modprobe("sit");
600 if (service == IPV6_ANYCAST_6TO4)
601 snprintf(ip, sizeof(ip), "192.88.99.%d", nvram_get_int("ipv6_relay"));
602 else
603 strlcpy(ip, (char *)nvram_safe_get("ipv6_tun_v4end"), sizeof(ip));
604 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit",
605 "remote", ip,
606 "local", (char *)wanip,
607 "ttl", nvram_safe_get("ipv6_tun_ttl"));
609 eval("ip", "link", "set", (char *)tun_dev, "mtu", (char *)mtu, "up");
610 nvram_set("ipv6_ifname", (char *)tun_dev);
612 if (service == IPV6_ANYCAST_6TO4) {
613 add_ip6_lanaddr();
614 addr4.s_addr = 0;
615 memset(&addr, 0, sizeof(addr));
616 inet_aton(wanip, &addr4);
617 addr.s6_addr16[0] = htons(0x2002);
618 ipv6_mapaddr4(&addr, 16, &addr4, 0);
619 addr.s6_addr16[7] = htons(0x0001);
620 inet_ntop(AF_INET6, &addr, ip, sizeof(ip));
621 strncat(ip, "/16", sizeof(ip));
623 else {
624 snprintf(ip, sizeof(ip), "%s/%d",
625 nvram_safe_get("ipv6_tun_addr"),
626 nvram_get_int("ipv6_tun_addrlen") ? : 64);
628 eval("ip", "addr", "add", ip, "dev", (char *)tun_dev);
629 eval("ip", "route", "add", "::/0", "dev", (char *)tun_dev);
631 // (re)start radvd - now dnsmasq provided
632 if (service == IPV6_ANYCAST_6TO4)
633 start_dnsmasq();
636 void stop_ipv6_tunnel(void)
638 eval("ip", "tunnel", "del", (char *)get_wan6face());
639 if (get_ipv6_service() == IPV6_ANYCAST_6TO4) {
640 // get rid of old IPv6 address from lan iface
641 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
643 modprobe_r("sit");
646 void start_6rd_tunnel(void)
648 const char *tun_dev, *wanip;
649 int service, mask_len, prefix_len, local_prefix_len;
650 char mtu[10], prefix[INET6_ADDRSTRLEN], relay[INET_ADDRSTRLEN];
651 struct in_addr netmask_addr, relay_addr, relay_prefix_addr, wanip_addr;
652 struct in6_addr prefix_addr, local_prefix_addr;
653 char local_prefix[INET6_ADDRSTRLEN];
654 char tmp_ipv6[INET6_ADDRSTRLEN + 4], tmp_ipv4[INET_ADDRSTRLEN + 4];
655 char tmp[256];
656 FILE *f;
658 service = get_ipv6_service();
659 wanip = get_wanip();
660 tun_dev = get_wan6face();
661 sprintf(mtu, "%d", (nvram_get_int("wan_mtu") > 0) ? (nvram_get_int("wan_mtu") - 20) : 1280);
663 // maybe we can merge the ipv6_6rd_* variables into a single ipv_6rd_string (ala wan_6rd)
664 // to save nvram space?
665 if (service == IPV6_6RD) {
666 _dprintf("starting 6rd tunnel using manual settings.\n");
667 mask_len = nvram_get_int("ipv6_6rd_ipv4masklen");
668 prefix_len = nvram_get_int("ipv6_6rd_prefix_length");
669 strcpy(prefix, nvram_safe_get("ipv6_6rd_prefix"));
670 strcpy(relay, nvram_safe_get("ipv6_6rd_borderrelay"));
672 else {
673 _dprintf("starting 6rd tunnel using automatic settings.\n");
674 char *wan_6rd = nvram_safe_get("wan_6rd");
675 if (sscanf(wan_6rd, "%d %d %s %s", &mask_len, &prefix_len, prefix, relay) < 4) {
676 _dprintf("wan_6rd string is missing or invalid (%s)\n", wan_6rd);
677 return;
681 // validate values that were passed
682 if (mask_len < 0 || mask_len > 32) {
683 _dprintf("invalid mask_len value (%d)\n", mask_len);
684 return;
686 if (prefix_len < 0 || prefix_len > 128) {
687 _dprintf("invalid prefix_len value (%d)\n", prefix_len);
688 return;
690 if ((32 - mask_len) + prefix_len > 128) {
691 _dprintf("invalid combination of mask_len and prefix_len!\n");
692 return;
695 sprintf(tmp, "ping -q -c 2 %s | grep packet", relay);
696 if ((f = popen(tmp, "r")) == NULL) {
697 _dprintf("error obtaining data\n");
698 return;
700 fgets(tmp, sizeof(tmp), f);
701 pclose(f);
702 if (strstr(tmp, " 0% packet loss") == NULL) {
703 _dprintf("failed to ping border relay\n");
704 return;
707 // get relay prefix from border relay address and mask
708 netmask_addr.s_addr = htonl(0xffffffff << (32 - mask_len));
709 inet_aton(relay, &relay_addr);
710 relay_prefix_addr.s_addr = relay_addr.s_addr & netmask_addr.s_addr;
712 // calculate the local prefix
713 inet_pton(AF_INET6, prefix, &prefix_addr);
714 inet_pton(AF_INET, wanip, &wanip_addr);
715 if (calc_6rd_local_prefix(&prefix_addr, prefix_len, mask_len,
716 &wanip_addr, &local_prefix_addr, &local_prefix_len) == 0) {
717 _dprintf("error calculating local prefix.");
718 return;
720 inet_ntop(AF_INET6, &local_prefix_addr, local_prefix, sizeof(local_prefix));
722 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1", local_prefix);
723 nvram_set("ipv6_rtr_addr", tmp_ipv6);
724 nvram_set("ipv6_prefix", local_prefix);
726 // load sit module needed for the 6rd tunnel
727 modprobe("sit");
729 // creating the 6rd tunnel
730 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit", "local", (char *)wanip, "ttl", nvram_safe_get("ipv6_tun_ttl"));
732 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s/%d", prefix, prefix_len);
733 snprintf(tmp_ipv4, sizeof(tmp_ipv4), "%s/%d", inet_ntoa(relay_prefix_addr), mask_len);
734 eval("ip", "tunnel" "6rd", "dev", (char *)tun_dev, "6rd-prefix", tmp_ipv6, "6rd-relay_prefix", tmp_ipv4);
736 // bringing up the link
737 eval("ip", "link", "set", "dev", (char *)tun_dev, "mtu", (char *)mtu, "up");
739 // setting the WAN address Note: IPv6 WAN CIDR should be: ((32 - ip6rd_ipv4masklen) + ip6rd_prefixlen)
740 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1/%d", local_prefix, local_prefix_len);
741 eval("ip", "-6", "addr", "add", tmp_ipv6, "dev", (char *)tun_dev);
743 // setting the LAN address Note: IPv6 LAN CIDR should be 64
744 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1/%d", local_prefix, nvram_get_int("ipv6_prefix_length") ? : 64);
745 eval("ip", "-6", "addr", "add", tmp_ipv6, "dev", nvram_safe_get("lan_ifname"));
747 // adding default route via the border relay
748 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "::%s", relay);
749 eval("ip", "-6", "route", "add", "default", "via", tmp_ipv6, "dev", (char *)tun_dev);
751 nvram_set("ipv6_ifname", (char *)tun_dev);
753 // (re)start radvd now dnsmasq
754 start_dnsmasq();
756 printf("6rd end\n");
759 void stop_6rd_tunnel(void)
761 eval("ip", "tunnel", "del", (char *)get_wan6face());
762 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
763 modprobe_r("sit");
767 void start_ipv6(void)
769 int service;
771 service = get_ipv6_service();
772 enable_ip_forward();
774 // Check if turned on
775 switch (service) {
776 case IPV6_NATIVE:
777 case IPV6_6IN4:
778 case IPV6_MANUAL:
779 add_ip6_lanaddr();
780 break;
781 case IPV6_NATIVE_DHCP:
782 case IPV6_ANYCAST_6TO4:
783 nvram_set("ipv6_rtr_addr", "");
784 nvram_set("ipv6_prefix", "");
785 break;
788 if (service != IPV6_DISABLED) {
789 if ((nvram_get_int("ipv6_accept_ra") & 2) != 0 && !nvram_get_int("ipv6_radvd"))
790 accept_ra(nvram_safe_get("lan_ifname"));
794 void stop_ipv6(void)
796 stop_ipv6_tunnel();
797 stop_dhcp6c();
798 eval("ip", "-6", "addr", "flush", "scope", "global");
801 #endif
803 // -----------------------------------------------------------------------------
805 void start_upnp(void)
807 if (getpid() != 1) {
808 start_service("upnp");
809 return;
812 if (get_wan_proto() == WP_DISABLED) return;
814 int enable;
815 FILE *f;
816 int upnp_port;
818 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
819 mkdir("/etc/upnp", 0777);
820 if (f_exists("/etc/upnp/config.alt")) {
821 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
823 else {
824 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
825 upnp_port = nvram_get_int("upnp_port");
826 if ((upnp_port < 0) || (upnp_port >= 0xFFFF)) upnp_port = 0;
829 fprintf(f,
830 "ext_ifname=%s\n"
831 "port=%d\n"
832 "enable_upnp=%s\n"
833 "enable_natpmp=%s\n"
834 "secure_mode=%s\n"
835 "upnp_forward_chain=upnp\n"
836 "upnp_nat_chain=upnp\n"
837 "notify_interval=%d\n"
838 "system_uptime=yes\n"
839 "\n"
841 get_wanface(),
842 upnp_port,
843 (enable & 1) ? "yes" : "no", // upnp enable
844 (enable & 2) ? "yes" : "no", // natpmp enable
845 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
846 nvram_get_int("upnp_ssdp_interval")
849 if (nvram_get_int("upnp_clean")) {
850 int interval = nvram_get_int("upnp_clean_interval");
851 if (interval < 60) interval = 60;
852 fprintf(f,
853 "clean_ruleset_interval=%d\n"
854 "clean_ruleset_threshold=%d\n",
855 interval,
856 nvram_get_int("upnp_clean_threshold")
859 else
860 fprintf(f,"clean_ruleset_interval=0\n");
862 if (nvram_match("upnp_mnp", "1")) {
863 int https = nvram_get_int("https_enable");
864 fprintf(f, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
865 https ? "s" : "", nvram_safe_get("lan_ipaddr"),
866 nvram_safe_get(https ? "https_lanport" : "http_lanport"));
868 else {
869 // Empty parameters are not included into XML service description
870 fprintf(f, "presentation_url=\n");
873 char uuid[45];
874 f_read_string("/proc/sys/kernel/random/uuid", uuid, sizeof(uuid));
875 fprintf(f, "uuid=%s\n", uuid);
877 #ifdef TCONFIG_VLAN
878 char lanN_ipaddr[] = "lanXX_ipaddr";
879 char lanN_netmask[] = "lanXX_netmask";
880 char upnp_lanN[] = "upnp_lanXX";
881 char br;
883 for(br=0 ; br<4 ; br++) {
884 char bridge[2] = "0";
885 if (br!=0)
886 bridge[0]+=br;
887 else
888 strcpy(bridge, "");
890 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
891 sprintf(lanN_netmask, "lan%s_netmask", bridge);
892 sprintf(upnp_lanN, "upnp_lan%s", bridge);
894 char *lanip = nvram_safe_get(lanN_ipaddr);
895 char *lanmask = nvram_safe_get(lanN_netmask);
896 char *lanlisten = nvram_safe_get(upnp_lanN);
898 if((strcmp(lanlisten,"1")==0) && (strcmp(lanip,"")!=0) && (strcmp(lanip,"0.0.0.0")!=0)) {
899 #else
900 char *lanip = nvram_safe_get("lan_ipaddr");
901 char *lanmask = nvram_safe_get("lan_netmask");
902 #endif
903 fprintf(f,
904 "listening_ip=%s/%s\n",
905 lanip, lanmask);
906 int ports[4];
907 if ((ports[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
908 (ports[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
909 (ports[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
910 (ports[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
911 fprintf(f,
912 "allow %d-%d %s/%s %d-%d\n",
913 ports[0], ports[1],
914 lanip, lanmask,
915 ports[2], ports[3]
918 else {
919 // by default allow only redirection of ports above 1024
920 fprintf(f, "allow 1024-65535 %s/%s 1024-65535\n", lanip, lanmask);
922 #ifdef TCONFIG_VLAN
925 #endif
927 fappend(f, "/jffs/upnpconfig.custom");
928 fappend(f, "/etc/upnp/config.custom");
929 fprintf(f, "%s\n", nvram_safe_get("upnp_custom"));
930 fprintf(f, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
932 fclose(f);
934 xstart("miniupnpd", "-f", "/etc/upnp/config");
940 void stop_upnp(void)
942 if (getpid() != 1) {
943 stop_service("upnp");
944 return;
947 killall_tk("miniupnpd");
950 // -----------------------------------------------------------------------------
952 static pid_t pid_crond = -1;
954 void start_cron(void)
956 stop_cron();
958 eval("crond", nvram_contains_word("log_events", "crond") ? NULL : "-l", "9");
959 if (!nvram_contains_word("debug_norestart", "crond")) {
960 pid_crond = -2;
964 void stop_cron(void)
966 pid_crond = -1;
967 killall_tk("crond");
970 // -----------------------------------------------------------------------------
971 #ifdef LINUX26
973 static pid_t pid_hotplug2 = -1;
975 void start_hotplug2()
977 stop_hotplug2();
979 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE, 0);
980 xstart("hotplug2", "--persistent", "--no-coldplug");
981 // FIXME: Don't remember exactly why I put "sleep" here -
982 // but it was not for a race with check_services()... - TB
983 sleep(1);
985 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
986 pid_hotplug2 = -2;
990 void stop_hotplug2(void)
992 pid_hotplug2 = -1;
993 killall_tk("hotplug2");
996 #endif /* LINUX26 */
997 // -----------------------------------------------------------------------------
999 // Written by Sparq in 2002/07/16
1000 void start_zebra(void)
1002 #ifdef TCONFIG_ZEBRA
1003 if (getpid() != 1) {
1004 start_service("zebra");
1005 return;
1008 FILE *fp;
1010 char *lan_tx = nvram_safe_get("dr_lan_tx");
1011 char *lan_rx = nvram_safe_get("dr_lan_rx");
1012 #ifdef TCONFIG_VLAN
1013 char *lan1_tx = nvram_safe_get("dr_lan1_tx");
1014 char *lan1_rx = nvram_safe_get("dr_lan1_rx");
1015 char *lan2_tx = nvram_safe_get("dr_lan2_tx");
1016 char *lan2_rx = nvram_safe_get("dr_lan2_rx");
1017 char *lan3_tx = nvram_safe_get("dr_lan3_tx");
1018 char *lan3_rx = nvram_safe_get("dr_lan3_rx");
1019 #endif
1020 char *wan_tx = nvram_safe_get("dr_wan_tx");
1021 char *wan_rx = nvram_safe_get("dr_wan_rx");
1023 #ifdef TCONFIG_VLAN
1024 if ((*lan_tx == '0') && (*lan_rx == '0') &&
1025 (*lan1_tx == '0') && (*lan1_rx == '0') &&
1026 (*lan2_tx == '0') && (*lan2_rx == '0') &&
1027 (*lan3_tx == '0') && (*lan3_rx == '0') &&
1028 (*wan_tx == '0') && (*wan_rx == '0')) {
1029 #else
1030 if ((*lan_tx == '0') && (*lan_rx == '0') && (*wan_tx == '0') && (*wan_rx == '0')) {
1031 #endif
1032 return;
1035 // empty
1036 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
1037 fclose(fp);
1041 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
1042 char *lan_ifname = nvram_safe_get("lan_ifname");
1043 #ifdef TCONFIG_VLAN
1044 char *lan1_ifname = nvram_safe_get("lan1_ifname");
1045 char *lan2_ifname = nvram_safe_get("lan2_ifname");
1046 char *lan3_ifname = nvram_safe_get("lan3_ifname");
1047 #endif
1048 char *wan_ifname = nvram_safe_get("wan_ifname");
1050 fprintf(fp, "router rip\n");
1051 if(strcmp(lan_ifname,"")!=0)
1052 fprintf(fp, "network %s\n", lan_ifname);
1053 #ifdef TCONFIG_VLAN
1054 if(strcmp(lan1_ifname,"")!=0)
1055 fprintf(fp, "network %s\n", lan1_ifname);
1056 if(strcmp(lan2_ifname,"")!=0)
1057 fprintf(fp, "network %s\n", lan2_ifname);
1058 if(strcmp(lan3_ifname,"")!=0)
1059 fprintf(fp, "network %s\n", lan3_ifname);
1060 #endif
1061 fprintf(fp, "network %s\n", wan_ifname);
1062 fprintf(fp, "redistribute connected\n");
1063 //fprintf(fp, "redistribute static\n");
1065 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
1066 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
1068 if(strcmp(lan_ifname,"")!=0) {
1069 fprintf(fp, "interface %s\n", lan_ifname);
1070 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
1071 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
1073 #ifdef TCONFIG_VLAN
1074 if(strcmp(lan1_ifname,"")!=0) {
1075 fprintf(fp, "interface %s\n", lan1_ifname);
1076 if (*lan1_tx != '0') fprintf(fp, "ip rip send version %s\n", lan1_tx);
1077 if (*lan1_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan1_rx);
1079 if(strcmp(lan2_ifname,"")!=0) {
1080 fprintf(fp, "interface %s\n", lan2_ifname);
1081 if (*lan2_tx != '0') fprintf(fp, "ip rip send version %s\n", lan2_tx);
1082 if (*lan2_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan2_rx);
1084 if(strcmp(lan3_ifname,"")!=0) {
1085 fprintf(fp, "interface %s\n", lan3_ifname);
1086 if (*lan3_tx != '0') fprintf(fp, "ip rip send version %s\n", lan3_tx);
1087 if (*lan3_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan3_rx);
1089 #endif
1090 fprintf(fp, "interface %s\n", wan_ifname);
1091 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
1092 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
1094 fprintf(fp, "router rip\n");
1095 if(strcmp(lan_ifname,"")!=0) {
1096 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
1097 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
1099 #ifdef TCONFIG_VLAN
1100 if(strcmp(lan1_ifname,"")!=0) {
1101 if (*lan1_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan1_ifname);
1102 if (*lan1_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan1_ifname);
1104 if(strcmp(lan2_ifname,"")!=0) {
1105 if (*lan2_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan2_ifname);
1106 if (*lan2_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan2_ifname);
1108 if(strcmp(lan3_ifname,"")!=0) {
1109 if (*lan3_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan3_ifname);
1110 if (*lan3_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan3_ifname);
1112 #endif
1113 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
1114 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
1115 fprintf(fp, "access-list private deny any\n");
1117 //fprintf(fp, "debug rip events\n");
1118 //fprintf(fp, "log file /etc/ripd.log\n");
1119 fclose(fp);
1122 xstart("zebra", "-d");
1123 xstart("ripd", "-d");
1124 #endif
1127 void stop_zebra(void)
1129 #ifdef TCONFIG_ZEBRA
1130 if (getpid() != 1) {
1131 stop_service("zebra");
1132 return;
1135 killall("zebra", SIGTERM);
1136 killall("ripd", SIGTERM);
1138 unlink("/etc/zebra.conf");
1139 unlink("/etc/ripd.conf");
1140 #endif
1143 // -----------------------------------------------------------------------------
1145 void start_syslog(void)
1147 char *argv[16];
1148 int argc;
1149 char *nv;
1150 char *b_opt = "";
1151 char rem[256];
1152 int n;
1153 char s[64];
1154 char cfg[256];
1155 char *rot_siz = "50";
1156 char *rot_keep = "1";
1157 char *log_file_path;
1159 argv[0] = "syslogd";
1160 argc = 1;
1162 if (nvram_match("log_remote", "1")) {
1163 nv = nvram_safe_get("log_remoteip");
1164 if (*nv) {
1165 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
1166 argv[argc++] = "-R";
1167 argv[argc++] = rem;
1171 if (nvram_match("log_file", "1")) {
1172 argv[argc++] = "-L";
1174 if (strcmp(nvram_safe_get("log_file_size"), "") != 0) {
1175 rot_siz = nvram_safe_get("log_file_size");
1177 if (nvram_get_int("log_file_size") > 0) {
1178 rot_keep = nvram_safe_get("log_file_keep");
1181 // log to custom path - shibby
1182 if (nvram_match("log_file_custom", "1")) {
1183 log_file_path = nvram_safe_get("log_file_path");
1184 argv[argc++] = "-s";
1185 argv[argc++] = rot_siz;
1186 argv[argc++] = "-O";
1187 argv[argc++] = log_file_path;
1188 if (strcmp(nvram_safe_get("log_file_path"), "/var/log/messages") != 0) {
1189 remove("/var/log/messages");
1190 symlink(log_file_path, "/var/log/messages");
1193 else
1195 /* Read options: rotate_size(kb) num_backups logfilename.
1196 * Ignore these settings and use defaults if the logfile cannot be written to.
1198 if (f_read_string("/etc/syslogd.cfg", cfg, sizeof(cfg)) > 0) {
1199 if ((nv = strchr(cfg, '\n')))
1200 *nv = 0;
1202 if ((nv = strtok(cfg, " \t"))) {
1203 if (isdigit(*nv))
1204 rot_siz = nv;
1207 if ((nv = strtok(NULL, " \t")))
1208 b_opt = nv;
1210 if ((nv = strtok(NULL, " \t")) && *nv == '/') {
1211 if (f_write(nv, cfg, 0, FW_APPEND, 0) >= 0) {
1212 argv[argc++] = "-O";
1213 argv[argc++] = nv;
1215 else {
1216 rot_siz = "50";
1217 b_opt = "";
1222 if (nvram_match("log_file_custom", "0")) {
1223 argv[argc++] = "-s";
1224 argv[argc++] = rot_siz;
1225 struct stat sb;
1226 if (lstat("/var/log/messages", &sb) != -1)
1227 if (S_ISLNK(sb.st_mode))
1228 remove("/var/log/messages");
1231 if (isdigit(*b_opt)) {
1232 argv[argc++] = "-b";
1233 argv[argc++] = b_opt;
1234 } else
1235 if (nvram_get_int("log_file_size") > 0) {
1236 argv[argc++] = "-b";
1237 argv[argc++] = rot_keep;
1241 if (argc > 1) {
1242 argv[argc] = NULL;
1243 _eval(argv, NULL, 0, NULL);
1245 argv[0] = "klogd";
1246 argv[1] = NULL;
1247 _eval(argv, NULL, 0, NULL);
1249 // used to be available in syslogd -m
1250 n = nvram_get_int("log_mark");
1251 if (n > 0) {
1252 // n is in minutes
1253 if (n < 60)
1254 sprintf(rem, "*/%d * * * *", n);
1255 else if (n < 60 * 24)
1256 sprintf(rem, "0 */%d * * *", n / 60);
1257 else
1258 sprintf(rem, "0 0 */%d * *", n / (60 * 24));
1259 sprintf(s, "%s logger -p syslog.info -- -- MARK --", rem);
1260 eval("cru", "a", "syslogdmark", s);
1262 else {
1263 eval("cru", "d", "syslogdmark");
1268 void stop_syslog(void)
1270 killall("klogd", SIGTERM);
1271 killall("syslogd", SIGTERM);
1274 // -----------------------------------------------------------------------------
1276 static pid_t pid_igmp = -1;
1278 void start_igmp_proxy(void)
1280 FILE *fp;
1282 pid_igmp = -1;
1283 if (nvram_match("multicast_pass", "1")) {
1284 if (get_wan_proto() == WP_DISABLED)
1285 return;
1287 if (f_exists("/etc/igmp.alt")) {
1288 eval("igmpproxy", "/etc/igmp.alt");
1290 else if ((fp = fopen("/etc/igmp.conf", "w")) != NULL) {
1291 fprintf(fp,
1292 "quickleave\n"
1293 "phyint %s upstream\n"
1294 "\taltnet %s\n",
1295 nvram_safe_get("wan_ifname"),
1296 nvram_get("multicast_altnet") ? : "0.0.0.0/0");
1297 // nvram_safe_get("lan_ifname"));
1299 #ifdef TCONFIG_VLAN
1300 char lanN_ifname[] = "lanXX_ifname";
1301 char multicast_lanN[] = "multicast_lanXX";
1302 char br;
1304 for(br=0 ; br<4 ; br++) {
1305 char bridge[2] = "0";
1306 if (br!=0)
1307 bridge[0]+=br;
1308 else
1309 strcpy(bridge, "");
1311 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1312 sprintf(multicast_lanN, "multicast_lan%s", bridge);
1314 if((strcmp(nvram_safe_get(multicast_lanN),"1")==0) && (strcmp(nvram_safe_get(lanN_ifname),"")!=0)) {
1315 fprintf(fp,
1316 "phyint %s downstream ratelimit 0\n",
1317 nvram_safe_get(lanN_ifname));
1320 #else
1321 fprintf(fp,
1322 "phyint %s downstream ratelimit 0\n",
1323 nvram_safe_get("lan_ifname"));
1324 #endif
1325 fclose(fp);
1326 eval("igmpproxy", "/etc/igmp.conf");
1328 else {
1329 return;
1331 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1332 pid_igmp = -2;
1337 void stop_igmp_proxy(void)
1339 pid_igmp = -1;
1340 killall_tk("igmpproxy");
1343 // -----------------------------------------------------------------------------
1345 void start_udpxy(void)
1347 if (nvram_match("udpxy_enable", "1")) {
1348 if (get_wan_proto() == WP_DISABLED)
1349 return;
1350 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") );
1354 void stop_udpxy(void)
1356 killall_tk("udpxy");
1359 // -----------------------------------------------------------------------------
1361 #ifdef TCONFIG_NOCAT
1363 static pid_t pid_splashd = -1;
1364 void start_splashd(void)
1366 pid_splashd = -1;
1367 start_nocat();
1368 if (!nvram_contains_word("debug_norestart", "splashd")) {
1369 pid_splashd = -2;
1373 void stop_splashd(void)
1375 pid_splashd = -1;
1376 stop_nocat();
1377 start_wan(BOOT);
1379 #endif
1381 // -----------------------------------------------------------------------------
1382 #ifdef TCONFIG_NGINX
1384 static pid_t pid_nginx = -1;
1385 void start_enginex(void)
1387 pid_nginx =-1;
1388 start_nginx();
1389 if (!nvram_contains_word("debug_norestart","enginex")) {
1390 pid_nginx = -2;
1394 void stop_enginex(void)
1396 pid_nginx = -1;
1397 stop_nginx();
1400 void start_nginxfastpath(void)
1402 pid_nginx =-1;
1403 start_nginxfp();
1404 if (!nvram_contains_word("debug_norestart","nginxfp")) {
1405 pid_nginx = -2;
1408 void stop_nginxfastpath(void)
1410 pid_nginx = -1;
1411 stop_nginxfp();
1414 #endif
1415 // -----------------------------------------------------------------------------
1416 void set_tz(void)
1418 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
1421 void start_ntpc(void)
1423 set_tz();
1425 stop_ntpc();
1427 if (nvram_get_int("ntp_updates") >= 0) {
1428 xstart("ntpsync", "--init");
1432 void stop_ntpc(void)
1434 killall("ntpsync", SIGTERM);
1437 // -----------------------------------------------------------------------------
1439 static void stop_rstats(void)
1441 int n, m;
1442 int pid;
1443 int pidz;
1444 int ppidz;
1445 int w = 0;
1447 n = 60;
1448 m = 15;
1449 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
1450 w = 1;
1451 pidz = pidof("gzip");
1452 if (pidz < 1) pidz = pidof("cp");
1453 ppidz = ppid(ppid(pidz));
1454 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1455 syslog(LOG_DEBUG, "rstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1456 --m;
1457 } else {
1458 kill(pid, SIGTERM);
1460 sleep(1);
1462 if ((w == 1) && (n > 0))
1463 syslog(LOG_DEBUG, "rstats stopped.\n");
1466 static void start_rstats(int new)
1468 if (nvram_match("rstats_enable", "1")) {
1469 stop_rstats();
1470 if (new) {
1471 syslog(LOG_DEBUG, "starting rstats (new datafile).\n");
1472 xstart("rstats", "--new");
1473 } else {
1474 syslog(LOG_DEBUG, "starting rstats.\n");
1475 xstart("rstats");
1480 static void stop_cstats(void)
1482 int n, m;
1483 int pid;
1484 int pidz;
1485 int ppidz;
1486 int w = 0;
1488 n = 60;
1489 m = 15;
1490 while ((n-- > 0) && ((pid = pidof("cstats")) > 0)) {
1491 w = 1;
1492 pidz = pidof("gzip");
1493 if (pidz < 1) pidz = pidof("cp");
1494 ppidz = ppid(ppid(pidz));
1495 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1496 syslog(LOG_DEBUG, "cstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1497 --m;
1498 } else {
1499 kill(pid, SIGTERM);
1501 sleep(1);
1503 if ((w == 1) && (n > 0))
1504 syslog(LOG_DEBUG, "cstats stopped.\n");
1507 static void start_cstats(int new)
1509 if (nvram_match("cstats_enable", "1")) {
1510 stop_cstats();
1511 if (new) {
1512 syslog(LOG_DEBUG, "starting cstats (new datafile).\n");
1513 xstart("cstats", "--new");
1514 } else {
1515 syslog(LOG_DEBUG, "starting cstats.\n");
1516 xstart("cstats");
1521 // -----------------------------------------------------------------------------
1523 // !!TB - FTP Server
1525 #ifdef TCONFIG_FTP
1526 static char *get_full_storage_path(char *val)
1528 static char buf[128];
1529 int len;
1531 if (val[0] == '/')
1532 len = sprintf(buf, "%s", val);
1533 else
1534 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
1536 if (len > 1 && buf[len - 1] == '/')
1537 buf[len - 1] = 0;
1539 return buf;
1542 static char *nvram_storage_path(char *var)
1544 char *val = nvram_safe_get(var);
1545 return get_full_storage_path(val);
1548 char vsftpd_conf[] = "/etc/vsftpd.conf";
1549 char vsftpd_users[] = "/etc/vsftpd.users";
1550 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
1552 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1554 static void start_ftpd(void)
1556 char tmp[256];
1557 FILE *fp, *f;
1558 char *buf;
1559 char *p, *q;
1560 char *user, *pass, *rights, *root_dir;
1561 int i;
1563 if (getpid() != 1) {
1564 start_service("ftpd");
1565 return;
1568 if (!nvram_get_int("ftp_enable")) return;
1570 mkdir_if_none(vsftpd_users);
1571 mkdir_if_none("/var/run/vsftpd");
1573 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
1574 return;
1576 if (nvram_get_int("ftp_super"))
1578 /* rights */
1579 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
1580 if ((f = fopen(tmp, "w")))
1582 fprintf(f,
1583 "dirlist_enable=yes\n"
1584 "write_enable=yes\n"
1585 "download_enable=yes\n");
1586 fclose(f);
1590 #ifdef TCONFIG_SAMBASRV
1591 if (nvram_match("smbd_cset", "utf8"))
1592 fprintf(fp, "utf8=yes\n");
1593 #endif
1595 if (nvram_invmatch("ftp_anonymous", "0"))
1597 fprintf(fp,
1598 "anon_allow_writable_root=yes\n"
1599 "anon_world_readable_only=no\n"
1600 "anon_umask=022\n");
1602 /* rights */
1603 sprintf(tmp, "%s/ftp", vsftpd_users);
1604 if ((f = fopen(tmp, "w")))
1606 if (nvram_match("ftp_dirlist", "0"))
1607 fprintf(f, "dirlist_enable=yes\n");
1608 if (nvram_match("ftp_anonymous", "1") ||
1609 nvram_match("ftp_anonymous", "3"))
1610 fprintf(f, "write_enable=yes\n");
1611 if (nvram_match("ftp_anonymous", "1") ||
1612 nvram_match("ftp_anonymous", "2"))
1613 fprintf(f, "download_enable=yes\n");
1614 fclose(f);
1616 if (nvram_match("ftp_anonymous", "1") ||
1617 nvram_match("ftp_anonymous", "3"))
1618 fprintf(fp,
1619 "anon_upload_enable=yes\n"
1620 "anon_mkdir_write_enable=yes\n"
1621 "anon_other_write_enable=yes\n");
1622 } else {
1623 fprintf(fp, "anonymous_enable=no\n");
1626 fprintf(fp,
1627 "dirmessage_enable=yes\n"
1628 "download_enable=no\n"
1629 "dirlist_enable=no\n"
1630 "hide_ids=yes\n"
1631 "syslog_enable=yes\n"
1632 "local_enable=yes\n"
1633 "local_umask=022\n"
1634 "chmod_enable=no\n"
1635 "chroot_local_user=yes\n"
1636 "check_shell=no\n"
1637 "log_ftp_protocol=%s\n"
1638 "user_config_dir=%s\n"
1639 "passwd_file=%s\n"
1640 "listen%s=yes\n"
1641 "listen_port=%s\n"
1642 "background=yes\n"
1643 "isolate=no\n"
1644 "max_clients=%d\n"
1645 "max_per_ip=%d\n"
1646 "max_login_fails=1\n"
1647 "idle_session_timeout=%s\n"
1648 "use_sendfile=no\n"
1649 "anon_max_rate=%d\n"
1650 "local_max_rate=%d\n"
1651 "%s\n",
1652 nvram_get_int("log_ftp") ? "yes" : "no",
1653 vsftpd_users, vsftpd_passwd,
1654 #ifdef TCONFIG_IPV6
1655 ipv6_enabled() ? "_ipv6" : "",
1656 #else
1658 #endif
1659 nvram_get("ftp_port") ? : "21",
1660 nvram_get_int("ftp_max"),
1661 nvram_get_int("ftp_ipmax"),
1662 nvram_get("ftp_staytimeout") ? : "300",
1663 nvram_get_int("ftp_anonrate") * 1024,
1664 nvram_get_int("ftp_rate") * 1024,
1665 nvram_safe_get("ftp_custom"));
1667 fclose(fp);
1669 /* prepare passwd file and default users */
1670 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
1671 return;
1673 if (((user = nvram_get("http_username")) == NULL) || (*user == 0)) user = "admin";
1674 if (((pass = nvram_get("http_passwd")) == NULL) || (*pass == 0)) pass = "admin";
1676 fprintf(fp, /* anonymous, admin, nobody */
1677 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1678 "%s:%s:0:0:root:/:/sbin/nologin\n"
1679 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1680 nvram_storage_path("ftp_anonroot"), user,
1681 nvram_get_int("ftp_super") ? crypt(pass, "$1$") : "x",
1682 MOUNT_ROOT);
1684 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
1687 username<password<rights[<root_dir>]
1688 rights:
1689 Read/Write
1690 Read Only
1691 View Only
1692 Private
1694 p = buf;
1695 while ((q = strsep(&p, ">")) != NULL) {
1696 i = vstrsep(q, "<", &user, &pass, &rights, &root_dir);
1697 if (i < 3 || i > 4) continue;
1698 if (!user || !pass) continue;
1700 if (i == 3 || !root_dir || !(*root_dir))
1702 root_dir = nvram_safe_get("ftp_pubroot");
1704 /* directory */
1705 if (strncmp(rights, "Private", 7) == 0)
1707 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
1708 mkdir_if_none(tmp);
1710 else
1711 sprintf(tmp, "%s", get_full_storage_path(root_dir));
1713 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1714 user, crypt(pass, "$1$"), user, tmp);
1716 /* rights */
1717 sprintf(tmp, "%s/%s", vsftpd_users, user);
1718 if ((f = fopen(tmp, "w")))
1720 tmp[0] = 0;
1721 if (nvram_invmatch("ftp_dirlist", "1"))
1722 strcat(tmp, "dirlist_enable=yes\n");
1723 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
1724 strcat(tmp, "download_enable=yes\n");
1725 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
1726 strcat(tmp, "write_enable=yes\n");
1728 fputs(tmp, f);
1729 fclose(f);
1732 free(buf);
1735 fclose(fp);
1736 killall("vsftpd", SIGHUP);
1738 /* start vsftpd if it's not already running */
1739 if (pidof("vsftpd") <= 0)
1740 xstart("vsftpd");
1743 static void stop_ftpd(void)
1745 if (getpid() != 1) {
1746 stop_service("ftpd");
1747 return;
1750 killall_tk("vsftpd");
1751 unlink(vsftpd_passwd);
1752 unlink(vsftpd_conf);
1753 eval("rm", "-rf", vsftpd_users);
1755 #endif // TCONFIG_FTP
1757 // -----------------------------------------------------------------------------
1759 // !!TB - Samba
1761 #ifdef TCONFIG_SAMBASRV
1762 static void kill_samba(int sig)
1764 if (sig == SIGTERM) {
1765 killall_tk("smbd");
1766 killall_tk("nmbd");
1768 else {
1769 killall("smbd", sig);
1770 killall("nmbd", sig);
1774 static void start_samba(void)
1776 FILE *fp;
1777 DIR *dir = NULL;
1778 struct dirent *dp;
1779 char nlsmod[15];
1780 int mode;
1781 char *nv;
1783 if (getpid() != 1) {
1784 start_service("smbd");
1785 return;
1788 mode = nvram_get_int("smbd_enable");
1789 if (!mode || !nvram_invmatch("lan_hostname", ""))
1790 return;
1792 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
1793 return;
1795 fprintf(fp, "[global]\n"
1796 " interfaces = %s\n"
1797 " bind interfaces only = yes\n"
1798 " workgroup = %s\n"
1799 " netbios name = %s\n"
1800 " server string = %s\n"
1801 " guest account = nobody\n"
1802 " security = user\n"
1803 " %s\n"
1804 " guest ok = %s\n"
1805 " guest only = no\n"
1806 " browseable = yes\n"
1807 " syslog only = yes\n"
1808 " timestamp logs = no\n"
1809 " syslog = 1\n"
1810 " encrypt passwords = yes\n"
1811 " preserve case = yes\n"
1812 " short preserve case = yes\n",
1813 nvram_safe_get("lan_ifname"),
1814 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1815 nvram_safe_get("lan_hostname"),
1816 nvram_get("router_name") ? : "Tomato",
1817 mode == 2 ? "" : "map to guest = Bad User",
1818 mode == 2 ? "no" : "yes" // guest ok
1821 if (nvram_get_int("smbd_wins")) {
1822 nv = nvram_safe_get("wan_wins");
1823 if ((*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
1824 fprintf(fp, " wins support = yes\n");
1828 if (nvram_get_int("smbd_master")) {
1829 fprintf(fp,
1830 " domain master = yes\n"
1831 " local master = yes\n"
1832 " preferred master = yes\n"
1833 " os level = 65\n");
1836 nv = nvram_safe_get("smbd_cpage");
1837 if (*nv) {
1838 #ifndef TCONFIG_SAMBA3
1839 fprintf(fp, " client code page = %s\n", nv);
1840 #endif
1841 sprintf(nlsmod, "nls_cp%s", nv);
1843 nv = nvram_safe_get("smbd_nlsmod");
1844 if ((*nv) && (strcmp(nv, nlsmod) != 0))
1845 modprobe_r(nv);
1847 modprobe(nlsmod);
1848 nvram_set("smbd_nlsmod", nlsmod);
1851 #ifndef TCONFIG_SAMBA3
1852 if (nvram_match("smbd_cset", "utf8"))
1853 fprintf(fp, " coding system = utf8\n");
1854 else if (nvram_invmatch("smbd_cset", ""))
1855 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1856 #endif
1858 nv = nvram_safe_get("smbd_custom");
1859 /* add socket options unless overriden by the user */
1860 if (strstr(nv, "socket options") == NULL) {
1861 fprintf(fp, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1863 fprintf(fp, "%s\n\n", nv);
1865 /* configure shares */
1867 char *buf;
1868 char *p, *q;
1869 char *name, *path, *comment, *writeable, *hidden;
1870 int cnt = 0;
1872 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1874 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1876 p = buf;
1877 while ((q = strsep(&p, ">")) != NULL) {
1878 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1879 if (!path || !name) continue;
1881 /* share name */
1882 fprintf(fp, "\n[%s]\n", name);
1884 /* path */
1885 fprintf(fp, " path = %s\n", path);
1887 /* access level */
1888 if (!strcmp(writeable, "1"))
1889 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1890 if (!strcmp(hidden, "1"))
1891 fprintf(fp, " browseable = no\n");
1893 /* comment */
1894 if (comment)
1895 fprintf(fp, " comment = %s\n", comment);
1897 cnt++;
1899 free(buf);
1902 /* Share every mountpoint below MOUNT_ROOT */
1903 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1904 while ((dp = readdir(dir))) {
1905 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1907 /* Only if is a directory and is mounted */
1908 if (!dir_is_mountpoint(MOUNT_ROOT, dp->d_name))
1909 continue;
1911 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1912 fprintf(fp, "\n[%s]\n path = %s/%s\n comment = %s\n",
1913 dp->d_name, MOUNT_ROOT, dp->d_name, dp->d_name);
1914 if (nvram_match("smbd_autoshare", "3")) // Hidden
1915 fprintf(fp, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1916 dp->d_name, MOUNT_ROOT, dp->d_name);
1917 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1918 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1920 cnt++;
1924 if (dir) closedir(dir);
1926 if (cnt == 0) {
1927 /* by default share MOUNT_ROOT as read-only */
1928 fprintf(fp, "\n[share]\n"
1929 " path = %s\n"
1930 " writable = no\n",
1931 MOUNT_ROOT);
1934 fclose(fp);
1936 mkdir_if_none("/var/run/samba");
1937 mkdir_if_none("/etc/samba");
1939 /* write smbpasswd */
1940 #ifdef TCONFIG_SAMBA3
1941 eval("smbpasswd", "nobody", "\"\"");
1942 #else
1943 eval("smbpasswd", "-a", "nobody", "\"\"");
1944 #endif
1945 if (mode == 2) {
1946 char *smbd_user;
1947 if (((smbd_user = nvram_get("smbd_user")) == NULL) || (*smbd_user == 0) || !strcmp(smbd_user, "root"))
1948 smbd_user = "nas";
1949 #ifdef TCONFIG_SAMBA3
1950 eval("smbpasswd", smbd_user, nvram_safe_get("smbd_passwd"));
1951 #else
1952 eval("smbpasswd", "-a", smbd_user, nvram_safe_get("smbd_passwd"));
1953 #endif
1956 kill_samba(SIGHUP);
1957 int ret1 = 0, ret2 = 0;
1958 /* start samba if it's not already running */
1959 if (pidof("nmbd") <= 0)
1960 ret1 = xstart("nmbd", "-D");
1961 if (pidof("smbd") <= 0)
1962 ret2 = xstart("smbd", "-D");
1964 if (ret1 || ret2) kill_samba(SIGTERM);
1967 static void stop_samba(void)
1969 if (getpid() != 1) {
1970 stop_service("smbd");
1971 return;
1974 kill_samba(SIGTERM);
1975 /* clean up */
1976 unlink("/var/log/smb");
1977 unlink("/var/log/nmb");
1978 eval("rm", "-rf", "/var/run/samba");
1980 #endif // TCONFIG_SAMBASRV
1982 #ifdef TCONFIG_MEDIA_SERVER
1983 #define MEDIA_SERVER_APP "minidlna"
1985 static void start_media_server(void)
1987 FILE *f;
1988 int port, pid, https;
1989 char *dbdir;
1990 char *argv[] = { MEDIA_SERVER_APP, "-f", "/etc/"MEDIA_SERVER_APP".conf", "-R", NULL };
1991 static int once = 1;
1993 if (getpid() != 1) {
1994 start_service("media");
1995 return;
1998 if (nvram_get_int("ms_sas") == 0)
1999 once = 0;
2001 if (nvram_get_int("ms_enable") != 0) {
2002 if ((!once) && (nvram_get_int("ms_rescan") == 0)) {
2003 // no forced rescan
2004 argv[3] = NULL;
2006 nvram_unset("ms_rescan");
2008 if (f_exists("/etc/"MEDIA_SERVER_APP".alt")) {
2009 argv[2] = "/etc/"MEDIA_SERVER_APP".alt";
2011 else {
2012 if ((f = fopen(argv[2], "w")) != NULL) {
2013 port = nvram_get_int("ms_port");
2014 https = nvram_get_int("https_enable");
2015 dbdir = nvram_safe_get("ms_dbdir");
2016 if (!(*dbdir)) dbdir = NULL;
2017 mkdir_if_none(dbdir ? : "/var/run/"MEDIA_SERVER_APP);
2019 fprintf(f,
2020 "network_interface=%s\n"
2021 "port=%d\n"
2022 "friendly_name=%s\n"
2023 "db_dir=%s/.db\n"
2024 "enable_tivo=%s\n"
2025 "strict_dlna=%s\n"
2026 "presentation_url=http%s://%s:%s/nas-media.asp\n"
2027 "inotify=yes\n"
2028 "notify_interval=600\n"
2029 "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"
2030 "\n",
2031 nvram_safe_get("lan_ifname"),
2032 (port < 0) || (port >= 0xffff) ? 0 : port,
2033 nvram_get("router_name") ? : "Tomato",
2034 dbdir ? : "/var/run/"MEDIA_SERVER_APP,
2035 nvram_get_int("ms_tivo") ? "yes" : "no",
2036 nvram_get_int("ms_stdlna") ? "yes" : "no",
2037 https ? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https ? "https_lanport" : "http_lanport")
2040 // media directories
2041 char *buf, *p, *q;
2042 char *path, *restrict;
2044 if ((buf = strdup(nvram_safe_get("ms_dirs"))) != NULL) {
2045 /* path<restrict[A|V|P|] */
2047 p = buf;
2048 while ((q = strsep(&p, ">")) != NULL) {
2049 if (vstrsep(q, "<", &path, &restrict) < 1 || !path || !(*path))
2050 continue;
2051 fprintf(f, "media_dir=%s%s%s\n",
2052 restrict ? : "", (restrict && *restrict) ? "," : "", path);
2054 free(buf);
2057 fclose(f);
2061 /* start media server if it's not already running */
2062 if (pidof(MEDIA_SERVER_APP) <= 0) {
2063 if ((_eval(argv, NULL, 0, &pid) == 0) && (once)) {
2064 /* If we started the media server successfully, wait 1 sec
2065 * to let it die if it can't open the database file.
2066 * If it's still alive after that, assume it's running and
2067 * disable forced once-after-reboot rescan.
2069 sleep(1);
2070 if (pidof(MEDIA_SERVER_APP) > 0)
2071 once = 0;
2077 static void stop_media_server(void)
2079 if (getpid() != 1) {
2080 stop_service("media");
2081 return;
2084 killall_tk(MEDIA_SERVER_APP);
2086 #endif // TCONFIG_MEDIA_SERVER
2088 #ifdef TCONFIG_USB
2089 static void start_nas_services(void)
2091 if (getpid() != 1) {
2092 start_service("usbapps");
2093 return;
2096 #ifdef TCONFIG_SAMBASRV
2097 start_samba();
2098 #endif
2099 #ifdef TCONFIG_FTP
2100 start_ftpd();
2101 #endif
2102 #ifdef TCONFIG_MEDIA_SERVER
2103 start_media_server();
2104 #endif
2107 static void stop_nas_services(void)
2109 if (getpid() != 1) {
2110 stop_service("usbapps");
2111 return;
2114 #ifdef TCONFIG_MEDIA_SERVER
2115 stop_media_server();
2116 #endif
2117 #ifdef TCONFIG_FTP
2118 stop_ftpd();
2119 #endif
2120 #ifdef TCONFIG_SAMBASRV
2121 stop_samba();
2122 #endif
2125 void restart_nas_services(int stop, int start)
2127 int fd = file_lock("usb");
2128 /* restart all NAS applications */
2129 if (stop)
2130 stop_nas_services();
2131 if (start)
2132 start_nas_services();
2133 file_unlock(fd);
2135 #endif // TCONFIG_USB
2137 // -----------------------------------------------------------------------------
2139 /* -1 = Don't check for this program, it is not expected to be running.
2140 * Other = This program has been started and should be kept running. If no
2141 * process with the name is running, call func to restart it.
2142 * Note: At startup, dnsmasq forks a short-lived child which forks a
2143 * long-lived (grand)child. The parents terminate.
2144 * Many daemons use this technique.
2146 static void _check(pid_t pid, const char *name, void (*func)(void))
2148 if (pid == -1) return;
2150 if (pidof(name) > 0) return;
2152 syslog(LOG_DEBUG, "%s terminated unexpectedly, restarting.\n", name);
2153 func();
2155 // Force recheck in 500 msec
2156 setitimer(ITIMER_REAL, &pop_tv, NULL);
2159 void check_services(void)
2161 TRACE_PT("keep alive\n");
2163 // Periodically reap any zombies
2164 setitimer(ITIMER_REAL, &zombie_tv, NULL);
2166 #ifdef LINUX26
2167 _check(pid_hotplug2, "hotplug2", start_hotplug2);
2168 #endif
2169 _check(pid_dnsmasq, "dnsmasq", start_dnsmasq);
2170 _check(pid_crond, "crond", start_cron);
2171 _check(pid_igmp, "igmpproxy", start_igmp_proxy);
2174 // -----------------------------------------------------------------------------
2176 void start_services(void)
2178 static int once = 1;
2180 if (once) {
2181 once = 0;
2183 if (nvram_get_int("telnetd_eas")) start_telnetd();
2184 if (nvram_get_int("sshd_eas")) start_sshd();
2187 // start_syslog();
2188 start_nas();
2189 start_zebra();
2190 start_dnsmasq();
2191 start_cifs();
2192 start_httpd();
2193 #ifdef TCONFIG_NGINX
2194 start_enginex();
2195 #endif
2196 start_cron();
2197 // start_upnp();
2198 start_rstats(0);
2199 start_cstats(0);
2200 start_sched();
2201 #ifdef TCONFIG_PPTPD
2202 start_pptpd();
2203 #endif
2204 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
2206 #ifdef TCONFIG_SNMP
2207 start_snmp();
2208 #endif
2210 #ifdef TCONFIG_NOCAT
2211 start_splashd();
2212 #endif
2216 void stop_services(void)
2218 clear_resolv();
2220 #ifdef TCONFIG_NOCAT
2221 stop_splashd();
2222 #endif
2224 #ifdef TCONFIG_SNMP
2225 stop_snmp();
2226 #endif
2228 #ifdef TCONFIG_NFS
2229 stop_nfs();
2230 #endif
2231 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2232 #ifdef TCONFIG_PPTPD
2233 stop_pptpd();
2234 #endif
2235 stop_sched();
2236 stop_rstats();
2237 stop_cstats();
2238 // stop_upnp();
2239 stop_cron();
2240 stop_httpd();
2241 #ifdef TCONFIG_NGINX
2242 stop_enginex();
2243 #endif
2244 stop_cifs();
2245 stop_dnsmasq();
2246 stop_zebra();
2247 stop_nas();
2248 // stop_syslog();
2251 // -----------------------------------------------------------------------------
2253 /* nvram "action_service" is: "service-action[-modifier]"
2254 * action is something like "stop" or "start" or "restart"
2255 * optional modifier is "c" for the "service" command-line command
2257 void exec_service(void)
2259 const int A_START = 1;
2260 const int A_STOP = 2;
2261 const int A_RESTART = 1|2;
2262 char buffer[128];
2263 char *service;
2264 char *act;
2265 char *next;
2266 char *modifier;
2267 int action, user;
2268 int i;
2270 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
2271 next = buffer;
2273 TOP:
2274 act = strsep(&next, ",");
2275 service = strsep(&act, "-");
2276 if (act == NULL) {
2277 next = NULL;
2278 goto CLEAR;
2280 modifier = act;
2281 strsep(&modifier, "-");
2283 TRACE_PT("service=%s action=%s modifier=%s\n", service, act, modifier ? : "");
2285 if (strcmp(act, "start") == 0) action = A_START;
2286 else if (strcmp(act, "stop") == 0) action = A_STOP;
2287 else if (strcmp(act, "restart") == 0) action = A_RESTART;
2288 else action = 0;
2289 user = (modifier != NULL && *modifier == 'c');
2291 if (strcmp(service, "dhcpc") == 0) {
2292 if (action & A_STOP) stop_dhcpc();
2293 if (action & A_START) start_dhcpc();
2294 goto CLEAR;
2297 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
2298 if (action & A_STOP) stop_dnsmasq();
2299 if (action & A_START) {
2300 dns_to_resolv();
2301 start_dnsmasq();
2303 goto CLEAR;
2306 if (strcmp(service, "firewall") == 0) {
2307 if (action & A_STOP) {
2308 stop_firewall();
2309 stop_igmp_proxy();
2310 stop_udpxy();
2312 if (action & A_START) {
2313 start_firewall();
2314 start_igmp_proxy();
2315 start_udpxy();
2317 goto CLEAR;
2320 if (strcmp(service, "restrict") == 0) {
2321 if (action & A_STOP) {
2322 stop_firewall();
2324 if (action & A_START) {
2325 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
2327 start_firewall();
2329 // if radio was disabled by access restriction, but no rule is handling it now, enable it
2330 if (i == 1) {
2331 if (nvram_get_int("rrules_radio") < 0) {
2332 eval("radio", "on");
2336 goto CLEAR;
2339 if (strcmp(service, "arpbind") == 0) {
2340 if (action & A_STOP) stop_arpbind();
2341 if (action & A_START) start_arpbind();
2342 goto CLEAR;
2345 if (strcmp(service, "qos") == 0) {
2346 if (action & A_STOP) {
2347 stop_qos();
2349 stop_firewall(); start_firewall(); // always restarted
2350 if (action & A_START) {
2351 start_qos();
2352 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
2354 goto CLEAR;
2357 if (strcmp(service, "qoslimit") == 0) {
2358 if (action & A_STOP) {
2359 stop_qoslimit();
2361 #ifdef TCONFIG_NOCAT
2362 stop_splashd();
2363 #endif
2364 stop_firewall(); start_firewall(); // always restarted
2365 if (action & A_START) {
2366 start_qoslimit();
2368 #ifdef TCONFIG_NOCAT
2369 start_splashd();
2370 #endif
2371 goto CLEAR;
2374 if (strcmp(service, "upnp") == 0) {
2375 if (action & A_STOP) {
2376 stop_upnp();
2378 stop_firewall(); start_firewall(); // always restarted
2379 if (action & A_START) {
2380 start_upnp();
2382 goto CLEAR;
2385 if (strcmp(service, "telnetd") == 0) {
2386 if (action & A_STOP) stop_telnetd();
2387 if (action & A_START) start_telnetd();
2388 goto CLEAR;
2391 if (strcmp(service, "sshd") == 0) {
2392 if (action & A_STOP) stop_sshd();
2393 if (action & A_START) start_sshd();
2394 goto CLEAR;
2397 if (strcmp(service, "httpd") == 0) {
2398 if (action & A_STOP) stop_httpd();
2399 if (action & A_START) start_httpd();
2400 goto CLEAR;
2403 #ifdef TCONFIG_NGINX
2404 if (strcmp(service, "enginex") == 0) {
2405 if (action & A_STOP) stop_enginex();
2406 if (action & A_START) start_enginex();
2407 goto CLEAR;
2409 if (strcmp(service, "nginxfp") == 0) {
2410 if (action & A_STOP) stop_nginxfastpath();
2411 if (action & A_START) start_nginxfastpath();
2412 goto CLEAR;
2414 #endif
2416 #ifdef TCONFIG_IPV6
2417 if (strcmp(service, "ipv6") == 0) {
2418 if (action & A_STOP) {
2419 stop_dnsmasq();
2420 stop_ipv6();
2422 if (action & A_START) {
2423 start_ipv6();
2424 start_dnsmasq();
2426 goto CLEAR;
2429 if (strncmp(service, "dhcp6", 5) == 0) {
2430 if (action & A_STOP) {
2431 stop_dhcp6c();
2433 if (action & A_START) {
2434 start_dhcp6c();
2436 goto CLEAR;
2438 #endif
2440 if (strcmp(service, "admin") == 0) {
2441 if (action & A_STOP) {
2442 stop_sshd();
2443 stop_telnetd();
2444 stop_httpd();
2446 stop_firewall(); start_firewall(); // always restarted
2447 if (action & A_START) {
2448 start_httpd();
2449 create_passwd();
2450 if (nvram_match("telnetd_eas", "1")) start_telnetd();
2451 if (nvram_match("sshd_eas", "1")) start_sshd();
2453 goto CLEAR;
2456 if (strcmp(service, "ddns") == 0) {
2457 if (action & A_STOP) stop_ddns();
2458 if (action & A_START) start_ddns();
2459 goto CLEAR;
2462 if (strcmp(service, "ntpc") == 0) {
2463 if (action & A_STOP) stop_ntpc();
2464 if (action & A_START) start_ntpc();
2465 goto CLEAR;
2468 if (strcmp(service, "logging") == 0) {
2469 if (action & A_STOP) {
2470 stop_syslog();
2472 if (action & A_START) {
2473 start_syslog();
2475 if (!user) {
2476 // always restarted except from "service" command
2477 stop_cron(); start_cron();
2478 stop_firewall(); start_firewall();
2480 goto CLEAR;
2483 if (strcmp(service, "crond") == 0) {
2484 if (action & A_STOP) {
2485 stop_cron();
2487 if (action & A_START) {
2488 start_cron();
2490 goto CLEAR;
2493 #ifdef LINUX26
2494 if (strncmp(service, "hotplug", 7) == 0) {
2495 if (action & A_STOP) {
2496 stop_hotplug2();
2498 if (action & A_START) {
2499 start_hotplug2(1);
2501 goto CLEAR;
2503 #endif
2505 if (strcmp(service, "upgrade") == 0) {
2506 if (action & A_START) {
2507 #if TOMATO_SL
2508 stop_usbevent();
2509 stop_smbd();
2510 #endif
2511 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2512 stop_jffs2();
2513 // stop_cifs();
2514 #ifdef TCONFIG_NGINX
2515 stop_enginex();
2516 #endif
2517 stop_zebra();
2518 stop_cron();
2519 stop_ntpc();
2520 stop_upnp();
2521 // stop_dhcpc();
2522 killall("rstats", SIGTERM);
2523 killall("cstats", SIGTERM);
2524 killall("buttons", SIGTERM);
2525 stop_syslog();
2526 remove_storage_main(1); // !!TB - USB Support
2527 stop_usb(); // !!TB - USB Support
2529 goto CLEAR;
2532 #ifdef TCONFIG_CIFS
2533 if (strcmp(service, "cifs") == 0) {
2534 if (action & A_STOP) stop_cifs();
2535 if (action & A_START) start_cifs();
2536 goto CLEAR;
2538 #endif
2540 #ifdef TCONFIG_JFFS2
2541 if (strncmp(service, "jffs", 4) == 0) {
2542 if (action & A_STOP) stop_jffs2();
2543 if (action & A_START) start_jffs2();
2544 goto CLEAR;
2546 #endif
2548 if (strcmp(service, "zebra") == 0) {
2549 if (action & A_STOP) stop_zebra();
2550 if (action & A_START) start_zebra();
2551 goto CLEAR;
2554 if (strcmp(service, "routing") == 0) {
2555 if (action & A_STOP) {
2556 stop_zebra();
2557 do_static_routes(0); // remove old '_saved'
2558 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2559 #ifdef TCONFIG_VLAN
2560 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2561 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), "0");
2562 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2563 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), "0");
2564 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2565 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), "0");
2566 #endif
2568 stop_firewall();
2569 start_firewall();
2570 if (action & A_START) {
2571 do_static_routes(1); // add new
2572 start_zebra();
2573 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2574 #ifdef TCONFIG_VLAN
2575 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2576 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), nvram_safe_get("lan1_stp"));
2577 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2578 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), nvram_safe_get("lan2_stp"));
2579 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2580 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), nvram_safe_get("lan3_stp"));
2581 #endif
2583 goto CLEAR;
2586 if (strcmp(service, "ctnf") == 0) {
2587 if (action & A_START) {
2588 setup_conntrack();
2589 stop_firewall();
2590 start_firewall();
2592 goto CLEAR;
2595 if (strcmp(service, "wan") == 0) {
2596 if (action & A_STOP) {
2597 stop_wan();
2600 if (action & A_START) {
2601 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2602 start_wan(BOOT);
2603 sleep(2);
2604 force_to_dial();
2606 goto CLEAR;
2609 if (strcmp(service, "net") == 0) {
2610 if (action & A_STOP) {
2611 #ifdef TCONFIG_USB
2612 stop_nas_services();
2613 #endif
2614 stop_httpd();
2615 stop_dnsmasq();
2616 stop_nas();
2617 stop_wan();
2618 stop_arpbind();
2619 stop_lan();
2620 stop_vlan();
2622 if (action & A_START) {
2623 start_vlan();
2624 start_lan();
2625 start_arpbind();
2626 start_wan(BOOT);
2627 start_nas();
2628 start_dnsmasq();
2629 start_httpd();
2630 start_wl();
2631 #ifdef TCONFIG_USB
2632 start_nas_services();
2633 #endif
2635 goto CLEAR;
2638 if (strcmp(service, "wireless") == 0) {
2639 if(action & A_STOP) {
2640 stop_wireless();
2642 if(action & A_START) {
2643 start_wireless();
2645 goto CLEAR;
2648 if (strcmp(service, "wl") == 0) {
2649 if(action & A_STOP) {
2650 stop_wireless();
2651 unload_wl();
2653 if(action & A_START) {
2654 load_wl();
2655 start_wireless();
2656 stop_wireless();
2657 start_wireless();
2659 goto CLEAR;
2662 if (strcmp(service, "nas") == 0) {
2663 if (action & A_STOP) {
2664 stop_nas();
2666 if (action & A_START) {
2667 start_nas();
2668 start_wl();
2670 goto CLEAR;
2673 if (strcmp(service, "rstats") == 0) {
2674 if (action & A_STOP) stop_rstats();
2675 if (action & A_START) start_rstats(0);
2676 goto CLEAR;
2679 if (strcmp(service, "rstatsnew") == 0) {
2680 if (action & A_STOP) stop_rstats();
2681 if (action & A_START) start_rstats(1);
2682 goto CLEAR;
2685 if (strcmp(service, "cstats") == 0) {
2686 if (action & A_STOP) stop_cstats();
2687 if (action & A_START) start_cstats(0);
2688 goto CLEAR;
2691 if (strcmp(service, "cstatsnew") == 0) {
2692 if (action & A_STOP) stop_cstats();
2693 if (action & A_START) start_cstats(1);
2694 goto CLEAR;
2697 if (strcmp(service, "sched") == 0) {
2698 if (action & A_STOP) stop_sched();
2699 if (action & A_START) start_sched();
2700 goto CLEAR;
2704 #ifdef TCONFIG_SNMP
2705 if (strcmp(service, "snmp") == 0) {
2706 if (action & A_STOP) stop_snmp();
2707 if (action & A_START) start_snmp();
2708 goto CLEAR;
2710 #endif
2713 #ifdef TCONFIG_USB
2714 // !!TB - USB Support
2715 if (strcmp(service, "usb") == 0) {
2716 if (action & A_STOP) stop_usb();
2717 if (action & A_START) {
2718 start_usb();
2719 // restart Samba and ftp since they may be killed by stop_usb()
2720 restart_nas_services(0, 1);
2721 // remount all partitions by simulating hotplug event
2722 add_remove_usbhost("-1", 1);
2724 goto CLEAR;
2727 if (strcmp(service, "usbapps") == 0) {
2728 if (action & A_STOP) stop_nas_services();
2729 if (action & A_START) start_nas_services();
2730 goto CLEAR;
2732 #endif
2734 #ifdef TCONFIG_FTP
2735 // !!TB - FTP Server
2736 if (strcmp(service, "ftpd") == 0) {
2737 if (action & A_STOP) stop_ftpd();
2738 setup_conntrack();
2739 stop_firewall();
2740 start_firewall();
2741 if (action & A_START) start_ftpd();
2742 goto CLEAR;
2744 #endif
2746 #ifdef TCONFIG_MEDIA_SERVER
2747 if (strcmp(service, "media") == 0 || strcmp(service, "dlna") == 0) {
2748 if (action & A_STOP) stop_media_server();
2749 if (action & A_START) start_media_server();
2750 goto CLEAR;
2752 #endif
2754 #ifdef TCONFIG_SAMBASRV
2755 // !!TB - Samba
2756 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
2757 if (action & A_STOP) stop_samba();
2758 if (action & A_START) {
2759 create_passwd();
2760 stop_dnsmasq();
2761 start_dnsmasq();
2762 start_samba();
2764 goto CLEAR;
2766 #endif
2768 #ifdef TCONFIG_OPENVPN
2769 if (strncmp(service, "vpnclient", 9) == 0) {
2770 if (action & A_STOP) stop_vpnclient(atoi(&service[9]));
2771 if (action & A_START) start_vpnclient(atoi(&service[9]));
2772 goto CLEAR;
2775 if (strncmp(service, "vpnserver", 9) == 0) {
2776 if (action & A_STOP) stop_vpnserver(atoi(&service[9]));
2777 if (action & A_START) start_vpnserver(atoi(&service[9]));
2778 goto CLEAR;
2780 #endif
2782 #ifdef TCONFIG_NOCAT
2783 if (strcmp(service, "splashd") == 0) {
2784 if (action & A_STOP) stop_splashd();
2785 if (action & A_START) start_splashd();
2786 goto CLEAR;
2788 #endif
2790 #ifdef TCONFIG_PPTPD
2791 if (strcmp(service, "pptpd") == 0) {
2792 if (action & A_STOP) stop_pptpd();
2793 if (action & A_START) start_pptpd();
2794 goto CLEAR;
2796 #endif
2798 #ifdef TCONFIG_USERPPTP
2799 if (strcmp(service, "pptpclient") == 0) {
2800 if (action & A_STOP) stop_pptp_client();
2801 if (action & A_START) start_pptp_client();
2802 if (action & (A_START | A_STOP))
2804 stop_dnsmasq();
2805 dns_to_resolv();
2806 start_dnsmasq();
2807 if ((action & A_START) == 0)
2808 clear_pptp_route();
2810 goto CLEAR;
2812 #endif
2814 CLEAR:
2815 if (next) goto TOP;
2817 // some functions check action_service and must be cleared at end -- zzz
2818 nvram_set("action_service", "");
2820 // Force recheck in 500 msec
2821 setitimer(ITIMER_REAL, &pop_tv, NULL);
2824 static void do_service(const char *name, const char *action, int user)
2826 int n;
2827 char s[64];
2829 n = 150;
2830 while (!nvram_match("action_service", "")) {
2831 if (user) {
2832 putchar('*');
2833 fflush(stdout);
2835 else if (--n < 0) break;
2836 usleep(100 * 1000);
2839 snprintf(s, sizeof(s), "%s-%s%s", name, action, (user ? "-c" : ""));
2840 nvram_set("action_service", s);
2842 if (nvram_match("debug_rc_svc", "1")) {
2843 nvram_unset("debug_rc_svc");
2844 exec_service();
2845 } else {
2846 kill(1, SIGUSR1);
2849 n = 150;
2850 while (nvram_match("action_service", s)) {
2851 if (user) {
2852 putchar('.');
2853 fflush(stdout);
2855 else if (--n < 0) {
2856 break;
2858 usleep(100 * 1000);
2862 int service_main(int argc, char *argv[])
2864 if (argc != 3) usage_exit(argv[0], "<service> <action>");
2865 do_service(argv[1], argv[2], 1);
2866 printf("\nDone.\n");
2867 return 0;
2870 void start_service(const char *name)
2872 do_service(name, "start", 0);
2875 void stop_service(const char *name)
2877 do_service(name, "stop", 0);
2881 void restart_service(const char *name)
2883 do_service(name, "restart", 0);