Setting log-async to a sane value per http://www.thekelleys.org.uk/dnsmasq/docs/dnsma...
[tomato.git] / release / src-rt-6.x.4708 / router / rc / services.c
blobb011bba967f32490a749b9804ffa8bb6e47ee521
1 /*
3 Copyright 2003, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Copyright 2005, Broadcom Corporation
22 All Rights Reserved.
24 THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
25 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
26 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
27 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
32 Modified for Tomato Firmware
33 Portions, Copyright (C) 2006-2009 Jonathan Zarate
36 #include "rc.h"
38 #include <arpa/inet.h>
39 #include <time.h>
40 #include <sys/time.h>
41 #include <errno.h>
43 // !!TB
44 #include <sys/mount.h>
45 #include <mntent.h>
46 #include <dirent.h>
48 // Pop an alarm to recheck pids in 500 msec.
49 static const struct itimerval pop_tv = { {0,0}, {0, 500 * 1000} };
51 // Pop an alarm to reap zombies.
52 static const struct itimerval zombie_tv = { {0,0}, {307, 0} };
54 // -----------------------------------------------------------------------------
56 static const char dmhosts[] = "/etc/dnsmasq/hosts";
57 static const char dmdhcp[] = "/etc/dnsmasq/dhcp";
58 static const char dmresolv[] = "/etc/resolv.dnsmasq";
60 static pid_t pid_dnsmasq = -1;
62 static int is_wet(int idx, int unit, int subunit, void *param)
64 return nvram_match(wl_nvname("mode", unit, subunit), "wet");
67 void start_dnsmasq()
69 FILE *f;
70 const char *nv;
71 char buf[512];
72 char lan[24];
73 const char *router_ip;
74 char sdhcp_lease[32];
75 char *e;
76 int n;
77 char *mac, *ip, *name;
78 char *p;
79 int ipn;
80 char ipbuf[32];
81 FILE *hf, *df;
82 int dhcp_start;
83 int dhcp_count;
84 int dhcp_lease;
85 int do_dhcpd;
86 int do_dns;
87 int do_dhcpd_hosts;
89 #ifdef TCONFIG_IPV6
90 char *prefix, *ipv6, *mtu;
91 int do_6to4, do_6rd;
92 int service;
93 #endif
95 TRACE_PT("begin\n");
97 if (getpid() != 1) {
98 start_service("dnsmasq");
99 return;
102 stop_dnsmasq();
104 if (foreach_wif(1, NULL, is_wet)) return;
106 if ((f = fopen("/etc/dnsmasq.conf", "w")) == NULL) return;
108 router_ip = nvram_safe_get("lan_ipaddr");
110 fprintf(f,
111 "pid-file=/var/run/dnsmasq.pid\n");
112 if (((nv = nvram_get("wan_domain")) != NULL) || ((nv = nvram_get("wan_get_domain")) != NULL)) {
113 if (*nv) fprintf(f, "domain=%s\n", nv);
116 // dns
117 const dns_list_t *dns = get_dns(); // this always points to a static buffer
119 if (((nv = nvram_get("dns_minport")) != NULL) && (*nv)) n = atoi(nv);
120 else n = 4096;
121 fprintf(f,
122 "resolv-file=%s\n" // the real stuff is here
123 "addn-hosts=%s\n" // directory with additional hosts files
124 "dhcp-hostsfile=%s\n" // directory with dhcp hosts files
125 "expand-hosts\n" // expand hostnames in hosts file
126 "min-port=%u\n", // min port used for random src port
127 dmresolv, dmhosts, dmdhcp, n);
128 do_dns = nvram_match("dhcpd_dmdns", "1");
130 // DNS rebinding protection, will discard upstream RFC1918 responses
131 if (nvram_get_int("dns_norebind")) {
132 fprintf(f,
133 "stop-dns-rebind\n"
134 "rebind-localhost-ok\n");
135 // allow RFC1918 responses for server domain
136 switch (get_wan_proto()) {
137 case WP_PPTP:
138 nv = nvram_get("pptp_server_ip");
139 break;
140 case WP_L2TP:
141 nv = nvram_get("l2tp_server_ip");
142 break;
143 default:
144 nv = NULL;
145 break;
147 if (nv && *nv) fprintf(f, "rebind-domain-ok=%s\n", nv);
150 #ifdef TCONFIG_DNSCRYPT
151 if (nvram_match("dnscrypt_proxy", "1")) {
152 fprintf(f, "server=127.0.0.1#%s\n", nvram_safe_get("dnscrypt_port") );
154 #endif
156 for (n = 0 ; n < dns->count; ++n) {
157 if (dns->dns[n].port != 53) {
158 fprintf(f, "server=%s#%u\n", inet_ntoa(dns->dns[n].addr), dns->dns[n].port);
162 if (nvram_get_int("dhcpd_static_only")) {
163 fprintf(f, "dhcp-ignore=tag:!known\n");
166 if ((n = nvram_get_int("dnsmasq_q"))) { //process quiet flags
167 if (n & 1) fprintf(f, "quiet-dhcp\n");
168 if (n & 2) fprintf(f, "quiet-dhcp6\n");
169 if (n & 4) fprintf(f, "quiet-ra\n");
172 // dhcp
173 do_dhcpd_hosts=0;
174 char lanN_proto[] = "lanXX_proto";
175 char lanN_ifname[] = "lanXX_ifname";
176 char lanN_ipaddr[] = "lanXX_ipaddr";
177 char lanN_netmask[] = "lanXX_netmask";
178 char dhcpdN_startip[] = "dhcpdXX_startip";
179 char dhcpdN_endip[] = "dhcpdXX_endip";
180 char dhcpN_start[] = "dhcpXX_start";
181 char dhcpN_num[] = "dhcpXX_num";
182 char dhcpN_lease[] = "dhcpXX_lease";
183 char br;
184 for(br=0 ; br<=3 ; br++) {
185 char bridge[2] = "0";
186 if (br!=0)
187 bridge[0]+=br;
188 else
189 strcpy(bridge, "");
191 sprintf(lanN_proto, "lan%s_proto", bridge);
192 sprintf(lanN_ifname, "lan%s_ifname", bridge);
193 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
194 do_dhcpd = nvram_match(lanN_proto, "dhcp");
195 if (do_dhcpd) {
196 do_dhcpd_hosts++;
198 router_ip = nvram_safe_get(lanN_ipaddr);
199 strlcpy(lan, router_ip, sizeof(lan));
200 if ((p = strrchr(lan, '.')) != NULL) *(p + 1) = 0;
202 fprintf(f,
203 "interface=%s\n",
204 nvram_safe_get(lanN_ifname));
206 sprintf(dhcpN_lease, "dhcp%s_lease", bridge);
207 dhcp_lease = nvram_get_int(dhcpN_lease);
209 if (dhcp_lease <= 0) dhcp_lease = 1440;
211 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
212 if (n < 0) strcpy(sdhcp_lease, "infinite");
213 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
215 if (!do_dns) {
216 // if not using dnsmasq for dns
218 if ((dns->count == 0) && (nvram_get_int("dhcpd_llndns"))) {
219 // no DNS might be temporary. use a low lease time to force clients to update.
220 dhcp_lease = 2;
221 strcpy(sdhcp_lease, "2m");
222 do_dns = 1;
224 else {
225 // pass the dns directly
226 buf[0] = 0;
227 for (n = 0 ; n < dns->count; ++n) {
228 if (dns->dns[n].port == 53) { // check: option 6 doesn't seem to support other ports
229 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n].addr));
232 fprintf(f, "dhcp-option=tag:%s,6%s\n", nvram_safe_get(lanN_ifname), buf);
236 sprintf(dhcpdN_startip, "dhcpd%s_startip", bridge);
237 sprintf(dhcpdN_endip, "dhcpd%s_endip", bridge);
238 sprintf(lanN_netmask, "lan%s_netmask", bridge);
240 if ((p = nvram_get(dhcpdN_startip)) && (*p) && (e = nvram_get(dhcpdN_endip)) && (*e)) {
241 fprintf(f, "dhcp-range=tag:%s,%s,%s,%s,%dm\n", nvram_safe_get(lanN_ifname), p, e, nvram_safe_get(lanN_netmask), dhcp_lease);
243 else {
244 // for compatibility
245 sprintf(dhcpN_start, "dhcp%s_start", bridge);
246 sprintf(dhcpN_num, "dhcp%s_num", bridge);
247 sprintf(lanN_netmask, "lan%s_netmask", bridge);
248 dhcp_start = nvram_get_int(dhcpN_start);
249 dhcp_count = nvram_get_int(dhcpN_num);
250 fprintf(f, "dhcp-range=tag:%s,%s%d,%s%d,%s,%dm\n",
251 nvram_safe_get(lanN_ifname), lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get(lanN_netmask), dhcp_lease);
254 nv = nvram_safe_get(lanN_ipaddr);
255 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED)) {
256 p = nvram_safe_get("lan_gateway");
257 if ((*p) && (strcmp(p, "0.0.0.0") != 0)) nv = p;
260 fprintf(f,
261 "dhcp-option=tag:%s,3,%s\n", // gateway
262 nvram_safe_get(lanN_ifname), nv);
264 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
265 fprintf(f, "dhcp-option=tag:%s,44,%s\n", nvram_safe_get(lanN_ifname), nv);
267 #ifdef TCONFIG_SAMBASRV
268 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
269 if ((nv == NULL) || (*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
270 // Samba will serve as a WINS server
271 fprintf(f, "dhcp-option=tag:%s,44,%s\n", nvram_safe_get(lanN_ifname), nvram_safe_get(lanN_ipaddr));
274 #endif
275 } else {
276 if (strcmp(nvram_safe_get(lanN_ifname),"")!=0) {
277 fprintf(f, "interface=%s\n", nvram_safe_get(lanN_ifname));
278 // if no dhcp range is set then no dhcp service will be offered so following
279 // line is superflous.
280 // fprintf(f, "no-dhcp-interface=%s\n", nvram_safe_get(lanN_ifname));
284 // write static lease entries & create hosts file
286 mkdir_if_none(dmhosts);
287 snprintf(buf, sizeof(buf), "%s/hosts", dmhosts);
288 if ((hf = fopen(buf, "w")) != NULL) {
289 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
290 fprintf(hf, "%s %s\n", router_ip, nv);
291 #ifdef TCONFIG_SAMBASRV
292 else if (((nv = nvram_get("lan_hostname")) != NULL) && (*nv))
293 fprintf(hf, "%s %s\n", router_ip, nv);
294 #endif
295 p = (char *)get_wanip();
296 if ((*p == 0) || strcmp(p, "0.0.0.0") == 0)
297 p = "127.0.0.1";
298 fprintf(hf, "%s wan-ip\n", p);
299 if (nv && (*nv))
300 fprintf(hf, "%s %s-wan\n", p, nv);
303 mkdir_if_none(dmdhcp);
304 snprintf(buf, sizeof(buf), "%s/dhcp-hosts", dmdhcp);
305 df = fopen(buf, "w");
307 // PREVIOUS/OLD FORMAT:
308 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
309 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
310 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 106 w/ delim
312 // NEW FORMAT (+static ARP binding after hostname):
313 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 55 w/ delim
314 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 87 w/ delim
315 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 108 w/ delim
317 p = nvram_safe_get("dhcpd_static");
318 while ((e = strchr(p, '>')) != NULL) {
319 n = (e - p);
320 if (n > 107) {
321 p = e + 1;
322 continue;
325 strncpy(buf, p, n);
326 buf[n] = 0;
327 p = e + 1;
329 if ((e = strchr(buf, '<')) == NULL) continue;
330 *e = 0;
331 mac = buf;
333 ip = e + 1;
334 if ((e = strchr(ip, '<')) == NULL) continue;
335 *e = 0;
336 if (strchr(ip, '.') == NULL) {
337 ipn = atoi(ip);
338 if ((ipn <= 0) || (ipn > 255)) continue;
339 sprintf(ipbuf, "%s%d", lan, ipn);
340 ip = ipbuf;
342 else {
343 if (inet_addr(ip) == INADDR_NONE) continue;
346 name = e + 1;
348 if ((e = strchr(name, '<')) != NULL) {
349 *e = 0;
352 if ((hf) && (*name != 0)) {
353 fprintf(hf, "%s %s\n", ip, name);
356 if ((do_dhcpd_hosts > 0) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
357 if (nvram_get_int("dhcpd_slt") == 0) {
358 fprintf(f, "dhcp-host=%s,%s\n", mac, ip);
359 } else {
360 fprintf(f, "dhcp-host=%s,%s,%s\n", mac, ip, sdhcp_lease);
365 if (df) fclose(df);
366 if (hf) fclose(hf);
368 n = nvram_get_int("dhcpd_lmax");
369 fprintf(f,
370 "dhcp-lease-max=%d\n",
371 (n > 0) ? n : 255);
372 if (nvram_get_int("dhcpd_auth") >= 0) {
373 fprintf(f, "dhcp-authoritative\n");
376 #ifdef TCONFIG_DNSSEC
377 if (nvram_match("dnssec_enable", "1")) {
378 fprintf(f, "conf-file=/etc/trust-anchors.conf\n"
379 "dnssec\n"
380 "dnssec-no-timecheck\n");
382 #endif
384 #ifdef TCONFIG_DNSCRYPT
385 if (nvram_match("dnscrypt_proxy", "1")) {
386 if (nvram_match("dnscrypt_priority", "1"))
387 fprintf(f, "strict-order\n");
389 if (nvram_match("dnscrypt_priority", "2"))
390 fprintf(f, "no-resolv\n");
392 #endif
396 #ifdef TCONFIG_OPENVPN
397 write_vpn_dnsmasq_config(f);
398 #endif
400 #ifdef TCONFIG_PPTPD
401 write_pptpd_dnsmasq_config(f);
402 #endif
404 #ifdef TCONFIG_IPV6
405 if (ipv6_enabled()) {
407 service = get_ipv6_service();
408 do_6to4 = (service == IPV6_ANYCAST_6TO4);
409 do_6rd = (service == IPV6_6RD || service == IPV6_6RD_DHCP);
410 mtu = NULL;
412 switch (service) {
413 case IPV6_NATIVE_DHCP:
414 case IPV6_ANYCAST_6TO4:
415 case IPV6_6IN4:
416 case IPV6_6RD:
417 case IPV6_6RD_DHCP:
418 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
419 // fall through
420 default:
421 prefix = do_6to4 ? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
422 break;
424 if (!(*prefix)) prefix = "::";
425 ipv6 = (char *)ipv6_router_address(NULL);
427 fprintf(f, "enable-ra\ndhcp-range=tag:br0,%s, slaac, ra-names, 64\n", prefix);
430 // enable-ra should be enabled in both cases
431 if (nvram_get_int("ipv6_radvd") || nvram_get_int("ipv6_dhcpd"))
432 fprintf(f,"enable-ra\n");
434 // Only SLAAC and NO DHCPv6
435 if (nvram_get_int("ipv6_radvd") && !nvram_get_int("ipv6_dhcpd"))
436 fprintf(f,"dhcp-range=::, constructor:br*, ra-names, ra-stateless, 64, 12h\n");
438 // Only DHCPv6 and NO SLAAC
439 if (nvram_get_int("ipv6_dhcpd") && !nvram_get_int("ipv6_radvd"))
440 fprintf(f,"dhcp-range=::1, ::FFFF:FFFF, constructor:br*, 64, 12h\n");
442 // SLAAC and DHCPv6 (2 IPv6 IPs)
443 if (nvram_get_int("ipv6_radvd") && nvram_get_int("ipv6_dhcpd"))
444 fprintf(f,"dhcp-range=::1, ::FFFF:FFFF, constructor:br*, ra-names, 64, 12h\n");
446 #endif
448 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
450 fappend(f, "/etc/dnsmasq.custom");
451 fappend(f, "/etc/dnsmasq.ipset");
455 fclose(f);
457 if (do_dns) {
458 unlink("/etc/resolv.conf");
459 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
462 TRACE_PT("run dnsmasq\n");
464 // Default to some values we like, but allow the user to override them.
465 eval("dnsmasq", "-c", "25", "--log-async");
466 eval("dnsmasq", "-c", "2048", "--cache-size");
468 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
469 pid_dnsmasq = -2;
472 TRACE_PT("end\n");
474 #ifdef TCONFIG_DNSCRYPT
475 //start dnscrypt-proxy
476 if (nvram_match("dnscrypt_proxy", "1")) {
477 char dnscrypt_local[30];
478 sprintf(dnscrypt_local, "127.0.0.1:%s", nvram_safe_get("dnscrypt_port") );
480 eval("ntp2ip");
482 if (nvram_match("dnscrypt_manual", "1")) {
483 eval("dnscrypt-proxy", "-d",
484 "-a", dnscrypt_local,
485 "-m", nvram_safe_get("dnscrypt_log"),
486 "-N", nvram_safe_get("dnscrypt_provider_name"),
487 "-k", nvram_safe_get("dnscrypt_provider_key"),
488 "-r", nvram_safe_get("dnscrypt_resolver_address") );
489 } else {
490 eval("dnscrypt-proxy", "-d",
491 "-a", dnscrypt_local,
492 "-m", nvram_safe_get("dnscrypt_log"),
493 "-R", nvram_safe_get("dnscrypt_resolver"),
494 "-L", "/etc/dnscrypt-resolvers.csv" );
497 #ifdef TCONFIG_IPV6
498 char dnscrypt_local_ipv6[30];
499 sprintf(dnscrypt_local_ipv6, "::1:%s", nvram_safe_get("dnscrypt_port") );
501 if (get_ipv6_service() != *("NULL")) { // when ipv6 enabled
502 if (nvram_match("dnscrypt_manual", "1")) {
503 eval("dnscrypt-proxy", "-d",
504 "-a", dnscrypt_local,
505 "-m", nvram_safe_get("dnscrypt_log"),
506 "-N", nvram_safe_get("dnscrypt_provider_name"),
507 "-k", nvram_safe_get("dnscrypt_provider_key"),
508 "-r", nvram_safe_get("dnscrypt_resolver_address") );
509 } else {
510 eval("dnscrypt-proxy", "-d",
511 "-a", dnscrypt_local,
512 "-m", nvram_safe_get("dnscrypt_log"),
513 "-R", nvram_safe_get("dnscrypt_resolver"),
514 "-L", "/etc/dnscrypt-resolvers.csv" );
517 #endif
519 #endif
521 #ifdef TCONFIG_DNSSEC
522 if ((time(0) > Y2K) && nvram_match("dnssec_enable", "1")){
523 killall("dnsmasq", SIGHUP);
525 #endif
529 void stop_dnsmasq(void)
531 TRACE_PT("begin\n");
533 if (getpid() != 1) {
534 stop_service("dnsmasq");
535 return;
538 pid_dnsmasq = -1;
540 unlink("/etc/resolv.conf");
541 symlink(dmresolv, "/etc/resolv.conf");
543 killall_tk("dnsmasq");
544 #ifdef TCONFIG_DNSCRYPT
545 killall_tk("dnscrypt-proxy");
546 #endif
548 TRACE_PT("end\n");
551 void clear_resolv(void)
553 f_write(dmresolv, NULL, 0, 0, 0); // blank
556 #ifdef TCONFIG_IPV6
557 static int write_ipv6_dns_servers(FILE *f, const char *prefix, char *dns, const char *suffix, int once)
559 char p[INET6_ADDRSTRLEN + 1], *next = NULL;
560 struct in6_addr addr;
561 int cnt = 0;
563 foreach(p, dns, next) {
564 // verify that this is a valid IPv6 address
565 if (inet_pton(AF_INET6, p, &addr) == 1) {
566 fprintf(f, "%s%s%s", (once && cnt) ? "" : prefix, p, suffix);
567 ++cnt;
571 return cnt;
573 #endif
575 void dns_to_resolv(void)
577 FILE *f;
578 const dns_list_t *dns;
579 int i;
580 mode_t m;
582 m = umask(022); // 077 from pppoecd
583 if ((f = fopen(dmresolv, "w")) != NULL) {
584 // Check for VPN DNS entries
585 if (!write_pptpvpn_resolv(f) && !write_vpn_resolv(f)) {
586 #ifdef TCONFIG_IPV6
587 if (write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_dns"), "\n", 0) == 0 || nvram_get_int("dns_addget"))
588 write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_get_dns"), "\n", 0);
589 #endif
590 dns = get_dns(); // static buffer
591 if (dns->count == 0) {
592 // Put a pseudo DNS IP to trigger Connect On Demand
593 if (nvram_match("ppp_demand", "1")) {
594 switch (get_wan_proto()) {
595 case WP_PPPOE:
596 case WP_PPP3G:
597 case WP_PPTP:
598 case WP_L2TP:
599 fprintf(f, "nameserver 1.1.1.1\n");
600 break;
604 else {
605 for (i = 0; i < dns->count; i++) {
606 if (dns->dns[i].port == 53) { // resolv.conf doesn't allow for an alternate port
607 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i].addr));
612 fclose(f);
614 umask(m);
617 // -----------------------------------------------------------------------------
619 void start_httpd(void)
621 if (getpid() != 1) {
622 start_service("httpd");
623 return;
626 if( nvram_match( "web_css", "online" ) )
627 xstart( "/usr/sbin/ttb" );
629 stop_httpd();
631 // set www dir
632 if ( nvram_match( "web_dir", "jffs" ) ) { chdir("/jffs/www"); }
633 else if ( nvram_match( "web_dir", "opt" ) ) { chdir("/opt/www"); }
634 else if ( nvram_match( "web_dir", "tmp" ) ) { chdir("/tmp/www");}
635 else { chdir("/www"); }
637 eval("httpd");
638 chdir("/");
641 void stop_httpd(void)
643 if (getpid() != 1) {
644 stop_service("httpd");
645 return;
648 killall_tk("httpd");
651 // -----------------------------------------------------------------------------
652 #ifdef TCONFIG_IPV6
654 static void add_ip6_lanaddr(void)
656 char ip[INET6_ADDRSTRLEN + 4];
657 const char *p;
659 p = ipv6_router_address(NULL);
660 if (*p) {
661 snprintf(ip, sizeof(ip), "%s/%d", p, nvram_get_int("ipv6_prefix_length") ? : 64);
662 eval("ip", "-6", "addr", "add", ip, "dev", nvram_safe_get("lan_ifname"));
666 void start_ipv6_tunnel(void)
668 char ip[INET6_ADDRSTRLEN + 4];
669 struct in_addr addr4;
670 struct in6_addr addr;
671 const char *wanip, *mtu, *tun_dev;
672 int service;
674 service = get_ipv6_service();
675 tun_dev = get_wan6face();
676 wanip = get_wanip();
677 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
678 modprobe("sit");
680 if (service == IPV6_ANYCAST_6TO4)
681 snprintf(ip, sizeof(ip), "192.88.99.%d", nvram_get_int("ipv6_relay"));
682 else
683 strlcpy(ip, (char *)nvram_safe_get("ipv6_tun_v4end"), sizeof(ip));
684 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit",
685 "remote", ip,
686 "local", (char *)wanip,
687 "ttl", nvram_safe_get("ipv6_tun_ttl"));
689 eval("ip", "link", "set", (char *)tun_dev, "mtu", (char *)mtu, "up");
690 nvram_set("ipv6_ifname", (char *)tun_dev);
692 if (service == IPV6_ANYCAST_6TO4) {
693 add_ip6_lanaddr();
694 addr4.s_addr = 0;
695 memset(&addr, 0, sizeof(addr));
696 inet_aton(wanip, &addr4);
697 addr.s6_addr16[0] = htons(0x2002);
698 ipv6_mapaddr4(&addr, 16, &addr4, 0);
699 addr.s6_addr16[7] = htons(0x0001);
700 inet_ntop(AF_INET6, &addr, ip, sizeof(ip));
701 strncat(ip, "/16", sizeof(ip));
703 else {
704 snprintf(ip, sizeof(ip), "%s/%d",
705 nvram_safe_get("ipv6_tun_addr"),
706 nvram_get_int("ipv6_tun_addrlen") ? : 64);
708 eval("ip", "addr", "add", ip, "dev", (char *)tun_dev);
709 eval("ip", "route", "add", "::/0", "dev", (char *)tun_dev);
711 // (re)start radvd - now dnsmasq provided
712 if (service == IPV6_ANYCAST_6TO4)
713 start_dnsmasq();
716 void stop_ipv6_tunnel(void)
718 eval("ip", "tunnel", "del", (char *)get_wan6face());
719 if (get_ipv6_service() == IPV6_ANYCAST_6TO4) {
720 // get rid of old IPv6 address from lan iface
721 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
723 modprobe_r("sit");
726 void start_6rd_tunnel(void)
728 const char *tun_dev, *wanip;
729 int service, mask_len, prefix_len, local_prefix_len;
730 char mtu[10], prefix[INET6_ADDRSTRLEN], relay[INET_ADDRSTRLEN];
731 struct in_addr netmask_addr, relay_addr, relay_prefix_addr, wanip_addr;
732 struct in6_addr prefix_addr, local_prefix_addr;
733 char local_prefix[INET6_ADDRSTRLEN];
734 char tmp_ipv6[INET6_ADDRSTRLEN + 4], tmp_ipv4[INET_ADDRSTRLEN + 4];
735 char tmp[256];
736 FILE *f;
738 service = get_ipv6_service();
739 wanip = get_wanip();
740 tun_dev = get_wan6face();
741 sprintf(mtu, "%d", (nvram_get_int("wan_mtu") > 0) ? (nvram_get_int("wan_mtu") - 20) : 1280);
743 // maybe we can merge the ipv6_6rd_* variables into a single ipv_6rd_string (ala wan_6rd)
744 // to save nvram space?
745 if (service == IPV6_6RD) {
746 _dprintf("starting 6rd tunnel using manual settings.\n");
747 mask_len = nvram_get_int("ipv6_6rd_ipv4masklen");
748 prefix_len = nvram_get_int("ipv6_6rd_prefix_length");
749 strcpy(prefix, nvram_safe_get("ipv6_6rd_prefix"));
750 strcpy(relay, nvram_safe_get("ipv6_6rd_borderrelay"));
752 else {
753 _dprintf("starting 6rd tunnel using automatic settings.\n");
754 char *wan_6rd = nvram_safe_get("wan_6rd");
755 if (sscanf(wan_6rd, "%d %d %s %s", &mask_len, &prefix_len, prefix, relay) < 4) {
756 _dprintf("wan_6rd string is missing or invalid (%s)\n", wan_6rd);
757 return;
761 // validate values that were passed
762 if (mask_len < 0 || mask_len > 32) {
763 _dprintf("invalid mask_len value (%d)\n", mask_len);
764 return;
766 if (prefix_len < 0 || prefix_len > 128) {
767 _dprintf("invalid prefix_len value (%d)\n", prefix_len);
768 return;
770 if ((32 - mask_len) + prefix_len > 128) {
771 _dprintf("invalid combination of mask_len and prefix_len!\n");
772 return;
775 sprintf(tmp, "ping -q -c 2 %s | grep packet", relay);
776 if ((f = popen(tmp, "r")) == NULL) {
777 _dprintf("error obtaining data\n");
778 return;
780 fgets(tmp, sizeof(tmp), f);
781 pclose(f);
782 if (strstr(tmp, " 0% packet loss") == NULL) {
783 _dprintf("failed to ping border relay\n");
784 return;
787 // get relay prefix from border relay address and mask
788 netmask_addr.s_addr = htonl(0xffffffff << (32 - mask_len));
789 inet_aton(relay, &relay_addr);
790 relay_prefix_addr.s_addr = relay_addr.s_addr & netmask_addr.s_addr;
792 // calculate the local prefix
793 inet_pton(AF_INET6, prefix, &prefix_addr);
794 inet_pton(AF_INET, wanip, &wanip_addr);
795 if (calc_6rd_local_prefix(&prefix_addr, prefix_len, mask_len,
796 &wanip_addr, &local_prefix_addr, &local_prefix_len) == 0) {
797 _dprintf("error calculating local prefix.");
798 return;
800 inet_ntop(AF_INET6, &local_prefix_addr, local_prefix, sizeof(local_prefix));
802 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1", local_prefix);
803 nvram_set("ipv6_rtr_addr", tmp_ipv6);
804 nvram_set("ipv6_prefix", local_prefix);
806 // load sit module needed for the 6rd tunnel
807 modprobe("sit");
809 // creating the 6rd tunnel
810 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit", "local", (char *)wanip, "ttl", nvram_safe_get("ipv6_tun_ttl"));
812 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s/%d", prefix, prefix_len);
813 snprintf(tmp_ipv4, sizeof(tmp_ipv4), "%s/%d", inet_ntoa(relay_prefix_addr), mask_len);
814 eval("ip", "tunnel" "6rd", "dev", (char *)tun_dev, "6rd-prefix", tmp_ipv6, "6rd-relay_prefix", tmp_ipv4);
816 // bringing up the link
817 eval("ip", "link", "set", "dev", (char *)tun_dev, "mtu", (char *)mtu, "up");
819 // setting the WAN address Note: IPv6 WAN CIDR should be: ((32 - ip6rd_ipv4masklen) + ip6rd_prefixlen)
820 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1/%d", local_prefix, local_prefix_len);
821 eval("ip", "-6", "addr", "add", tmp_ipv6, "dev", (char *)tun_dev);
823 // setting the LAN address Note: IPv6 LAN CIDR should be 64
824 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1/%d", local_prefix, nvram_get_int("ipv6_prefix_length") ? : 64);
825 eval("ip", "-6", "addr", "add", tmp_ipv6, "dev", nvram_safe_get("lan_ifname"));
827 // adding default route via the border relay
828 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "::%s", relay);
829 eval("ip", "-6", "route", "add", "default", "via", tmp_ipv6, "dev", (char *)tun_dev);
831 nvram_set("ipv6_ifname", (char *)tun_dev);
833 // (re)start radvd now dnsmasq
834 start_dnsmasq();
836 printf("6rd end\n");
839 void stop_6rd_tunnel(void)
841 eval("ip", "tunnel", "del", (char *)get_wan6face());
842 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
843 modprobe_r("sit");
847 void start_ipv6(void)
849 int service;
851 service = get_ipv6_service();
852 enable_ip6_forward();
854 // Check if turned on
855 switch (service) {
856 case IPV6_NATIVE:
857 case IPV6_6IN4:
858 case IPV6_MANUAL:
859 add_ip6_lanaddr();
860 break;
861 case IPV6_NATIVE_DHCP:
862 case IPV6_ANYCAST_6TO4:
863 nvram_set("ipv6_rtr_addr", "");
864 nvram_set("ipv6_prefix", "");
865 break;
868 if (service != IPV6_DISABLED) {
869 if ((nvram_get_int("ipv6_accept_ra") & 2) != 0 && !nvram_get_int("ipv6_radvd"))
870 accept_ra(nvram_safe_get("lan_ifname"));
874 void stop_ipv6(void)
876 stop_ipv6_tunnel();
877 stop_dhcp6c();
878 eval("ip", "-6", "addr", "flush", "scope", "global");
881 #endif
883 // -----------------------------------------------------------------------------
885 void start_upnp(void)
887 if (getpid() != 1) {
888 start_service("upnp");
889 return;
892 if (get_wan_proto() == WP_DISABLED) return;
894 int enable;
895 FILE *f;
896 int upnp_port;
898 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
899 mkdir("/etc/upnp", 0777);
900 if (f_exists("/etc/upnp/config.alt")) {
901 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
903 else {
904 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
905 upnp_port = nvram_get_int("upnp_port");
906 if ((upnp_port < 0) || (upnp_port >= 0xFFFF)) upnp_port = 0;
909 fprintf(f,
910 "ext_ifname=%s\n"
911 "port=%d\n"
912 "enable_upnp=%s\n"
913 "enable_natpmp=%s\n"
914 "secure_mode=%s\n"
915 "upnp_forward_chain=upnp\n"
916 "upnp_nat_chain=upnp\n"
917 "notify_interval=%d\n"
918 "system_uptime=yes\n"
919 "friendly_name=%s"" Router\n"
920 "model_name=%s\n"
921 "model_url=http://linksysinfo.org/index.php?forums/tomato-firmware.33/\n"
922 "manufacturer_name=Tomato Firmware\n"
923 "manufacturer_url=http://linksysinfo.org/index.php?forums/tomato-firmware.33/\n"
924 "\n"
926 get_wanface(),
927 upnp_port,
928 (enable & 1) ? "yes" : "no", // upnp enable
929 (enable & 2) ? "yes" : "no", // natpmp enable
930 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
931 nvram_get_int("upnp_ssdp_interval"),
932 nvram_safe_get("router_name"),
933 nvram_safe_get("t_model_name")
936 if (nvram_get_int("upnp_clean")) {
937 int interval = nvram_get_int("upnp_clean_interval");
938 if (interval < 60) interval = 60;
939 fprintf(f,
940 "clean_ruleset_interval=%d\n"
941 "clean_ruleset_threshold=%d\n",
942 interval,
943 nvram_get_int("upnp_clean_threshold")
946 else
947 fprintf(f,"clean_ruleset_interval=0\n");
949 if (nvram_match("upnp_mnp", "1")) {
950 int https = nvram_get_int("https_enable");
951 fprintf(f, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
952 https ? "s" : "", nvram_safe_get("lan_ipaddr"),
953 nvram_safe_get(https ? "https_lanport" : "http_lanport"));
955 else {
956 // Empty parameters are not included into XML service description
957 fprintf(f, "presentation_url=\n");
960 char uuid[45];
961 f_read_string("/proc/sys/kernel/random/uuid", uuid, sizeof(uuid));
962 fprintf(f, "uuid=%s\n", uuid);
964 // shibby - move custom configuration before "allow" statements
965 // discussion: http://www.linksysinfo.org/index.php?threads/miniupnpd-custom-config-syntax.70863/#post-256291
966 fappend(f, "/etc/upnp/config.custom");
967 fprintf(f, "%s\n", nvram_safe_get("upnp_custom"));
969 char lanN_ipaddr[] = "lanXX_ipaddr";
970 char lanN_netmask[] = "lanXX_netmask";
971 char upnp_lanN[] = "upnp_lanXX";
972 char br;
974 for(br=0 ; br<4 ; br++) {
975 char bridge[2] = "0";
976 if (br!=0)
977 bridge[0]+=br;
978 else
979 strcpy(bridge, "");
981 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
982 sprintf(lanN_netmask, "lan%s_netmask", bridge);
983 sprintf(upnp_lanN, "upnp_lan%s", bridge);
985 char *lanip = nvram_safe_get(lanN_ipaddr);
986 char *lanmask = nvram_safe_get(lanN_netmask);
987 char *lanlisten = nvram_safe_get(upnp_lanN);
989 if((strcmp(lanlisten,"1")==0) && (strcmp(lanip,"")!=0) && (strcmp(lanip,"0.0.0.0")!=0)) {
990 fprintf(f,
991 "listening_ip=%s/%s\n",
992 lanip, lanmask);
993 int ports[4];
994 if ((ports[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
995 (ports[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
996 (ports[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
997 (ports[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
998 fprintf(f,
999 "allow %d-%d %s/%s %d-%d\n",
1000 ports[0], ports[1],
1001 lanip, lanmask,
1002 ports[2], ports[3]
1005 else {
1006 // by default allow only redirection of ports above 1024
1007 fprintf(f, "allow 1024-65535 %s/%s 1024-65535\n", lanip, lanmask);
1011 fprintf(f, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
1012 fclose(f);
1014 xstart("miniupnpd", "-f", "/etc/upnp/config");
1020 void stop_upnp(void)
1022 if (getpid() != 1) {
1023 stop_service("upnp");
1024 return;
1027 killall_tk("miniupnpd");
1030 // -----------------------------------------------------------------------------
1032 static pid_t pid_crond = -1;
1034 void start_cron(void)
1036 stop_cron();
1038 eval("crond", nvram_contains_word("log_events", "crond") ? NULL : "-l", "9");
1039 if (!nvram_contains_word("debug_norestart", "crond")) {
1040 pid_crond = -2;
1044 void stop_cron(void)
1046 pid_crond = -1;
1047 killall_tk("crond");
1050 // -----------------------------------------------------------------------------
1051 #ifdef LINUX26
1053 static pid_t pid_hotplug2 = -1;
1055 void start_hotplug2()
1057 stop_hotplug2();
1059 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE, 0);
1060 xstart("hotplug2", "--persistent", "--no-coldplug");
1061 // FIXME: Don't remember exactly why I put "sleep" here -
1062 // but it was not for a race with check_services()... - TB
1063 sleep(1);
1065 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
1066 pid_hotplug2 = -2;
1070 void stop_hotplug2(void)
1072 pid_hotplug2 = -1;
1073 killall_tk("hotplug2");
1076 #endif /* LINUX26 */
1077 // -----------------------------------------------------------------------------
1079 // Written by Sparq in 2002/07/16
1080 void start_zebra(void)
1082 #ifdef TCONFIG_ZEBRA
1083 if (getpid() != 1) {
1084 start_service("zebra");
1085 return;
1088 FILE *fp;
1090 char *lan_tx = nvram_safe_get("dr_lan_tx");
1091 char *lan_rx = nvram_safe_get("dr_lan_rx");
1092 char *lan1_tx = nvram_safe_get("dr_lan1_tx");
1093 char *lan1_rx = nvram_safe_get("dr_lan1_rx");
1094 char *lan2_tx = nvram_safe_get("dr_lan2_tx");
1095 char *lan2_rx = nvram_safe_get("dr_lan2_rx");
1096 char *lan3_tx = nvram_safe_get("dr_lan3_tx");
1097 char *lan3_rx = nvram_safe_get("dr_lan3_rx");
1098 char *wan_tx = nvram_safe_get("dr_wan_tx");
1099 char *wan_rx = nvram_safe_get("dr_wan_rx");
1101 if ((*lan_tx == '0') && (*lan_rx == '0') &&
1102 (*lan1_tx == '0') && (*lan1_rx == '0') &&
1103 (*lan2_tx == '0') && (*lan2_rx == '0') &&
1104 (*lan3_tx == '0') && (*lan3_rx == '0') &&
1105 (*wan_tx == '0') && (*wan_rx == '0')) {
1106 return;
1109 // empty
1110 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
1111 fclose(fp);
1115 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
1116 char *lan_ifname = nvram_safe_get("lan_ifname");
1117 char *lan1_ifname = nvram_safe_get("lan1_ifname");
1118 char *lan2_ifname = nvram_safe_get("lan2_ifname");
1119 char *lan3_ifname = nvram_safe_get("lan3_ifname");
1120 char *wan_ifname = nvram_safe_get("wan_ifname");
1122 fprintf(fp, "router rip\n");
1123 if(strcmp(lan_ifname,"")!=0)
1124 fprintf(fp, "network %s\n", lan_ifname);
1125 if(strcmp(lan1_ifname,"")!=0)
1126 fprintf(fp, "network %s\n", lan1_ifname);
1127 if(strcmp(lan2_ifname,"")!=0)
1128 fprintf(fp, "network %s\n", lan2_ifname);
1129 if(strcmp(lan3_ifname,"")!=0)
1130 fprintf(fp, "network %s\n", lan3_ifname);
1131 fprintf(fp, "network %s\n", wan_ifname);
1132 fprintf(fp, "redistribute connected\n");
1133 //fprintf(fp, "redistribute static\n");
1135 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
1136 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
1138 if(strcmp(lan_ifname,"")!=0) {
1139 fprintf(fp, "interface %s\n", lan_ifname);
1140 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
1141 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
1143 if(strcmp(lan1_ifname,"")!=0) {
1144 fprintf(fp, "interface %s\n", lan1_ifname);
1145 if (*lan1_tx != '0') fprintf(fp, "ip rip send version %s\n", lan1_tx);
1146 if (*lan1_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan1_rx);
1148 if(strcmp(lan2_ifname,"")!=0) {
1149 fprintf(fp, "interface %s\n", lan2_ifname);
1150 if (*lan2_tx != '0') fprintf(fp, "ip rip send version %s\n", lan2_tx);
1151 if (*lan2_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan2_rx);
1153 if(strcmp(lan3_ifname,"")!=0) {
1154 fprintf(fp, "interface %s\n", lan3_ifname);
1155 if (*lan3_tx != '0') fprintf(fp, "ip rip send version %s\n", lan3_tx);
1156 if (*lan3_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan3_rx);
1158 fprintf(fp, "interface %s\n", wan_ifname);
1159 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
1160 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
1162 fprintf(fp, "router rip\n");
1163 if(strcmp(lan_ifname,"")!=0) {
1164 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
1165 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
1167 if(strcmp(lan1_ifname,"")!=0) {
1168 if (*lan1_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan1_ifname);
1169 if (*lan1_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan1_ifname);
1171 if(strcmp(lan2_ifname,"")!=0) {
1172 if (*lan2_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan2_ifname);
1173 if (*lan2_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan2_ifname);
1175 if(strcmp(lan3_ifname,"")!=0) {
1176 if (*lan3_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan3_ifname);
1177 if (*lan3_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan3_ifname);
1179 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
1180 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
1181 fprintf(fp, "access-list private deny any\n");
1183 //fprintf(fp, "debug rip events\n");
1184 //fprintf(fp, "log file /etc/ripd.log\n");
1185 fclose(fp);
1188 xstart("zebra", "-d");
1189 xstart("ripd", "-d");
1190 #endif
1193 void stop_zebra(void)
1195 #ifdef TCONFIG_ZEBRA
1196 if (getpid() != 1) {
1197 stop_service("zebra");
1198 return;
1201 killall("zebra", SIGTERM);
1202 killall("ripd", SIGTERM);
1204 unlink("/etc/zebra.conf");
1205 unlink("/etc/ripd.conf");
1206 #endif
1209 // -----------------------------------------------------------------------------
1211 void start_syslog(void)
1213 char *argv[16];
1214 int argc;
1215 char *nv;
1216 char *b_opt = "";
1217 char rem[256];
1218 int n;
1219 char s[64];
1220 char cfg[256];
1221 char *rot_siz = "50";
1222 char *rot_keep = "1";
1223 char *log_file_path;
1225 argv[0] = "syslogd";
1226 argc = 1;
1228 if (nvram_match("log_remote", "1")) {
1229 nv = nvram_safe_get("log_remoteip");
1230 if (*nv) {
1231 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
1232 argv[argc++] = "-R";
1233 argv[argc++] = rem;
1237 if (nvram_match("log_file", "1")) {
1238 argv[argc++] = "-L";
1240 if (strcmp(nvram_safe_get("log_file_size"), "") != 0) {
1241 rot_siz = nvram_safe_get("log_file_size");
1243 if (nvram_get_int("log_file_size") > 0) {
1244 rot_keep = nvram_safe_get("log_file_keep");
1247 // log to custom path - shibby
1248 if (nvram_match("log_file_custom", "1")) {
1249 log_file_path = nvram_safe_get("log_file_path");
1250 argv[argc++] = "-s";
1251 argv[argc++] = rot_siz;
1252 argv[argc++] = "-O";
1253 argv[argc++] = log_file_path;
1254 if (strcmp(nvram_safe_get("log_file_path"), "/var/log/messages") != 0) {
1255 remove("/var/log/messages");
1256 symlink(log_file_path, "/var/log/messages");
1259 else
1261 /* Read options: rotate_size(kb) num_backups logfilename.
1262 * Ignore these settings and use defaults if the logfile cannot be written to.
1264 if (f_read_string("/etc/syslogd.cfg", cfg, sizeof(cfg)) > 0) {
1265 if ((nv = strchr(cfg, '\n')))
1266 *nv = 0;
1268 if ((nv = strtok(cfg, " \t"))) {
1269 if (isdigit(*nv))
1270 rot_siz = nv;
1273 if ((nv = strtok(NULL, " \t")))
1274 b_opt = nv;
1276 if ((nv = strtok(NULL, " \t")) && *nv == '/') {
1277 if (f_write(nv, cfg, 0, FW_APPEND, 0) >= 0) {
1278 argv[argc++] = "-O";
1279 argv[argc++] = nv;
1281 else {
1282 rot_siz = "50";
1283 b_opt = "";
1288 if (nvram_match("log_file_custom", "0")) {
1289 argv[argc++] = "-s";
1290 argv[argc++] = rot_siz;
1291 struct stat sb;
1292 if (lstat("/var/log/messages", &sb) != -1)
1293 if (S_ISLNK(sb.st_mode))
1294 remove("/var/log/messages");
1297 if (isdigit(*b_opt)) {
1298 argv[argc++] = "-b";
1299 argv[argc++] = b_opt;
1300 } else
1301 if (nvram_get_int("log_file_size") > 0) {
1302 argv[argc++] = "-b";
1303 argv[argc++] = rot_keep;
1307 if (argc > 1) {
1308 argv[argc] = NULL;
1309 _eval(argv, NULL, 0, NULL);
1311 argv[0] = "klogd";
1312 argv[1] = NULL;
1313 _eval(argv, NULL, 0, NULL);
1315 // used to be available in syslogd -m
1316 n = nvram_get_int("log_mark");
1317 if (n > 0) {
1318 // n is in minutes
1319 if (n < 60)
1320 sprintf(rem, "*/%d * * * *", n);
1321 else if (n < 60 * 24)
1322 sprintf(rem, "0 */%d * * *", n / 60);
1323 else
1324 sprintf(rem, "0 0 */%d * *", n / (60 * 24));
1325 sprintf(s, "%s logger -p syslog.info -- -- MARK --", rem);
1326 eval("cru", "a", "syslogdmark", s);
1328 else {
1329 eval("cru", "d", "syslogdmark");
1334 void stop_syslog(void)
1336 killall("klogd", SIGTERM);
1337 killall("syslogd", SIGTERM);
1340 // -----------------------------------------------------------------------------
1342 static pid_t pid_igmp = -1;
1344 void start_igmp_proxy(void)
1346 FILE *fp;
1348 pid_igmp = -1;
1349 if (nvram_match("multicast_pass", "1")) {
1350 if (get_wan_proto() == WP_DISABLED)
1351 return;
1353 if (f_exists("/etc/igmp.alt")) {
1354 eval("igmpproxy", "/etc/igmp.alt");
1356 else if ((fp = fopen("/etc/igmp.conf", "w")) != NULL) {
1357 fprintf(fp,
1358 "quickleave\n"
1359 "phyint %s upstream\n"
1360 "\taltnet %s\n",
1361 // "phyint %s downstream ratelimit 0\n",
1362 get_wanface(),
1363 nvram_get("multicast_altnet") ? : "0.0.0.0/0");
1364 // nvram_safe_get("lan_ifname"));
1366 char lanN_ifname[] = "lanXX_ifname";
1367 char multicast_lanN[] = "multicast_lanXX";
1368 char br;
1370 for(br=0 ; br<4 ; br++) {
1371 char bridge[2] = "0";
1372 if (br!=0)
1373 bridge[0]+=br;
1374 else
1375 strcpy(bridge, "");
1377 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1378 sprintf(multicast_lanN, "multicast_lan%s", bridge);
1380 if((strcmp(nvram_safe_get(multicast_lanN),"1")==0) && (strcmp(nvram_safe_get(lanN_ifname),"")!=0)) {
1381 fprintf(fp,
1382 "phyint %s downstream ratelimit 0\n",
1383 nvram_safe_get(lanN_ifname));
1386 fclose(fp);
1387 eval("igmpproxy", "/etc/igmp.conf");
1389 else {
1390 return;
1392 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1393 pid_igmp = -2;
1398 void stop_igmp_proxy(void)
1400 pid_igmp = -1;
1401 killall_tk("igmpproxy");
1404 // -----------------------------------------------------------------------------
1406 void start_udpxy(void)
1408 if (nvram_match("udpxy_enable", "1")) {
1409 if (get_wan_proto() == WP_DISABLED)
1410 return;
1411 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") );
1415 void stop_udpxy(void)
1417 killall_tk("udpxy");
1420 // -----------------------------------------------------------------------------
1422 #ifdef TCONFIG_NOCAT
1424 static pid_t pid_splashd = -1;
1425 void start_splashd(void)
1427 pid_splashd = -1;
1428 start_nocat();
1429 if (!nvram_contains_word("debug_norestart", "splashd")) {
1430 pid_splashd = -2;
1434 void stop_splashd(void)
1436 pid_splashd = -1;
1437 stop_nocat();
1438 start_wan(BOOT);
1440 #endif
1442 // -----------------------------------------------------------------------------
1443 #ifdef TCONFIG_NGINX
1445 static pid_t pid_nginx = -1;
1446 void start_enginex(void)
1448 pid_nginx =-1;
1449 start_nginx();
1450 if (!nvram_contains_word("debug_norestart","enginex")) {
1451 pid_nginx = -2;
1455 void stop_enginex(void)
1457 pid_nginx = -1;
1458 stop_nginx();
1461 void start_nginxfastpath(void)
1463 pid_nginx =-1;
1464 start_nginxfp();
1465 if (!nvram_contains_word("debug_norestart","nginxfp")) {
1466 pid_nginx = -2;
1469 void stop_nginxfastpath(void)
1471 pid_nginx = -1;
1472 stop_nginxfp();
1474 #endif
1476 // -----------------------------------------------------------------------------
1478 void set_tz(void)
1480 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
1483 void start_ntpc(void)
1485 static char servers[32];
1487 set_tz();
1489 stop_ntpc();
1491 if (nvram_get_int("ntp_updates") >= 0) {
1492 strcpy(servers, nvram_safe_get("ntp_server"));
1493 xstart("ntpclient", "-h", servers, "-i", "3", "-l", "-s");
1497 void stop_ntpc(void)
1499 killall("ntpclient", SIGTERM);
1502 // -----------------------------------------------------------------------------
1504 static void stop_rstats(void)
1506 int n, m;
1507 int pid;
1508 int pidz;
1509 int ppidz;
1510 int w = 0;
1512 n = 60;
1513 m = 15;
1514 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
1515 w = 1;
1516 pidz = pidof("gzip");
1517 if (pidz < 1) pidz = pidof("cp");
1518 ppidz = ppid(ppid(pidz));
1519 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1520 syslog(LOG_DEBUG, "rstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1521 --m;
1522 } else {
1523 kill(pid, SIGTERM);
1525 sleep(1);
1527 if ((w == 1) && (n > 0))
1528 syslog(LOG_DEBUG, "rstats stopped.\n");
1531 static void start_rstats(int new)
1533 if (nvram_match("rstats_enable", "1")) {
1534 stop_rstats();
1535 if (new) {
1536 syslog(LOG_DEBUG, "starting rstats (new datafile).\n");
1537 xstart("rstats", "--new");
1538 } else {
1539 syslog(LOG_DEBUG, "starting rstats.\n");
1540 xstart("rstats");
1545 static void stop_cstats(void)
1547 int n, m;
1548 int pid;
1549 int pidz;
1550 int ppidz;
1551 int w = 0;
1553 n = 60;
1554 m = 15;
1555 while ((n-- > 0) && ((pid = pidof("cstats")) > 0)) {
1556 w = 1;
1557 pidz = pidof("gzip");
1558 if (pidz < 1) pidz = pidof("cp");
1559 ppidz = ppid(ppid(pidz));
1560 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1561 syslog(LOG_DEBUG, "cstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1562 --m;
1563 } else {
1564 kill(pid, SIGTERM);
1566 sleep(1);
1568 if ((w == 1) && (n > 0))
1569 syslog(LOG_DEBUG, "cstats stopped.\n");
1572 static void start_cstats(int new)
1574 if (nvram_match("cstats_enable", "1")) {
1575 stop_cstats();
1576 if (new) {
1577 syslog(LOG_DEBUG, "starting cstats (new datafile).\n");
1578 xstart("cstats", "--new");
1579 } else {
1580 syslog(LOG_DEBUG, "starting cstats.\n");
1581 xstart("cstats");
1586 // -----------------------------------------------------------------------------
1588 // !!TB - FTP Server
1590 #ifdef TCONFIG_FTP
1591 static char *get_full_storage_path(char *val)
1593 static char buf[128];
1594 int len;
1596 if (val[0] == '/')
1597 len = sprintf(buf, "%s", val);
1598 else
1599 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
1601 if (len > 1 && buf[len - 1] == '/')
1602 buf[len - 1] = 0;
1604 return buf;
1607 static char *nvram_storage_path(char *var)
1609 char *val = nvram_safe_get(var);
1610 return get_full_storage_path(val);
1613 char vsftpd_conf[] = "/etc/vsftpd.conf";
1614 char vsftpd_users[] = "/etc/vsftpd.users";
1615 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
1617 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1619 static void start_ftpd(void)
1621 char tmp[256];
1622 FILE *fp, *f;
1623 char *buf;
1624 char *p, *q;
1625 char *user, *pass, *rights, *root_dir;
1626 int i;
1628 if (getpid() != 1) {
1629 start_service("ftpd");
1630 return;
1633 if (!nvram_get_int("ftp_enable")) return;
1635 mkdir_if_none(vsftpd_users);
1636 mkdir_if_none("/var/run/vsftpd");
1638 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
1639 return;
1641 if (nvram_get_int("ftp_super"))
1643 /* rights */
1644 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
1645 if ((f = fopen(tmp, "w")))
1647 fprintf(f,
1648 "dirlist_enable=yes\n"
1649 "write_enable=yes\n"
1650 "download_enable=yes\n");
1651 fclose(f);
1655 #ifdef TCONFIG_SAMBASRV
1656 if (nvram_match("smbd_cset", "utf8"))
1657 fprintf(fp, "utf8=yes\n");
1658 #endif
1660 if (nvram_invmatch("ftp_anonymous", "0"))
1662 fprintf(fp,
1663 "anon_allow_writable_root=yes\n"
1664 "anon_world_readable_only=no\n"
1665 "anon_umask=022\n");
1667 /* rights */
1668 sprintf(tmp, "%s/ftp", vsftpd_users);
1669 if ((f = fopen(tmp, "w")))
1671 if (nvram_match("ftp_dirlist", "0"))
1672 fprintf(f, "dirlist_enable=yes\n");
1673 if (nvram_match("ftp_anonymous", "1") ||
1674 nvram_match("ftp_anonymous", "3"))
1675 fprintf(f, "write_enable=yes\n");
1676 if (nvram_match("ftp_anonymous", "1") ||
1677 nvram_match("ftp_anonymous", "2"))
1678 fprintf(f, "download_enable=yes\n");
1679 fclose(f);
1681 if (nvram_match("ftp_anonymous", "1") ||
1682 nvram_match("ftp_anonymous", "3"))
1683 fprintf(fp,
1684 "anon_upload_enable=yes\n"
1685 "anon_mkdir_write_enable=yes\n"
1686 "anon_other_write_enable=yes\n");
1687 } else {
1688 fprintf(fp, "anonymous_enable=no\n");
1691 fprintf(fp,
1692 "dirmessage_enable=yes\n"
1693 "download_enable=no\n"
1694 "dirlist_enable=no\n"
1695 "hide_ids=yes\n"
1696 "syslog_enable=yes\n"
1697 "local_enable=yes\n"
1698 "local_umask=022\n"
1699 "chmod_enable=no\n"
1700 "chroot_local_user=yes\n"
1701 "check_shell=no\n"
1702 "log_ftp_protocol=%s\n"
1703 "user_config_dir=%s\n"
1704 "passwd_file=%s\n"
1705 "listen%s=yes\n"
1706 "listen_port=%s\n"
1707 "background=yes\n"
1708 "isolate=no\n"
1709 "max_clients=%d\n"
1710 "max_per_ip=%d\n"
1711 "max_login_fails=1\n"
1712 "idle_session_timeout=%s\n"
1713 "use_sendfile=no\n"
1714 "anon_max_rate=%d\n"
1715 "local_max_rate=%d\n"
1716 "%s\n",
1717 nvram_get_int("log_ftp") ? "yes" : "no",
1718 vsftpd_users, vsftpd_passwd,
1719 #ifdef TCONFIG_IPV6
1720 ipv6_enabled() ? "_ipv6" : "",
1721 #else
1723 #endif
1724 nvram_get("ftp_port") ? : "21",
1725 nvram_get_int("ftp_max"),
1726 nvram_get_int("ftp_ipmax"),
1727 nvram_get("ftp_staytimeout") ? : "300",
1728 nvram_get_int("ftp_anonrate") * 1024,
1729 nvram_get_int("ftp_rate") * 1024,
1730 nvram_safe_get("ftp_custom"));
1732 fclose(fp);
1734 /* prepare passwd file and default users */
1735 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
1736 return;
1738 if (((user = nvram_get("http_username")) == NULL) || (*user == 0)) user = "admin";
1739 if (((pass = nvram_get("http_passwd")) == NULL) || (*pass == 0)) pass = "admin";
1741 fprintf(fp, /* anonymous, admin, nobody */
1742 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1743 "%s:%s:0:0:root:/:/sbin/nologin\n"
1744 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1745 nvram_storage_path("ftp_anonroot"), user,
1746 nvram_get_int("ftp_super") ? crypt(pass, "$1$") : "x",
1747 MOUNT_ROOT);
1749 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
1752 username<password<rights[<root_dir>]
1753 rights:
1754 Read/Write
1755 Read Only
1756 View Only
1757 Private
1759 p = buf;
1760 while ((q = strsep(&p, ">")) != NULL) {
1761 i = vstrsep(q, "<", &user, &pass, &rights, &root_dir);
1762 if (i < 3 || i > 4) continue;
1763 if (!user || !pass) continue;
1765 if (i == 3 || !root_dir || !(*root_dir))
1767 root_dir = nvram_safe_get("ftp_pubroot");
1769 /* directory */
1770 if (strncmp(rights, "Private", 7) == 0)
1772 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
1773 mkdir_if_none(tmp);
1775 else
1776 sprintf(tmp, "%s", get_full_storage_path(root_dir));
1778 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1779 user, crypt(pass, "$1$"), user, tmp);
1781 /* rights */
1782 sprintf(tmp, "%s/%s", vsftpd_users, user);
1783 if ((f = fopen(tmp, "w")))
1785 tmp[0] = 0;
1786 if (nvram_invmatch("ftp_dirlist", "1"))
1787 strcat(tmp, "dirlist_enable=yes\n");
1788 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
1789 strcat(tmp, "download_enable=yes\n");
1790 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
1791 strcat(tmp, "write_enable=yes\n");
1793 fputs(tmp, f);
1794 fclose(f);
1797 free(buf);
1800 fclose(fp);
1801 killall("vsftpd", SIGHUP);
1803 /* start vsftpd if it's not already running */
1804 if (pidof("vsftpd") <= 0)
1805 xstart("vsftpd");
1808 static void stop_ftpd(void)
1810 if (getpid() != 1) {
1811 stop_service("ftpd");
1812 return;
1815 killall_tk("vsftpd");
1816 unlink(vsftpd_passwd);
1817 unlink(vsftpd_conf);
1818 eval("rm", "-rf", vsftpd_users);
1820 #endif // TCONFIG_FTP
1822 // -----------------------------------------------------------------------------
1824 // !!TB - Samba
1826 #ifdef TCONFIG_SAMBASRV
1827 static void kill_samba(int sig)
1829 if (sig == SIGTERM) {
1830 killall_tk("smbd");
1831 killall_tk("nmbd");
1833 else {
1834 killall("smbd", sig);
1835 killall("nmbd", sig);
1839 #if 0
1840 #ifdef TCONFIG_BCMARM
1841 extern void del_samba_rules(void);
1842 extern void add_samba_rules(void);
1843 #endif
1844 #endif
1846 static void start_samba(void)
1848 FILE *fp;
1849 DIR *dir = NULL;
1850 struct dirent *dp;
1851 char nlsmod[15];
1852 int mode;
1853 char *nv;
1854 #ifdef TCONFIG_BCMARM
1855 int cpu_num = sysconf(_SC_NPROCESSORS_CONF);
1856 int taskset_ret = -1;
1857 #endif
1859 if (getpid() != 1) {
1860 start_service("smbd");
1861 return;
1864 mode = nvram_get_int("smbd_enable");
1865 if (!mode || !nvram_invmatch("lan_hostname", ""))
1866 return;
1868 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
1869 return;
1871 #ifdef TCONFIG_GROCTRL
1872 enable_gro(2);
1873 #endif
1875 fprintf(fp, "[global]\n"
1876 " interfaces = %s\n"
1877 " bind interfaces only = yes\n"
1878 " workgroup = %s\n"
1879 " netbios name = %s\n"
1880 " server string = %s\n"
1881 " guest account = nobody\n"
1882 " security = user\n"
1883 " %s\n"
1884 " guest ok = %s\n"
1885 " guest only = no\n"
1886 " browseable = yes\n"
1887 " syslog only = yes\n"
1888 " timestamp logs = no\n"
1889 " syslog = 1\n"
1890 " encrypt passwords = yes\n"
1891 " preserve case = yes\n"
1892 " short preserve case = yes\n",
1893 nvram_safe_get("lan_ifname"),
1894 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1895 nvram_safe_get("lan_hostname"),
1896 nvram_get("router_name") ? : "Tomato",
1897 mode == 2 ? "" : "map to guest = Bad User",
1898 mode == 2 ? "no" : "yes" // guest ok
1901 if (nvram_get_int("smbd_wins")) {
1902 nv = nvram_safe_get("wan_wins");
1903 if ((*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
1904 fprintf(fp, " wins support = yes\n");
1908 if (nvram_get_int("smbd_master")) {
1909 fprintf(fp,
1910 " domain master = yes\n"
1911 " local master = yes\n"
1912 " preferred master = yes\n"
1913 " os level = 65\n");
1916 nv = nvram_safe_get("smbd_cpage");
1917 if (*nv) {
1918 #ifndef TCONFIG_SAMBA3
1919 fprintf(fp, " client code page = %s\n", nv);
1920 #endif
1921 sprintf(nlsmod, "nls_cp%s", nv);
1923 nv = nvram_safe_get("smbd_nlsmod");
1924 if ((*nv) && (strcmp(nv, nlsmod) != 0))
1925 modprobe_r(nv);
1927 modprobe(nlsmod);
1928 nvram_set("smbd_nlsmod", nlsmod);
1931 #ifndef TCONFIG_SAMBA3
1932 if (nvram_match("smbd_cset", "utf8"))
1933 fprintf(fp, " coding system = utf8\n");
1934 else if (nvram_invmatch("smbd_cset", ""))
1935 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1936 #endif
1938 nv = nvram_safe_get("smbd_custom");
1939 /* add socket options unless overriden by the user */
1940 if (strstr(nv, "socket options") == NULL) {
1941 fprintf(fp, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1943 fprintf(fp, "%s\n\n", nv);
1945 /* configure shares */
1947 char *buf;
1948 char *p, *q;
1949 char *name, *path, *comment, *writeable, *hidden;
1950 int cnt = 0;
1952 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1954 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1956 p = buf;
1957 while ((q = strsep(&p, ">")) != NULL) {
1958 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1959 if (!path || !name) continue;
1961 /* share name */
1962 fprintf(fp, "\n[%s]\n", name);
1964 /* path */
1965 fprintf(fp, " path = %s\n", path);
1967 /* access level */
1968 if (!strcmp(writeable, "1"))
1969 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1970 if (!strcmp(hidden, "1"))
1971 fprintf(fp, " browseable = no\n");
1973 /* comment */
1974 if (comment)
1975 fprintf(fp, " comment = %s\n", comment);
1977 cnt++;
1979 free(buf);
1982 /* Share every mountpoint below MOUNT_ROOT */
1983 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1984 while ((dp = readdir(dir))) {
1985 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1987 /* Only if is a directory and is mounted */
1988 if (!dir_is_mountpoint(MOUNT_ROOT, dp->d_name))
1989 continue;
1991 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1992 fprintf(fp, "\n[%s]\n path = %s/%s\n comment = %s\n",
1993 dp->d_name, MOUNT_ROOT, dp->d_name, dp->d_name);
1994 if (nvram_match("smbd_autoshare", "3")) // Hidden
1995 fprintf(fp, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1996 dp->d_name, MOUNT_ROOT, dp->d_name);
1997 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1998 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
2000 cnt++;
2004 if (dir) closedir(dir);
2006 if (cnt == 0) {
2007 /* by default share MOUNT_ROOT as read-only */
2008 fprintf(fp, "\n[share]\n"
2009 " path = %s\n"
2010 " writable = no\n",
2011 MOUNT_ROOT);
2014 fclose(fp);
2016 mkdir_if_none("/var/run/samba");
2017 mkdir_if_none("/etc/samba");
2019 /* write smbpasswd */
2020 #ifdef TCONFIG_SAMBA3
2021 eval("smbpasswd", "nobody", "\"\"");
2022 #else
2023 eval("smbpasswd", "-a", "nobody", "\"\"");
2024 #endif
2025 if (mode == 2) {
2026 char *smbd_user;
2027 if (((smbd_user = nvram_get("smbd_user")) == NULL) || (*smbd_user == 0) || !strcmp(smbd_user, "root"))
2028 smbd_user = "nas";
2029 #ifdef TCONFIG_SAMBA3
2030 eval("smbpasswd", smbd_user, nvram_safe_get("smbd_passwd"));
2031 #else
2032 eval("smbpasswd", "-a", smbd_user, nvram_safe_get("smbd_passwd"));
2033 #endif
2036 kill_samba(SIGHUP);
2037 int ret1 = 0, ret2 = 0;
2038 /* start samba if it's not already running */
2039 if (pidof("nmbd") <= 0)
2040 ret1 = xstart("nmbd", "-D");
2041 if (pidof("smbd") <= 0) {
2042 #ifdef TCONFIG_BCMARM
2043 #ifdef TCONFIG_BCMSMP
2044 if (cpu_num > 1)
2045 taskset_ret = cpu_eval(NULL, "1", "ionice", "-c1", "-n0", "smbd", "-D");
2046 else
2047 taskset_ret = eval("ionice", "-c1", "-n0", "smbd", "-D");
2049 if (taskset_ret != 0)
2050 #endif
2051 #endif
2052 ret2 = xstart("smbd", "-D");
2055 if (ret1 || ret2) kill_samba(SIGTERM);
2058 static void stop_samba(void)
2060 if (getpid() != 1) {
2061 stop_service("smbd");
2062 return;
2065 kill_samba(SIGTERM);
2066 /* clean up */
2067 unlink("/var/log/smb");
2068 unlink("/var/log/nmb");
2069 eval("rm", "-rf", "/var/run/samba");
2071 #ifdef TCONFIG_GROCTRL
2072 enable_gro(0);
2073 #endif
2076 #endif // TCONFIG_SAMBASRV
2078 #ifdef TCONFIG_GROCTRL
2079 void enable_gro(int interval)
2081 char *argv[3] = {"echo", "", NULL};
2082 char lan_ifname[32], *lan_ifnames, *next;
2083 char path[64] = {0};
2084 char parm[32] = {0};
2086 if(nvram_get_int("gro_disable"))
2087 return;
2089 /* enabled gso on vlan interface */
2090 lan_ifnames = nvram_safe_get("lan_ifnames");
2091 foreach(lan_ifname, lan_ifnames, next) {
2092 if (!strncmp(lan_ifname, "vlan", 4)) {
2093 sprintf(path, ">>/proc/net/vlan/%s", lan_ifname);
2094 sprintf(parm, "-gro %d", interval);
2095 argv[1] = parm;
2096 _eval(argv, path, 0, NULL);
2100 #endif
2102 #ifdef TCONFIG_MEDIA_SERVER
2103 #define MEDIA_SERVER_APP "minidlna"
2105 static void start_media_server(void)
2107 FILE *f;
2108 int port, pid, https;
2109 char *dbdir;
2110 char *argv[] = { MEDIA_SERVER_APP, "-f", "/etc/"MEDIA_SERVER_APP".conf", "-R", NULL };
2111 static int once = 1;
2113 if (getpid() != 1) {
2114 start_service("media");
2115 return;
2118 if (nvram_get_int("ms_sas") == 0)
2119 once = 0;
2121 if (nvram_get_int("ms_enable") != 0) {
2122 if ((!once) && (nvram_get_int("ms_rescan") == 0)) {
2123 // no forced rescan
2124 argv[3] = NULL;
2126 nvram_unset("ms_rescan");
2128 if (f_exists("/etc/"MEDIA_SERVER_APP".alt")) {
2129 argv[2] = "/etc/"MEDIA_SERVER_APP".alt";
2131 else {
2132 if ((f = fopen(argv[2], "w")) != NULL) {
2133 port = nvram_get_int("ms_port");
2134 https = nvram_get_int("https_enable");
2135 dbdir = nvram_safe_get("ms_dbdir");
2136 if (!(*dbdir)) dbdir = NULL;
2137 mkdir_if_none(dbdir ? : "/var/run/"MEDIA_SERVER_APP);
2139 fprintf(f,
2140 "network_interface=%s\n"
2141 "port=%d\n"
2142 "friendly_name=%s\n"
2143 "db_dir=%s/.db\n"
2144 "enable_tivo=%s\n"
2145 "strict_dlna=%s\n"
2146 "presentation_url=http%s://%s:%s/nas-media.asp\n"
2147 "inotify=yes\n"
2148 "notify_interval=600\n"
2149 "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"
2150 "log_dir=/var/log\n"
2151 "log_level=general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn\n"
2152 "\n",
2153 nvram_safe_get("lan_ifname"),
2154 (port < 0) || (port >= 0xffff) ? 0 : port,
2155 nvram_get("router_name") ? : "Tomato",
2156 dbdir ? : "/var/run/"MEDIA_SERVER_APP,
2157 nvram_get_int("ms_tivo") ? "yes" : "no",
2158 nvram_get_int("ms_stdlna") ? "yes" : "no",
2159 https ? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https ? "https_lanport" : "http_lanport")
2162 // media directories
2163 char *buf, *p, *q;
2164 char *path, *restrict;
2166 if ((buf = strdup(nvram_safe_get("ms_dirs"))) != NULL) {
2167 /* path<restrict[A|V|P|] */
2169 p = buf;
2170 while ((q = strsep(&p, ">")) != NULL) {
2171 if (vstrsep(q, "<", &path, &restrict) < 1 || !path || !(*path))
2172 continue;
2173 fprintf(f, "media_dir=%s%s%s\n",
2174 restrict ? : "", (restrict && *restrict) ? "," : "", path);
2176 free(buf);
2179 fclose(f);
2183 /* start media server if it's not already running */
2184 if (pidof(MEDIA_SERVER_APP) <= 0) {
2185 if ((_eval(argv, NULL, 0, &pid) == 0) && (once)) {
2186 /* If we started the media server successfully, wait 1 sec
2187 * to let it die if it can't open the database file.
2188 * If it's still alive after that, assume it's running and
2189 * disable forced once-after-reboot rescan.
2191 sleep(1);
2192 if (pidof(MEDIA_SERVER_APP) > 0)
2193 once = 0;
2199 static void stop_media_server(void)
2201 if (getpid() != 1) {
2202 stop_service("media");
2203 return;
2206 killall_tk(MEDIA_SERVER_APP);
2208 #endif // TCONFIG_MEDIA_SERVER
2210 #ifdef TCONFIG_USB
2211 static void start_nas_services(void)
2213 if (getpid() != 1) {
2214 start_service("usbapps");
2215 return;
2218 #ifdef TCONFIG_SAMBASRV
2219 start_samba();
2220 #endif
2221 #ifdef TCONFIG_FTP
2222 start_ftpd();
2223 #endif
2224 #ifdef TCONFIG_MEDIA_SERVER
2225 start_media_server();
2226 #endif
2229 static void stop_nas_services(void)
2231 if (getpid() != 1) {
2232 stop_service("usbapps");
2233 return;
2236 #ifdef TCONFIG_MEDIA_SERVER
2237 stop_media_server();
2238 #endif
2239 #ifdef TCONFIG_FTP
2240 stop_ftpd();
2241 #endif
2242 #ifdef TCONFIG_SAMBASRV
2243 stop_samba();
2244 #endif
2247 void restart_nas_services(int stop, int start)
2249 int fd = file_lock("usb");
2250 /* restart all NAS applications */
2251 if (stop)
2252 stop_nas_services();
2253 if (start)
2254 start_nas_services();
2255 file_unlock(fd);
2257 #endif // TCONFIG_USB
2259 // -----------------------------------------------------------------------------
2261 /* -1 = Don't check for this program, it is not expected to be running.
2262 * Other = This program has been started and should be kept running. If no
2263 * process with the name is running, call func to restart it.
2264 * Note: At startup, dnsmasq forks a short-lived child which forks a
2265 * long-lived (grand)child. The parents terminate.
2266 * Many daemons use this technique.
2268 static void _check(pid_t pid, const char *name, void (*func)(void))
2270 if (pid == -1) return;
2272 if (pidof(name) > 0) return;
2274 syslog(LOG_DEBUG, "%s terminated unexpectedly, restarting.\n", name);
2275 func();
2277 // Force recheck in 500 msec
2278 setitimer(ITIMER_REAL, &pop_tv, NULL);
2281 void check_services(void)
2283 TRACE_PT("keep alive\n");
2285 // Periodically reap any zombies
2286 setitimer(ITIMER_REAL, &zombie_tv, NULL);
2288 #ifdef LINUX26
2289 _check(pid_hotplug2, "hotplug2", start_hotplug2);
2290 #endif
2291 _check(pid_dnsmasq, "dnsmasq", start_dnsmasq);
2292 _check(pid_crond, "crond", start_cron);
2293 _check(pid_igmp, "igmpproxy", start_igmp_proxy);
2295 //#ifdef TCONFIG_NOCAT
2296 // if (nvram_get_int("NC_enable"))
2297 // _check(&pid_splashd, "splashd", start_splashd);
2298 //#endif
2302 // -----------------------------------------------------------------------------
2304 void start_services(void)
2306 static int once = 1;
2308 if (once) {
2309 once = 0;
2311 if (nvram_get_int("telnetd_eas")) start_telnetd();
2312 if (nvram_get_int("sshd_eas")) start_sshd();
2315 // start_syslog();
2316 start_nas();
2317 start_zebra();
2318 #ifdef TCONFIG_SDHC
2319 start_mmc();
2320 #endif
2321 start_dnsmasq();
2322 start_cifs();
2323 start_httpd();
2324 #ifdef TCONFIG_NGINX
2325 start_enginex();
2326 start_mysql();
2327 #endif
2328 start_cron();
2329 // start_upnp();
2330 start_rstats(0);
2331 start_cstats(0);
2332 start_sched();
2333 #ifdef TCONFIG_PPTPD
2334 start_pptpd();
2335 #endif
2336 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
2338 #ifdef TCONFIG_SNMP
2339 start_snmp();
2340 #endif
2342 #ifdef TCONFIG_TOR
2343 start_tor();
2344 #endif
2346 #ifdef TCONFIG_BT
2347 start_bittorrent();
2348 #endif
2350 #ifdef TCONFIG_NOCAT
2351 start_splashd();
2352 #endif
2354 #ifdef TCONFIG_NFS
2355 start_nfs();
2356 #endif
2358 if (get_model() == MODEL_R7000) {
2359 //enable WAN port led
2360 system("/usr/sbin/et robowr 0x0 0x10 0x3000");
2361 system("/usr/sbin/et robowr 0x0 0x12 0x78");
2362 system("/usr/sbin/et robowr 0x0 0x14 0x01");
2363 system("gpio disable 9");
2367 void stop_services(void)
2369 clear_resolv();
2371 #ifdef TCONFIG_BT
2372 stop_bittorrent();
2373 #endif
2375 #ifdef TCONFIG_NOCAT
2376 stop_splashd();
2377 #endif
2379 #ifdef TCONFIG_SNMP
2380 stop_snmp();
2381 #endif
2383 #ifdef TCONFIG_TOR
2384 stop_tor();
2385 #endif
2387 #ifdef TCONFIG_NFS
2388 stop_nfs();
2389 #endif
2390 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2391 #ifdef TCONFIG_PPTPD
2392 stop_pptpd();
2393 #endif
2394 stop_sched();
2395 stop_rstats();
2396 stop_cstats();
2397 // stop_upnp();
2398 stop_cron();
2399 stop_httpd();
2400 #ifdef TCONFIG_NGINX
2401 stop_mysql();
2402 stop_enginex();
2403 #endif
2404 #ifdef TCONFIG_SDHC
2405 stop_mmc();
2406 #endif
2407 stop_cifs();
2408 stop_dnsmasq();
2409 stop_zebra();
2410 stop_nas();
2411 // stop_syslog();
2414 // -----------------------------------------------------------------------------
2416 /* nvram "action_service" is: "service-action[-modifier]"
2417 * action is something like "stop" or "start" or "restart"
2418 * optional modifier is "c" for the "service" command-line command
2420 void exec_service(void)
2422 const int A_START = 1;
2423 const int A_STOP = 2;
2424 const int A_RESTART = 1|2;
2425 char buffer[128];
2426 char *service;
2427 char *act;
2428 char *next;
2429 char *modifier;
2430 int action, user;
2431 int i;
2433 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
2434 next = buffer;
2436 TOP:
2437 act = strsep(&next, ",");
2438 service = strsep(&act, "-");
2439 if (act == NULL) {
2440 next = NULL;
2441 goto CLEAR;
2443 modifier = act;
2444 strsep(&modifier, "-");
2446 TRACE_PT("service=%s action=%s modifier=%s\n", service, act, modifier ? : "");
2448 if (strcmp(act, "start") == 0) action = A_START;
2449 else if (strcmp(act, "stop") == 0) action = A_STOP;
2450 else if (strcmp(act, "restart") == 0) action = A_RESTART;
2451 else action = 0;
2452 user = (modifier != NULL && *modifier == 'c');
2454 if (strcmp(service, "dhcpc") == 0) {
2455 if (action & A_STOP) stop_dhcpc();
2456 if (action & A_START) start_dhcpc();
2457 goto CLEAR;
2460 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
2461 if (action & A_STOP) stop_dnsmasq();
2462 if (action & A_START) {
2463 dns_to_resolv();
2464 start_dnsmasq();
2466 goto CLEAR;
2469 if (strcmp(service, "firewall") == 0) {
2470 if (action & A_STOP) {
2471 stop_firewall();
2472 stop_igmp_proxy();
2473 stop_udpxy();
2475 if (action & A_START) {
2476 start_firewall();
2477 start_igmp_proxy();
2478 start_udpxy();
2480 goto CLEAR;
2483 if (strcmp(service, "restrict") == 0) {
2484 if (action & A_STOP) {
2485 stop_firewall();
2487 if (action & A_START) {
2488 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
2490 start_firewall();
2492 // if radio was disabled by access restriction, but no rule is handling it now, enable it
2493 if (i == 1) {
2494 if (nvram_get_int("rrules_radio") < 0) {
2495 eval("radio", "on");
2499 goto CLEAR;
2502 if (strcmp(service, "arpbind") == 0) {
2503 if (action & A_STOP) stop_arpbind();
2504 if (action & A_START) start_arpbind();
2505 goto CLEAR;
2508 if (strcmp(service, "qos") == 0) {
2509 if (action & A_STOP) {
2510 stop_qos();
2512 stop_firewall(); start_firewall(); // always restarted
2513 if (action & A_START) {
2514 start_qos();
2515 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
2517 goto CLEAR;
2520 if (strcmp(service, "qoslimit") == 0) {
2521 if (action & A_STOP) {
2522 new_qoslimit_stop();
2524 #ifdef TCONFIG_NOCAT
2525 stop_splashd();
2526 #endif
2527 stop_firewall(); start_firewall(); // always restarted
2528 if (action & A_START) {
2529 new_qoslimit_start();
2531 #ifdef TCONFIG_NOCAT
2532 start_splashd();
2533 #endif
2534 goto CLEAR;
2537 if (strcmp(service, "upnp") == 0) {
2538 if (action & A_STOP) {
2539 stop_upnp();
2541 stop_firewall(); start_firewall(); // always restarted
2542 if (action & A_START) {
2543 start_upnp();
2545 goto CLEAR;
2548 if (strcmp(service, "telnetd") == 0) {
2549 if (action & A_STOP) stop_telnetd();
2550 if (action & A_START) start_telnetd();
2551 goto CLEAR;
2554 if (strcmp(service, "sshd") == 0) {
2555 if (action & A_STOP) stop_sshd();
2556 if (action & A_START) start_sshd();
2557 goto CLEAR;
2560 if (strcmp(service, "httpd") == 0) {
2561 if (action & A_STOP) stop_httpd();
2562 if (action & A_START) start_httpd();
2563 goto CLEAR;
2566 #ifdef TCONFIG_IPV6
2567 if (strcmp(service, "ipv6") == 0) {
2568 if (action & A_STOP) {
2569 stop_dnsmasq();
2570 stop_ipv6();
2572 if (action & A_START) {
2573 start_ipv6();
2574 start_dnsmasq();
2576 goto CLEAR;
2579 if (strncmp(service, "dhcp6", 5) == 0) {
2580 if (action & A_STOP) {
2581 stop_dhcp6c();
2583 if (action & A_START) {
2584 start_dhcp6c();
2586 goto CLEAR;
2588 #endif
2590 if (strcmp(service, "admin") == 0) {
2591 if (action & A_STOP) {
2592 stop_sshd();
2593 stop_telnetd();
2594 stop_httpd();
2596 stop_firewall(); start_firewall(); // always restarted
2597 if (action & A_START) {
2598 start_httpd();
2599 create_passwd();
2600 if (nvram_match("telnetd_eas", "1")) start_telnetd();
2601 if (nvram_match("sshd_eas", "1")) start_sshd();
2603 goto CLEAR;
2606 if (strcmp(service, "ddns") == 0) {
2607 if (action & A_STOP) stop_ddns();
2608 if (action & A_START) start_ddns();
2609 goto CLEAR;
2612 if (strcmp(service, "ntpc") == 0) {
2613 if (action & A_STOP) stop_ntpc();
2614 if (action & A_START) start_ntpc();
2615 goto CLEAR;
2618 if (strcmp(service, "logging") == 0) {
2619 if (action & A_STOP) {
2620 stop_syslog();
2622 if (action & A_START) {
2623 start_syslog();
2625 if (!user) {
2626 // always restarted except from "service" command
2627 stop_cron(); start_cron();
2628 stop_firewall(); start_firewall();
2630 goto CLEAR;
2633 if (strcmp(service, "crond") == 0) {
2634 if (action & A_STOP) {
2635 stop_cron();
2637 if (action & A_START) {
2638 start_cron();
2640 goto CLEAR;
2643 #ifdef LINUX26
2644 if (strncmp(service, "hotplug", 7) == 0) {
2645 if (action & A_STOP) {
2646 stop_hotplug2();
2648 if (action & A_START) {
2649 start_hotplug2(1);
2651 goto CLEAR;
2653 #endif
2655 if (strcmp(service, "upgrade") == 0) {
2656 if (action & A_START) {
2657 #if TOMATO_SL
2658 stop_usbevent();
2659 stop_smbd();
2660 #endif
2661 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2662 stop_jffs2();
2663 // stop_cifs();
2664 stop_zebra();
2665 stop_cron();
2666 stop_ntpc();
2667 stop_upnp();
2668 // stop_dhcpc();
2669 killall("rstats", SIGTERM);
2670 killall("cstats", SIGTERM);
2671 killall("buttons", SIGTERM);
2672 stop_syslog();
2673 remove_storage_main(1); // !!TB - USB Support
2674 stop_usb(); // !!TB - USB Support
2676 goto CLEAR;
2679 #ifdef TCONFIG_CIFS
2680 if (strcmp(service, "cifs") == 0) {
2681 if (action & A_STOP) stop_cifs();
2682 if (action & A_START) start_cifs();
2683 goto CLEAR;
2685 #endif
2687 #ifdef TCONFIG_JFFS2
2688 if (strncmp(service, "jffs", 4) == 0) {
2689 if (action & A_STOP) stop_jffs2();
2690 if (action & A_START) start_jffs2();
2691 goto CLEAR;
2693 #endif
2695 if (strcmp(service, "zebra") == 0) {
2696 if (action & A_STOP) stop_zebra();
2697 if (action & A_START) start_zebra();
2698 goto CLEAR;
2701 #ifdef TCONFIG_SDHC
2702 if (strcmp(service, "mmc") == 0) {
2703 if (action & A_STOP) stop_mmc();
2704 if (action & A_START) start_mmc();
2705 goto CLEAR;
2707 #endif
2709 if (strcmp(service, "routing") == 0) {
2710 if (action & A_STOP) {
2711 stop_zebra();
2712 do_static_routes(0); // remove old '_saved'
2713 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2714 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2715 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), "0");
2716 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2717 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), "0");
2718 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2719 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), "0");
2721 stop_firewall();
2722 start_firewall();
2723 if (action & A_START) {
2724 do_static_routes(1); // add new
2725 start_zebra();
2726 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2727 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2728 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), nvram_safe_get("lan1_stp"));
2729 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2730 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), nvram_safe_get("lan2_stp"));
2731 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2732 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), nvram_safe_get("lan3_stp"));
2734 goto CLEAR;
2737 if (strcmp(service, "ctnf") == 0) {
2738 if (action & A_START) {
2739 setup_conntrack();
2740 stop_firewall();
2741 start_firewall();
2743 goto CLEAR;
2746 if (strcmp(service, "wan") == 0) {
2747 if (action & A_STOP) {
2748 stop_wan();
2751 if (action & A_START) {
2752 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2753 start_wan(BOOT);
2754 sleep(2);
2755 force_to_dial();
2757 goto CLEAR;
2760 if (strcmp(service, "net") == 0) {
2761 if (action & A_STOP) {
2762 #ifdef TCONFIG_USB
2763 stop_nas_services();
2764 #endif
2765 stop_httpd();
2766 stop_dnsmasq();
2767 stop_nas();
2768 stop_wan();
2769 stop_arpbind();
2770 stop_lan();
2771 stop_vlan();
2773 if (action & A_START) {
2774 start_vlan();
2775 start_lan();
2776 start_arpbind();
2777 start_wan(BOOT);
2778 start_nas();
2779 start_dnsmasq();
2780 start_httpd();
2781 start_wl();
2782 #ifdef TCONFIG_USB
2783 start_nas_services();
2784 #endif
2786 goto CLEAR;
2789 if (strcmp(service, "wireless") == 0) {
2790 if(action & A_STOP) {
2791 stop_wireless();
2793 if(action & A_START) {
2794 start_wireless();
2796 goto CLEAR;
2799 if (strcmp(service, "wl") == 0) {
2800 if(action & A_STOP) {
2801 stop_wireless();
2802 unload_wl();
2804 if(action & A_START) {
2805 load_wl();
2806 start_wireless();
2807 stop_wireless();
2808 start_wireless();
2810 goto CLEAR;
2813 if (strcmp(service, "nas") == 0) {
2814 if (action & A_STOP) {
2815 stop_nas();
2817 if (action & A_START) {
2818 start_nas();
2819 start_wl();
2821 goto CLEAR;
2824 if (strcmp(service, "rstats") == 0) {
2825 if (action & A_STOP) stop_rstats();
2826 if (action & A_START) start_rstats(0);
2827 goto CLEAR;
2830 if (strcmp(service, "rstatsnew") == 0) {
2831 if (action & A_STOP) stop_rstats();
2832 if (action & A_START) start_rstats(1);
2833 goto CLEAR;
2836 if (strcmp(service, "cstats") == 0) {
2837 if (action & A_STOP) stop_cstats();
2838 if (action & A_START) start_cstats(0);
2839 goto CLEAR;
2842 if (strcmp(service, "cstatsnew") == 0) {
2843 if (action & A_STOP) stop_cstats();
2844 if (action & A_START) start_cstats(1);
2845 goto CLEAR;
2848 if (strcmp(service, "sched") == 0) {
2849 if (action & A_STOP) stop_sched();
2850 if (action & A_START) start_sched();
2851 goto CLEAR;
2854 #ifdef TCONFIG_BT
2855 if (strcmp(service, "bittorrent") == 0) {
2856 if (action & A_STOP) {
2857 stop_bittorrent();
2859 stop_firewall(); start_firewall(); // always restarted
2860 if (action & A_START) {
2861 start_bittorrent();
2863 goto CLEAR;
2865 #endif
2867 #ifdef TCONFIG_NFS
2868 if (strcmp(service, "nfs") == 0) {
2869 if (action & A_STOP) stop_nfs();
2870 if (action & A_START) start_nfs();
2871 goto CLEAR;
2873 #endif
2875 #ifdef TCONFIG_SNMP
2876 if (strcmp(service, "snmp") == 0) {
2877 if (action & A_STOP) stop_snmp();
2878 if (action & A_START) start_snmp();
2879 goto CLEAR;
2881 #endif
2883 #ifdef TCONFIG_TOR
2884 if (strcmp(service, "tor") == 0) {
2885 if (action & A_STOP) stop_tor();
2887 stop_firewall(); start_firewall(); // always restarted
2889 if (action & A_START) start_tor();
2890 goto CLEAR;
2892 #endif
2894 #ifdef TCONFIG_UPS
2895 if (strcmp(service, "ups") == 0) {
2896 if (action & A_STOP) stop_ups();
2897 if (action & A_START) start_ups();
2898 goto CLEAR;
2900 #endif
2902 #ifdef TCONFIG_USB
2903 // !!TB - USB Support
2904 if (strcmp(service, "usb") == 0) {
2905 if (action & A_STOP) stop_usb();
2906 if (action & A_START) {
2907 start_usb();
2908 // restart Samba and ftp since they may be killed by stop_usb()
2909 restart_nas_services(0, 1);
2910 // remount all partitions by simulating hotplug event
2911 add_remove_usbhost("-1", 1);
2913 goto CLEAR;
2916 if (strcmp(service, "usbapps") == 0) {
2917 if (action & A_STOP) stop_nas_services();
2918 if (action & A_START) start_nas_services();
2919 goto CLEAR;
2921 #endif
2923 #ifdef TCONFIG_FTP
2924 // !!TB - FTP Server
2925 if (strcmp(service, "ftpd") == 0) {
2926 if (action & A_STOP) stop_ftpd();
2927 setup_conntrack();
2928 stop_firewall();
2929 start_firewall();
2930 if (action & A_START) start_ftpd();
2931 goto CLEAR;
2933 #endif
2935 #ifdef TCONFIG_MEDIA_SERVER
2936 if (strcmp(service, "media") == 0 || strcmp(service, "dlna") == 0) {
2937 if (action & A_STOP) stop_media_server();
2938 if (action & A_START) start_media_server();
2939 goto CLEAR;
2941 #endif
2943 #ifdef TCONFIG_SAMBASRV
2944 // !!TB - Samba
2945 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
2946 if (action & A_STOP) stop_samba();
2947 if (action & A_START) {
2948 create_passwd();
2949 stop_dnsmasq();
2950 start_dnsmasq();
2951 start_samba();
2953 goto CLEAR;
2955 #endif
2957 #ifdef TCONFIG_OPENVPN
2958 if (strncmp(service, "vpnclient", 9) == 0) {
2959 if (action & A_STOP) stop_vpnclient(atoi(&service[9]));
2960 if (action & A_START) start_vpnclient(atoi(&service[9]));
2961 goto CLEAR;
2964 if (strncmp(service, "vpnserver", 9) == 0) {
2965 if (action & A_STOP) stop_vpnserver(atoi(&service[9]));
2966 if (action & A_START) start_vpnserver(atoi(&service[9]));
2967 goto CLEAR;
2969 #endif
2971 #ifdef TCONFIG_TINC
2972 if (strcmp(service, "tinc") == 0) {
2973 if (action & A_STOP) stop_tinc();
2974 if (action & A_START) start_tinc();
2975 goto CLEAR;
2977 #endif
2979 #ifdef TCONFIG_NOCAT
2980 if (strcmp(service, "splashd") == 0) {
2981 if (action & A_STOP) stop_splashd();
2982 if (action & A_START) start_splashd();
2983 goto CLEAR;
2985 #endif
2987 #ifdef TCONFIG_NGINX
2988 if (strcmp(service, "enginex") == 0) {
2989 if (action & A_STOP) stop_enginex();
2990 stop_firewall(); start_firewall(); // always restarted
2991 if (action & A_START) start_enginex();
2992 goto CLEAR;
2994 if (strcmp(service, "nginxfp") == 0) {
2995 if (action & A_STOP) stop_nginxfastpath();
2996 stop_firewall(); start_firewall(); // always restarted
2997 if (action & A_START) start_nginxfastpath();
2998 goto CLEAR;
3000 if (strcmp(service, "mysql") == 0) {
3001 if (action & A_STOP) stop_mysql();
3002 stop_firewall(); start_firewall(); // always restarted
3003 if (action & A_START) start_mysql();
3004 goto CLEAR;
3006 #endif
3008 #ifdef TCONFIG_PPTPD
3009 if (strcmp(service, "pptpd") == 0) {
3010 if (action & A_STOP) stop_pptpd();
3011 if (action & A_START) start_pptpd();
3012 goto CLEAR;
3014 #endif
3016 #ifdef TCONFIG_PPTPD
3017 if (strcmp(service, "pptpclient") == 0) {
3018 if (action & A_STOP) stop_pptp_client();
3019 if (action & A_START) start_pptp_client();
3020 if (action & (A_START | A_STOP))
3022 stop_dnsmasq();
3023 dns_to_resolv();
3024 start_dnsmasq();
3025 if ((action & A_START) == 0)
3026 clear_pptp_route();
3028 goto CLEAR;
3030 #endif
3032 CLEAR:
3033 if (next) goto TOP;
3035 // some functions check action_service and must be cleared at end -- zzz
3036 nvram_set("action_service", "");
3038 // Force recheck in 500 msec
3039 setitimer(ITIMER_REAL, &pop_tv, NULL);
3042 static void do_service(const char *name, const char *action, int user)
3044 int n;
3045 char s[64];
3047 n = 150;
3048 while (!nvram_match("action_service", "")) {
3049 if (user) {
3050 putchar('*');
3051 fflush(stdout);
3053 else if (--n < 0) break;
3054 usleep(100 * 1000);
3057 snprintf(s, sizeof(s), "%s-%s%s", name, action, (user ? "-c" : ""));
3058 nvram_set("action_service", s);
3060 if (nvram_match("debug_rc_svc", "1")) {
3061 nvram_unset("debug_rc_svc");
3062 exec_service();
3063 } else {
3064 kill(1, SIGUSR1);
3067 n = 150;
3068 while (nvram_match("action_service", s)) {
3069 if (user) {
3070 putchar('.');
3071 fflush(stdout);
3073 else if (--n < 0) {
3074 break;
3076 usleep(100 * 1000);
3080 int service_main(int argc, char *argv[])
3082 if (argc != 3) usage_exit(argv[0], "<service> <action>");
3083 do_service(argv[1], argv[2], 1);
3084 printf("\nDone.\n");
3085 return 0;
3088 void start_service(const char *name)
3090 do_service(name, "start", 0);
3093 void stop_service(const char *name)
3095 do_service(name, "stop", 0);
3099 void restart_service(const char *name)
3101 do_service(name, "restart", 0);