TTB: project integration and GUI
[tomato.git] / release / src / router / rc / services.c
blobe732ce5b8bb99be41760b2bf58eaee1ebb34c9c2
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 TRACE_PT("begin\n");
91 if (getpid() != 1) {
92 start_service("dnsmasq");
93 return;
96 stop_dnsmasq();
98 if (foreach_wif(1, NULL, is_wet)) return;
100 if ((f = fopen("/etc/dnsmasq.conf", "w")) == NULL) return;
102 router_ip = nvram_safe_get("lan_ipaddr");
104 fprintf(f,
105 "pid-file=/var/run/dnsmasq.pid\n");
106 if (((nv = nvram_get("wan_domain")) != NULL) || ((nv = nvram_get("wan_get_domain")) != NULL)) {
107 if (*nv) fprintf(f, "domain=%s\n", nv);
110 // dns
111 const dns_list_t *dns = get_dns(); // this always points to a static buffer
113 if (((nv = nvram_get("dns_minport")) != NULL) && (*nv)) n = atoi(nv);
114 else n = 4096;
115 fprintf(f,
116 "resolv-file=%s\n" // the real stuff is here
117 "addn-hosts=%s\n" // directory with additional hosts files
118 "dhcp-hostsfile=%s\n" // directory with dhcp hosts files
119 "expand-hosts\n" // expand hostnames in hosts file
120 "min-port=%u\n", // min port used for random src port
121 dmresolv, dmhosts, dmdhcp, n);
122 do_dns = nvram_match("dhcpd_dmdns", "1");
124 // DNS rebinding protection, will discard upstream RFC1918 responses
125 if (nvram_get_int("dns_norebind")) {
126 fprintf(f,
127 "stop-dns-rebind\n"
128 "rebind-localhost-ok\n");
129 // allow RFC1918 responses for server domain
130 switch (get_wan_proto()) {
131 case WP_PPTP:
132 nv = nvram_get("pptp_server_ip");
133 break;
134 case WP_L2TP:
135 nv = nvram_get("l2tp_server_ip");
136 break;
137 default:
138 nv = NULL;
139 break;
141 if (nv && *nv) fprintf(f, "rebind-domain-ok=%s\n", nv);
144 #ifdef TCONFIG_DNSCRYPT
145 if (nvram_match("dnscrypt_proxy", "1")) {
146 fprintf(f, "server=127.0.0.1#40\n");
148 #endif
150 for (n = 0 ; n < dns->count; ++n) {
151 if (dns->dns[n].port != 53) {
152 fprintf(f, "server=%s#%u\n", inet_ntoa(dns->dns[n].addr), dns->dns[n].port);
156 if (nvram_get_int("dhcpd_static_only")) {
157 fprintf(f, "dhcp-ignore=tag:!known\n");
160 // dhcp
161 do_dhcpd_hosts=0;
162 char lanN_proto[] = "lanXX_proto";
163 char lanN_ifname[] = "lanXX_ifname";
164 char lanN_ipaddr[] = "lanXX_ipaddr";
165 char lanN_netmask[] = "lanXX_netmask";
166 char dhcpdN_startip[] = "dhcpdXX_startip";
167 char dhcpdN_endip[] = "dhcpdXX_endip";
168 char dhcpN_start[] = "dhcpXX_start";
169 char dhcpN_num[] = "dhcpXX_num";
170 char dhcpN_lease[] = "dhcpXX_lease";
171 char br;
172 for(br=0 ; br<=3 ; br++) {
173 char bridge[2] = "0";
174 if (br!=0)
175 bridge[0]+=br;
176 else
177 strcpy(bridge, "");
179 sprintf(lanN_proto, "lan%s_proto", bridge);
180 sprintf(lanN_ifname, "lan%s_ifname", bridge);
181 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
182 do_dhcpd = nvram_match(lanN_proto, "dhcp");
183 if (do_dhcpd) {
184 do_dhcpd_hosts++;
186 router_ip = nvram_safe_get(lanN_ipaddr);
187 strlcpy(lan, router_ip, sizeof(lan));
188 if ((p = strrchr(lan, '.')) != NULL) *(p + 1) = 0;
190 fprintf(f,
191 "interface=%s\n",
192 nvram_safe_get(lanN_ifname));
194 sprintf(dhcpN_lease, "dhcp%s_lease", bridge);
195 dhcp_lease = nvram_get_int(dhcpN_lease);
197 if (dhcp_lease <= 0) dhcp_lease = 1440;
199 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
200 if (n < 0) strcpy(sdhcp_lease, "infinite");
201 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
203 if (!do_dns) {
204 // if not using dnsmasq for dns
206 if ((dns->count == 0) && (nvram_get_int("dhcpd_llndns"))) {
207 // no DNS might be temporary. use a low lease time to force clients to update.
208 dhcp_lease = 2;
209 strcpy(sdhcp_lease, "2m");
210 do_dns = 1;
212 else {
213 // pass the dns directly
214 buf[0] = 0;
215 for (n = 0 ; n < dns->count; ++n) {
216 if (dns->dns[n].port == 53) { // check: option 6 doesn't seem to support other ports
217 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n].addr));
220 fprintf(f, "dhcp-option=%s,6%s\n", nvram_safe_get(lanN_ifname), buf);
224 sprintf(dhcpdN_startip, "dhcpd%s_startip", bridge);
225 sprintf(dhcpdN_endip, "dhcpd%s_endip", bridge);
226 sprintf(lanN_netmask, "lan%s_netmask", bridge);
228 if ((p = nvram_get(dhcpdN_startip)) && (*p) && (e = nvram_get(dhcpdN_endip)) && (*e)) {
229 fprintf(f, "dhcp-range=%s,%s,%s,%s,%dm\n", nvram_safe_get(lanN_ifname), p, e, nvram_safe_get(lanN_netmask), dhcp_lease);
231 else {
232 // for compatibility
233 sprintf(dhcpN_start, "dhcp%s_start", bridge);
234 sprintf(dhcpN_num, "dhcp%s_num", bridge);
235 sprintf(lanN_netmask, "lan%s_netmask", bridge);
236 dhcp_start = nvram_get_int(dhcpN_start);
237 dhcp_count = nvram_get_int(dhcpN_num);
238 fprintf(f, "dhcp-range=%s,%s%d,%s%d,%s,%dm\n",
239 nvram_safe_get(lanN_ifname), lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get(lanN_netmask), dhcp_lease);
242 nv = nvram_safe_get(lanN_ipaddr);
243 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED)) {
244 p = nvram_safe_get("lan_gateway");
245 if ((*p) && (strcmp(p, "0.0.0.0") != 0)) nv = p;
248 fprintf(f,
249 "dhcp-option=%s,3,%s\n", // gateway
250 nvram_safe_get(lanN_ifname), nv);
252 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
253 fprintf(f, "dhcp-option=%s,44,%s\n", nvram_safe_get(lanN_ifname), nv);
255 #ifdef TCONFIG_SAMBASRV
256 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
257 if ((nv == NULL) || (*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
258 // Samba will serve as a WINS server
259 fprintf(f, "dhcp-option=%s,44,0.0.0.0\n", nvram_safe_get(lanN_ifname));
262 #endif
263 } else {
264 if (strcmp(nvram_safe_get(lanN_ifname),"")!=0) {
265 fprintf(f, "interface=%s\n", nvram_safe_get(lanN_ifname));
266 fprintf(f, "no-dhcp-interface=%s\n", nvram_safe_get(lanN_ifname));
270 // write static lease entries & create hosts file
272 mkdir_if_none(dmhosts);
273 snprintf(buf, sizeof(buf), "%s/hosts", dmhosts);
274 if ((hf = fopen(buf, "w")) != NULL) {
275 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
276 fprintf(hf, "%s %s\n", router_ip, nv);
277 #ifdef TCONFIG_SAMBASRV
278 else if (((nv = nvram_get("lan_hostname")) != NULL) && (*nv))
279 fprintf(hf, "%s %s\n", router_ip, nv);
280 #endif
281 p = (char *)get_wanip();
282 if ((*p == 0) || strcmp(p, "0.0.0.0") == 0)
283 p = "127.0.0.1";
284 fprintf(hf, "%s wan-ip\n", p);
285 if (nv && (*nv))
286 fprintf(hf, "%s %s-wan\n", p, nv);
289 mkdir_if_none(dmdhcp);
290 snprintf(buf, sizeof(buf), "%s/dhcp-hosts", dmdhcp);
291 df = fopen(buf, "w");
293 // PREVIOUS/OLD FORMAT:
294 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
295 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
296 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 106 w/ delim
298 // NEW FORMAT (+static ARP binding after hostname):
299 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 55 w/ delim
300 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 87 w/ delim
301 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 108 w/ delim
303 p = nvram_safe_get("dhcpd_static");
304 while ((e = strchr(p, '>')) != NULL) {
305 n = (e - p);
306 if (n > 107) {
307 p = e + 1;
308 continue;
311 strncpy(buf, p, n);
312 buf[n] = 0;
313 p = e + 1;
315 if ((e = strchr(buf, '<')) == NULL) continue;
316 *e = 0;
317 mac = buf;
319 ip = e + 1;
320 if ((e = strchr(ip, '<')) == NULL) continue;
321 *e = 0;
322 if (strchr(ip, '.') == NULL) {
323 ipn = atoi(ip);
324 if ((ipn <= 0) || (ipn > 255)) continue;
325 sprintf(ipbuf, "%s%d", lan, ipn);
326 ip = ipbuf;
328 else {
329 if (inet_addr(ip) == INADDR_NONE) continue;
332 name = e + 1;
334 if ((e = strchr(name, '<')) != NULL) {
335 *e = 0;
338 if ((hf) && (*name != 0)) {
339 fprintf(hf, "%s %s\n", ip, name);
342 if ((do_dhcpd_hosts > 0) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
343 if (nvram_get_int("dhcpd_slt") == 0) {
344 fprintf(f, "dhcp-host=%s,%s\n", mac, ip);
345 } else {
346 fprintf(f, "dhcp-host=%s,%s,%s\n", mac, ip, sdhcp_lease);
351 if (df) fclose(df);
352 if (hf) fclose(hf);
354 n = nvram_get_int("dhcpd_lmax");
355 fprintf(f,
356 "dhcp-lease-max=%d\n",
357 (n > 0) ? n : 255);
358 if (nvram_get_int("dhcpd_auth") >= 0) {
359 fprintf(f, "dhcp-authoritative\n");
362 #ifdef TCONFIG_DNSCRYPT
363 if (nvram_match("dnscrypt_proxy", "1")) {
364 fprintf(f, "strict-order\n");
366 #endif
370 #ifdef TCONFIG_OPENVPN
371 write_vpn_dnsmasq_config(f);
372 #endif
374 #ifdef TCONFIG_PPTPD
375 write_pptpd_dnsmasq_config(f);
376 #endif
378 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
380 fappend(f, "/etc/dnsmasq.custom");
384 fclose(f);
386 if (do_dns) {
387 unlink("/etc/resolv.conf");
388 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
391 TRACE_PT("run dnsmasq\n");
393 // Default to some values we like, but allow the user to override them.
394 eval("dnsmasq", "-c", "1500", "--log-async");
396 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
397 pid_dnsmasq = -2;
400 TRACE_PT("end\n");
402 #ifdef TCONFIG_DNSCRYPT
403 //start dnscrypt-proxy
404 if (nvram_match("dnscrypt_proxy", "1")) {
405 eval("ntp2ip");
406 eval("dnscrypt-proxy", "-d", "-P", "40");
408 #endif
412 void stop_dnsmasq(void)
414 TRACE_PT("begin\n");
416 if (getpid() != 1) {
417 stop_service("dnsmasq");
418 return;
421 pid_dnsmasq = -1;
423 unlink("/etc/resolv.conf");
424 symlink(dmresolv, "/etc/resolv.conf");
426 killall_tk("dnsmasq");
427 #ifdef TCONFIG_DNSCRYPT
428 killall_tk("dnscrypt-proxy");
429 #endif
431 TRACE_PT("end\n");
434 void clear_resolv(void)
436 f_write(dmresolv, NULL, 0, 0, 0); // blank
439 #ifdef TCONFIG_IPV6
440 static int write_ipv6_dns_servers(FILE *f, const char *prefix, char *dns, const char *suffix, int once)
442 char p[INET6_ADDRSTRLEN + 1], *next = NULL;
443 struct in6_addr addr;
444 int cnt = 0;
446 foreach(p, dns, next) {
447 // verify that this is a valid IPv6 address
448 if (inet_pton(AF_INET6, p, &addr) == 1) {
449 fprintf(f, "%s%s%s", (once && cnt) ? "" : prefix, p, suffix);
450 ++cnt;
454 return cnt;
456 #endif
458 void dns_to_resolv(void)
460 FILE *f;
461 const dns_list_t *dns;
462 int i;
463 mode_t m;
465 m = umask(022); // 077 from pppoecd
466 if ((f = fopen(dmresolv, "w")) != NULL) {
467 // Check for VPN DNS entries
468 if (!write_pptpvpn_resolv(f) && !write_vpn_resolv(f)) {
469 #ifdef TCONFIG_IPV6
470 if (write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_dns"), "\n", 0) == 0 || nvram_get_int("dns_addget"))
471 write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_get_dns"), "\n", 0);
472 #endif
473 dns = get_dns(); // static buffer
474 if (dns->count == 0) {
475 // Put a pseudo DNS IP to trigger Connect On Demand
476 if (nvram_match("ppp_demand", "1")) {
477 switch (get_wan_proto()) {
478 case WP_PPPOE:
479 case WP_PPP3G:
480 case WP_PPTP:
481 case WP_L2TP:
482 fprintf(f, "nameserver 1.1.1.1\n");
483 break;
487 else {
488 for (i = 0; i < dns->count; i++) {
489 if (dns->dns[i].port == 53) { // resolv.conf doesn't allow for an alternate port
490 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i].addr));
495 fclose(f);
497 umask(m);
500 // -----------------------------------------------------------------------------
502 void start_httpd(void)
504 if (getpid() != 1) {
505 start_service("httpd");
506 return;
509 if( nvram_match( "web_css", "online" ) )
510 xstart( "/usr/sbin/ttb" );
512 stop_httpd();
513 chdir("/www");
514 eval("httpd");
515 chdir("/");
518 void stop_httpd(void)
520 if (getpid() != 1) {
521 stop_service("httpd");
522 return;
525 killall_tk("httpd");
528 // -----------------------------------------------------------------------------
529 #ifdef TCONFIG_IPV6
531 static void add_ip6_lanaddr(void)
533 char ip[INET6_ADDRSTRLEN + 4];
534 const char *p;
536 p = ipv6_router_address(NULL);
537 if (*p) {
538 snprintf(ip, sizeof(ip), "%s/%d", p, nvram_get_int("ipv6_prefix_length") ? : 64);
539 eval("ip", "-6", "addr", "add", ip, "dev", nvram_safe_get("lan_ifname"));
543 void start_ipv6_tunnel(void)
545 char ip[INET6_ADDRSTRLEN + 4];
546 struct in_addr addr4;
547 struct in6_addr addr;
548 const char *wanip, *mtu, *tun_dev;
549 int service;
551 service = get_ipv6_service();
552 tun_dev = get_wan6face();
553 wanip = get_wanip();
554 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
555 modprobe("sit");
557 if (service == IPV6_ANYCAST_6TO4)
558 snprintf(ip, sizeof(ip), "192.88.99.%d", nvram_get_int("ipv6_relay"));
559 else
560 strlcpy(ip, (char *)nvram_safe_get("ipv6_tun_v4end"), sizeof(ip));
561 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit",
562 "remote", ip,
563 "local", (char *)wanip,
564 "ttl", nvram_safe_get("ipv6_tun_ttl"));
566 eval("ip", "link", "set", (char *)tun_dev, "mtu", (char *)mtu, "up");
567 nvram_set("ipv6_ifname", (char *)tun_dev);
569 if (service == IPV6_ANYCAST_6TO4) {
570 add_ip6_lanaddr();
571 addr4.s_addr = 0;
572 memset(&addr, 0, sizeof(addr));
573 inet_aton(wanip, &addr4);
574 addr.s6_addr16[0] = htons(0x2002);
575 ipv6_mapaddr4(&addr, 16, &addr4, 0);
576 addr.s6_addr16[7] = htons(0x0001);
577 inet_ntop(AF_INET6, &addr, ip, sizeof(ip));
578 strncat(ip, "/16", sizeof(ip));
580 else {
581 snprintf(ip, sizeof(ip), "%s/%d",
582 nvram_safe_get("ipv6_tun_addr"),
583 nvram_get_int("ipv6_tun_addrlen") ? : 64);
585 eval("ip", "addr", "add", ip, "dev", (char *)tun_dev);
586 eval("ip", "route", "add", "::/0", "dev", (char *)tun_dev);
588 // (re)start radvd
589 if (service == IPV6_ANYCAST_6TO4)
590 start_radvd();
593 void stop_ipv6_tunnel(void)
595 eval("ip", "tunnel", "del", (char *)get_wan6face());
596 if (get_ipv6_service() == IPV6_ANYCAST_6TO4) {
597 // get rid of old IPv6 address from lan iface
598 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
600 modprobe_r("sit");
603 void start_6rd_tunnel(void)
605 const char *tun_dev, *wanip;
606 int service, mask_len, prefix_len, local_prefix_len;
607 char mtu[10], prefix[INET6_ADDRSTRLEN], relay[INET_ADDRSTRLEN];
608 struct in_addr netmask_addr, relay_addr, relay_prefix_addr, wanip_addr;
609 struct in6_addr prefix_addr, local_prefix_addr;
610 char local_prefix[INET6_ADDRSTRLEN];
611 char tmp_ipv6[INET6_ADDRSTRLEN + 4], tmp_ipv4[INET_ADDRSTRLEN + 4];
612 char tmp[256];
613 FILE *f;
615 service = get_ipv6_service();
616 wanip = get_wanip();
617 tun_dev = get_wan6face();
618 sprintf(mtu, "%d", (nvram_get_int("wan_mtu") > 0) ? (nvram_get_int("wan_mtu") - 20) : 1280);
620 // maybe we can merge the ipv6_6rd_* variables into a single ipv_6rd_string (ala wan_6rd)
621 // to save nvram space?
622 if (service == IPV6_6RD) {
623 _dprintf("starting 6rd tunnel using manual settings.\n");
624 mask_len = nvram_get_int("ipv6_6rd_ipv4masklen");
625 prefix_len = nvram_get_int("ipv6_6rd_prefix_length");
626 strcpy(prefix, nvram_safe_get("ipv6_6rd_prefix"));
627 strcpy(relay, nvram_safe_get("ipv6_6rd_borderrelay"));
629 else {
630 _dprintf("starting 6rd tunnel using automatic settings.\n");
631 char *wan_6rd = nvram_safe_get("wan_6rd");
632 if (sscanf(wan_6rd, "%d %d %s %s", &mask_len, &prefix_len, prefix, relay) < 4) {
633 _dprintf("wan_6rd string is missing or invalid (%s)\n", wan_6rd);
634 return;
638 // validate values that were passed
639 if (mask_len < 0 || mask_len > 32) {
640 _dprintf("invalid mask_len value (%d)\n", mask_len);
641 return;
643 if (prefix_len < 0 || prefix_len > 128) {
644 _dprintf("invalid prefix_len value (%d)\n", prefix_len);
645 return;
647 if ((32 - mask_len) + prefix_len > 128) {
648 _dprintf("invalid combination of mask_len and prefix_len!\n");
649 return;
652 sprintf(tmp, "ping -q -c 2 %s | grep packet", relay);
653 if ((f = popen(tmp, "r")) == NULL) {
654 _dprintf("error obtaining data\n");
655 return;
657 fgets(tmp, sizeof(tmp), f);
658 pclose(f);
659 if (strstr(tmp, " 0% packet loss") == NULL) {
660 _dprintf("failed to ping border relay\n");
661 return;
664 // get relay prefix from border relay address and mask
665 netmask_addr.s_addr = htonl(0xffffffff << (32 - mask_len));
666 inet_aton(relay, &relay_addr);
667 relay_prefix_addr.s_addr = relay_addr.s_addr & netmask_addr.s_addr;
669 // calculate the local prefix
670 inet_pton(AF_INET6, prefix, &prefix_addr);
671 inet_pton(AF_INET, wanip, &wanip_addr);
672 if (calc_6rd_local_prefix(&prefix_addr, prefix_len, mask_len,
673 &wanip_addr, &local_prefix_addr, &local_prefix_len) == 0) {
674 _dprintf("error calculating local prefix.");
675 return;
677 inet_ntop(AF_INET6, &local_prefix_addr, local_prefix, sizeof(local_prefix));
679 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1", local_prefix);
680 nvram_set("ipv6_rtr_addr", tmp_ipv6);
681 nvram_set("ipv6_prefix", local_prefix);
683 // load sit module needed for the 6rd tunnel
684 modprobe("sit");
686 // creating the 6rd tunnel
687 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit", "local", (char *)wanip, "ttl", nvram_safe_get("ipv6_tun_ttl"));
689 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s/%d", prefix, prefix_len);
690 snprintf(tmp_ipv4, sizeof(tmp_ipv4), "%s/%d", inet_ntoa(relay_prefix_addr), mask_len);
691 eval("ip", "tunnel" "6rd", "dev", (char *)tun_dev, "6rd-prefix", tmp_ipv6, "6rd-relay_prefix", tmp_ipv4);
693 // bringing up the link
694 eval("ip", "link", "set", "dev", (char *)tun_dev, "mtu", (char *)mtu, "up");
696 // setting the WAN address Note: IPv6 WAN CIDR should be: ((32 - ip6rd_ipv4masklen) + ip6rd_prefixlen)
697 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1/%d", local_prefix, local_prefix_len);
698 eval("ip", "-6", "addr", "add", tmp_ipv6, "dev", (char *)tun_dev);
700 // setting the LAN address Note: IPv6 LAN CIDR should be 64
701 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "%s1/%d", local_prefix, nvram_get_int("ipv6_prefix_length") ? : 64);
702 eval("ip", "-6", "addr", "add", tmp_ipv6, "dev", nvram_safe_get("lan_ifname"));
704 // adding default route via the border relay
705 snprintf(tmp_ipv6, sizeof(tmp_ipv6), "::%s", relay);
706 eval("ip", "-6", "route", "add", "default", "via", tmp_ipv6, "dev", (char *)tun_dev);
708 nvram_set("ipv6_ifname", (char *)tun_dev);
710 // (re)start radvd
711 start_radvd();
713 printf("6rd end\n");
716 void stop_6rd_tunnel(void)
718 eval("ip", "tunnel", "del", (char *)get_wan6face());
719 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
720 modprobe_r("sit");
723 static pid_t pid_radvd = -1;
725 void start_radvd(void)
727 FILE *f;
728 char *prefix, *ip, *mtu;
729 int do_dns, do_6to4, do_6rd;
730 char *argv[] = { "radvd", NULL, NULL, NULL };
731 int pid, argc, service, cnt;
733 if (getpid() != 1) {
734 start_service("radvd");
735 return;
738 stop_radvd();
740 if (ipv6_enabled() && nvram_get_int("ipv6_radvd")) {
741 service = get_ipv6_service();
742 do_6to4 = (service == IPV6_ANYCAST_6TO4);
743 do_6rd = (service == IPV6_6RD || service == IPV6_6RD_DHCP);
744 mtu = NULL;
746 switch (service) {
747 case IPV6_NATIVE_DHCP:
748 prefix = "::";
749 break;
750 case IPV6_ANYCAST_6TO4:
751 case IPV6_6IN4:
752 case IPV6_6RD:
753 case IPV6_6RD_DHCP:
754 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
755 // fall through
756 default:
757 prefix = do_6to4 ? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
758 break;
760 if (!(*prefix)) prefix = "::";
762 // Create radvd.conf
763 if ((f = fopen("/etc/radvd.conf", "w")) == NULL) return;
765 ip = (char *)ipv6_router_address(NULL);
766 do_dns = (*ip) && nvram_match("dhcpd_dmdns", "1");
768 fprintf(f,
769 "interface %s\n"
770 "{\n"
771 " IgnoreIfMissing on;\n"
772 " AdvSendAdvert on;\n"
773 " MaxRtrAdvInterval 60;\n"
774 " AdvHomeAgentFlag off;\n"
775 " AdvManagedFlag off;\n"
776 "%s%s%s"
777 " prefix %s/64 \n"
778 " {\n"
779 " AdvOnLink on;\n"
780 " AdvAutonomous on;\n"
781 "%s"
782 "%s%s%s"
783 " };\n",
784 nvram_safe_get("lan_ifname"),
785 mtu ? " AdvLinkMTU " : "", mtu ? : "", mtu ? ";\n" : "",
786 prefix,
787 (do_6to4 || do_6rd) ? " AdvValidLifetime 300;\n AdvPreferredLifetime 120;\n" : "",
788 do_6to4 ? " Base6to4Interface " : "",
789 do_6to4 ? get_wanface() : "",
790 do_6to4 ? ";\n" : "");
792 if (do_dns) {
793 fprintf(f, " RDNSS %s {};\n", ip);
795 else {
796 cnt = write_ipv6_dns_servers(f, " RDNSS ", nvram_safe_get("ipv6_dns"), " ", 1);
797 if (cnt == 0 || nvram_get_int("dns_addget"))
798 cnt += write_ipv6_dns_servers(f, (cnt) ? "" : " RDNSS ", nvram_safe_get("ipv6_get_dns"), " ", 1);
799 if (cnt) fprintf(f, "{};\n");
802 fprintf(f,
803 "};\n"); // close "interface" section
804 fclose(f);
806 // Start radvd
807 argc = 1;
808 if (nvram_get_int("debug_ipv6")) {
809 argv[argc++] = "-d";
810 argv[argc++] = "10";
812 argv[argc] = NULL;
813 _eval(argv, NULL, 0, &pid);
815 if (!nvram_contains_word("debug_norestart", "radvd")) {
816 pid_radvd = -2;
821 void stop_radvd(void)
823 if (getpid() != 1) {
824 stop_service("radvd");
825 return;
828 pid_radvd = -1;
829 killall_tk("radvd");
832 void start_ipv6(void)
834 int service;
836 service = get_ipv6_service();
837 enable_ip_forward();
839 // Check if turned on
840 switch (service) {
841 case IPV6_NATIVE:
842 case IPV6_6IN4:
843 case IPV6_MANUAL:
844 add_ip6_lanaddr();
845 break;
846 case IPV6_NATIVE_DHCP:
847 case IPV6_ANYCAST_6TO4:
848 nvram_set("ipv6_rtr_addr", "");
849 nvram_set("ipv6_prefix", "");
850 break;
853 if (service != IPV6_DISABLED) {
854 if ((nvram_get_int("ipv6_accept_ra") & 2) != 0 && !nvram_get_int("ipv6_radvd"))
855 accept_ra(nvram_safe_get("lan_ifname"));
859 void stop_ipv6(void)
861 stop_ipv6_tunnel();
862 stop_dhcp6c();
863 eval("ip", "-6", "addr", "flush", "scope", "global");
866 #endif
868 // -----------------------------------------------------------------------------
870 void start_upnp(void)
872 if (getpid() != 1) {
873 start_service("upnp");
874 return;
877 if (get_wan_proto() == WP_DISABLED) return;
879 int enable;
880 FILE *f;
881 int upnp_port;
883 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
884 mkdir("/etc/upnp", 0777);
885 if (f_exists("/etc/upnp/config.alt")) {
886 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
888 else {
889 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
890 upnp_port = nvram_get_int("upnp_port");
891 if ((upnp_port < 0) || (upnp_port >= 0xFFFF)) upnp_port = 0;
894 fprintf(f,
895 "ext_ifname=%s\n"
896 "port=%d\n"
897 "enable_upnp=%s\n"
898 "enable_natpmp=%s\n"
899 "secure_mode=%s\n"
900 "upnp_forward_chain=upnp\n"
901 "upnp_nat_chain=upnp\n"
902 "notify_interval=%d\n"
903 "system_uptime=yes\n"
904 "\n"
906 get_wanface(),
907 upnp_port,
908 (enable & 1) ? "yes" : "no", // upnp enable
909 (enable & 2) ? "yes" : "no", // natpmp enable
910 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
911 nvram_get_int("upnp_ssdp_interval")
914 if (nvram_get_int("upnp_clean")) {
915 int interval = nvram_get_int("upnp_clean_interval");
916 if (interval < 60) interval = 60;
917 fprintf(f,
918 "clean_ruleset_interval=%d\n"
919 "clean_ruleset_threshold=%d\n",
920 interval,
921 nvram_get_int("upnp_clean_threshold")
924 else
925 fprintf(f,"clean_ruleset_interval=0\n");
927 if (nvram_match("upnp_mnp", "1")) {
928 int https = nvram_get_int("https_enable");
929 fprintf(f, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
930 https ? "s" : "", nvram_safe_get("lan_ipaddr"),
931 nvram_safe_get(https ? "https_lanport" : "http_lanport"));
933 else {
934 // Empty parameters are not included into XML service description
935 fprintf(f, "presentation_url=\n");
938 char uuid[45];
939 f_read_string("/proc/sys/kernel/random/uuid", uuid, sizeof(uuid));
940 fprintf(f, "uuid=%s\n", uuid);
942 char lanN_ipaddr[] = "lanXX_ipaddr";
943 char lanN_netmask[] = "lanXX_netmask";
944 char upnp_lanN[] = "upnp_lanXX";
945 char br;
947 for(br=0 ; br<4 ; br++) {
948 char bridge[2] = "0";
949 if (br!=0)
950 bridge[0]+=br;
951 else
952 strcpy(bridge, "");
954 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
955 sprintf(lanN_netmask, "lan%s_netmask", bridge);
956 sprintf(upnp_lanN, "upnp_lan%s", bridge);
958 char *lanip = nvram_safe_get(lanN_ipaddr);
959 char *lanmask = nvram_safe_get(lanN_netmask);
960 char *lanlisten = nvram_safe_get(upnp_lanN);
961 if((strcmp(lanlisten,"1")==0) && (strcmp(lanip,"")!=0) && (strcmp(lanip,"0.0.0.0")!=0)) {
962 fprintf(f,
963 "listening_ip=%s/%s\n",
964 lanip, lanmask);
965 int ports[4];
966 if ((ports[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
967 (ports[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
968 (ports[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
969 (ports[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
970 fprintf(f,
971 "allow %d-%d %s/%s %d-%d\n",
972 ports[0], ports[1],
973 lanip, lanmask,
974 ports[2], ports[3]
977 else {
978 // by default allow only redirection of ports above 1024
979 fprintf(f, "allow 1024-65535 %s/%s 1024-65535\n", lanip, lanmask);
984 fappend(f, "/etc/upnp/config.custom");
985 fprintf(f, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
986 fclose(f);
988 xstart("miniupnpd", "-f", "/etc/upnp/config");
994 void stop_upnp(void)
996 if (getpid() != 1) {
997 stop_service("upnp");
998 return;
1001 killall_tk("miniupnpd");
1004 // -----------------------------------------------------------------------------
1006 static pid_t pid_crond = -1;
1008 void start_cron(void)
1010 stop_cron();
1012 eval("crond", nvram_contains_word("log_events", "crond") ? NULL : "-l", "9");
1013 if (!nvram_contains_word("debug_norestart", "crond")) {
1014 pid_crond = -2;
1018 void stop_cron(void)
1020 pid_crond = -1;
1021 killall_tk("crond");
1024 // -----------------------------------------------------------------------------
1025 #ifdef LINUX26
1027 static pid_t pid_hotplug2 = -1;
1029 void start_hotplug2()
1031 stop_hotplug2();
1033 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE, 0);
1034 xstart("hotplug2", "--persistent", "--no-coldplug");
1035 // FIXME: Don't remember exactly why I put "sleep" here -
1036 // but it was not for a race with check_services()... - TB
1037 sleep(1);
1039 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
1040 pid_hotplug2 = -2;
1044 void stop_hotplug2(void)
1046 pid_hotplug2 = -1;
1047 killall_tk("hotplug2");
1050 #endif /* LINUX26 */
1051 // -----------------------------------------------------------------------------
1053 // Written by Sparq in 2002/07/16
1054 void start_zebra(void)
1056 #ifdef TCONFIG_ZEBRA
1057 if (getpid() != 1) {
1058 start_service("zebra");
1059 return;
1062 FILE *fp;
1064 char *lan_tx = nvram_safe_get("dr_lan_tx");
1065 char *lan_rx = nvram_safe_get("dr_lan_rx");
1066 char *lan1_tx = nvram_safe_get("dr_lan1_tx");
1067 char *lan1_rx = nvram_safe_get("dr_lan1_rx");
1068 char *lan2_tx = nvram_safe_get("dr_lan2_tx");
1069 char *lan2_rx = nvram_safe_get("dr_lan2_rx");
1070 char *lan3_tx = nvram_safe_get("dr_lan3_tx");
1071 char *lan3_rx = nvram_safe_get("dr_lan3_rx");
1072 char *wan_tx = nvram_safe_get("dr_wan_tx");
1073 char *wan_rx = nvram_safe_get("dr_wan_rx");
1075 if ((*lan_tx == '0') && (*lan_rx == '0') &&
1076 (*lan1_tx == '0') && (*lan1_rx == '0') &&
1077 (*lan2_tx == '0') && (*lan2_rx == '0') &&
1078 (*lan3_tx == '0') && (*lan3_rx == '0') &&
1079 (*wan_tx == '0') && (*wan_rx == '0')) {
1080 return;
1083 // empty
1084 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
1085 fclose(fp);
1089 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
1090 char *lan_ifname = nvram_safe_get("lan_ifname");
1091 char *lan1_ifname = nvram_safe_get("lan1_ifname");
1092 char *lan2_ifname = nvram_safe_get("lan2_ifname");
1093 char *lan3_ifname = nvram_safe_get("lan3_ifname");
1094 char *wan_ifname = nvram_safe_get("wan_ifname");
1096 fprintf(fp, "router rip\n");
1097 if(strcmp(lan_ifname,"")!=0)
1098 fprintf(fp, "network %s\n", lan_ifname);
1099 if(strcmp(lan1_ifname,"")!=0)
1100 fprintf(fp, "network %s\n", lan1_ifname);
1101 if(strcmp(lan2_ifname,"")!=0)
1102 fprintf(fp, "network %s\n", lan2_ifname);
1103 if(strcmp(lan3_ifname,"")!=0)
1104 fprintf(fp, "network %s\n", lan3_ifname);
1105 fprintf(fp, "network %s\n", wan_ifname);
1106 fprintf(fp, "redistribute connected\n");
1107 //fprintf(fp, "redistribute static\n");
1109 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
1110 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
1112 if(strcmp(lan_ifname,"")!=0) {
1113 fprintf(fp, "interface %s\n", lan_ifname);
1114 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
1115 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
1117 if(strcmp(lan1_ifname,"")!=0) {
1118 fprintf(fp, "interface %s\n", lan1_ifname);
1119 if (*lan1_tx != '0') fprintf(fp, "ip rip send version %s\n", lan1_tx);
1120 if (*lan1_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan1_rx);
1122 if(strcmp(lan2_ifname,"")!=0) {
1123 fprintf(fp, "interface %s\n", lan2_ifname);
1124 if (*lan2_tx != '0') fprintf(fp, "ip rip send version %s\n", lan2_tx);
1125 if (*lan2_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan2_rx);
1127 if(strcmp(lan3_ifname,"")!=0) {
1128 fprintf(fp, "interface %s\n", lan3_ifname);
1129 if (*lan3_tx != '0') fprintf(fp, "ip rip send version %s\n", lan3_tx);
1130 if (*lan3_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan3_rx);
1132 fprintf(fp, "interface %s\n", wan_ifname);
1133 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
1134 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
1136 fprintf(fp, "router rip\n");
1137 if(strcmp(lan_ifname,"")!=0) {
1138 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
1139 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
1141 if(strcmp(lan1_ifname,"")!=0) {
1142 if (*lan1_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan1_ifname);
1143 if (*lan1_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan1_ifname);
1145 if(strcmp(lan2_ifname,"")!=0) {
1146 if (*lan2_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan2_ifname);
1147 if (*lan2_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan2_ifname);
1149 if(strcmp(lan3_ifname,"")!=0) {
1150 if (*lan3_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan3_ifname);
1151 if (*lan3_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan3_ifname);
1153 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
1154 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
1155 fprintf(fp, "access-list private deny any\n");
1157 //fprintf(fp, "debug rip events\n");
1158 //fprintf(fp, "log file /etc/ripd.log\n");
1159 fclose(fp);
1162 xstart("zebra", "-d");
1163 xstart("ripd", "-d");
1164 #endif
1167 void stop_zebra(void)
1169 #ifdef TCONFIG_ZEBRA
1170 if (getpid() != 1) {
1171 stop_service("zebra");
1172 return;
1175 killall("zebra", SIGTERM);
1176 killall("ripd", SIGTERM);
1178 unlink("/etc/zebra.conf");
1179 unlink("/etc/ripd.conf");
1180 #endif
1183 // -----------------------------------------------------------------------------
1185 void start_syslog(void)
1187 char *argv[16];
1188 int argc;
1189 char *nv;
1190 char *b_opt = "";
1191 char rem[256];
1192 int n;
1193 char s[64];
1194 char cfg[256];
1195 char *rot_siz = "50";
1196 char *rot_keep = "1";
1197 char *log_file_path;
1199 argv[0] = "syslogd";
1200 argc = 1;
1202 if (nvram_match("log_remote", "1")) {
1203 nv = nvram_safe_get("log_remoteip");
1204 if (*nv) {
1205 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
1206 argv[argc++] = "-R";
1207 argv[argc++] = rem;
1211 if (nvram_match("log_file", "1")) {
1212 argv[argc++] = "-L";
1214 if (strcmp(nvram_safe_get("log_file_size"), "") != 0) {
1215 rot_siz = nvram_safe_get("log_file_size");
1217 if (nvram_get_int("log_file_size") > 0) {
1218 rot_keep = nvram_safe_get("log_file_keep");
1221 // log to custom path - shibby
1222 if (nvram_match("log_file_custom", "1")) {
1223 log_file_path = nvram_safe_get("log_file_path");
1224 argv[argc++] = "-s";
1225 argv[argc++] = rot_siz;
1226 argv[argc++] = "-O";
1227 argv[argc++] = log_file_path;
1228 if (strcmp(nvram_safe_get("log_file_path"), "/var/log/messages") != 0) {
1229 remove("/var/log/messages");
1230 symlink(log_file_path, "/var/log/messages");
1233 else
1235 /* Read options: rotate_size(kb) num_backups logfilename.
1236 * Ignore these settings and use defaults if the logfile cannot be written to.
1238 if (f_read_string("/etc/syslogd.cfg", cfg, sizeof(cfg)) > 0) {
1239 if ((nv = strchr(cfg, '\n')))
1240 *nv = 0;
1242 if ((nv = strtok(cfg, " \t"))) {
1243 if (isdigit(*nv))
1244 rot_siz = nv;
1247 if ((nv = strtok(NULL, " \t")))
1248 b_opt = nv;
1250 if ((nv = strtok(NULL, " \t")) && *nv == '/') {
1251 if (f_write(nv, cfg, 0, FW_APPEND, 0) >= 0) {
1252 argv[argc++] = "-O";
1253 argv[argc++] = nv;
1255 else {
1256 rot_siz = "50";
1257 b_opt = "";
1262 if (nvram_match("log_file_custom", "0")) {
1263 argv[argc++] = "-s";
1264 argv[argc++] = rot_siz;
1265 struct stat sb;
1266 if (lstat("/var/log/messages", &sb) != -1)
1267 if (S_ISLNK(sb.st_mode))
1268 remove("/var/log/messages");
1271 if (isdigit(*b_opt)) {
1272 argv[argc++] = "-b";
1273 argv[argc++] = b_opt;
1274 } else
1275 if (nvram_get_int("log_file_size") > 0) {
1276 argv[argc++] = "-b";
1277 argv[argc++] = rot_keep;
1281 if (argc > 1) {
1282 argv[argc] = NULL;
1283 _eval(argv, NULL, 0, NULL);
1285 argv[0] = "klogd";
1286 argv[1] = NULL;
1287 _eval(argv, NULL, 0, NULL);
1289 // used to be available in syslogd -m
1290 n = nvram_get_int("log_mark");
1291 if (n > 0) {
1292 // n is in minutes
1293 if (n < 60)
1294 sprintf(rem, "*/%d * * * *", n);
1295 else if (n < 60 * 24)
1296 sprintf(rem, "0 */%d * * *", n / 60);
1297 else
1298 sprintf(rem, "0 0 */%d * *", n / (60 * 24));
1299 sprintf(s, "%s logger -p syslog.info -- -- MARK --", rem);
1300 eval("cru", "a", "syslogdmark", s);
1302 else {
1303 eval("cru", "d", "syslogdmark");
1308 void stop_syslog(void)
1310 killall("klogd", SIGTERM);
1311 killall("syslogd", SIGTERM);
1314 // -----------------------------------------------------------------------------
1316 static pid_t pid_igmp = -1;
1318 void start_igmp_proxy(void)
1320 FILE *fp;
1322 pid_igmp = -1;
1323 if (nvram_match("multicast_pass", "1")) {
1324 if (get_wan_proto() == WP_DISABLED)
1325 return;
1327 if (f_exists("/etc/igmp.alt")) {
1328 eval("igmpproxy", "/etc/igmp.alt");
1330 else if ((fp = fopen("/etc/igmp.conf", "w")) != NULL) {
1331 fprintf(fp,
1332 "quickleave\n"
1333 "phyint %s upstream\n"
1334 "\taltnet %s\n",
1335 // "phyint %s downstream ratelimit 0\n",
1336 get_wanface(),
1337 nvram_get("multicast_altnet") ? : "0.0.0.0/0");
1338 // nvram_safe_get("lan_ifname"));
1340 char lanN_ifname[] = "lanXX_ifname";
1341 char multicast_lanN[] = "multicast_lanXX";
1342 char br;
1344 for(br=0 ; br<4 ; br++) {
1345 char bridge[2] = "0";
1346 if (br!=0)
1347 bridge[0]+=br;
1348 else
1349 strcpy(bridge, "");
1351 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1352 sprintf(multicast_lanN, "multicast_lan%s", bridge);
1354 if((strcmp(nvram_safe_get(multicast_lanN),"1")==0) && (strcmp(nvram_safe_get(lanN_ifname),"")!=0)) {
1355 fprintf(fp,
1356 "phyint %s downstream ratelimit 0\n",
1357 nvram_safe_get(lanN_ifname));
1360 fclose(fp);
1361 eval("igmpproxy", "/etc/igmp.conf");
1363 else {
1364 return;
1366 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1367 pid_igmp = -2;
1372 void stop_igmp_proxy(void)
1374 pid_igmp = -1;
1375 killall_tk("igmpproxy");
1378 // -----------------------------------------------------------------------------
1380 void start_udpxy(void)
1382 if (nvram_match("udpxy_enable", "1")) {
1383 if (get_wan_proto() == WP_DISABLED)
1384 return;
1385 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") );
1389 void stop_udpxy(void)
1391 killall_tk("udpxy");
1394 // -----------------------------------------------------------------------------
1396 #ifdef TCONFIG_NOCAT
1398 static pid_t pid_splashd = -1;
1399 void start_splashd(void)
1401 pid_splashd = -1;
1402 start_nocat();
1403 if (!nvram_contains_word("debug_norestart", "splashd")) {
1404 pid_splashd = -2;
1408 void stop_splashd(void)
1410 pid_splashd = -1;
1411 stop_nocat();
1412 start_wan(BOOT);
1414 #endif
1416 // -----------------------------------------------------------------------------
1418 void set_tz(void)
1420 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
1423 void start_ntpc(void)
1425 set_tz();
1427 stop_ntpc();
1429 if (nvram_get_int("ntp_updates") >= 0) {
1430 xstart("ntpsync", "--init");
1434 void stop_ntpc(void)
1436 killall("ntpsync", SIGTERM);
1439 // -----------------------------------------------------------------------------
1441 static void stop_rstats(void)
1443 int n, m;
1444 int pid;
1445 int pidz;
1446 int ppidz;
1447 int w = 0;
1449 n = 60;
1450 m = 15;
1451 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
1452 w = 1;
1453 pidz = pidof("gzip");
1454 if (pidz < 1) pidz = pidof("cp");
1455 ppidz = ppid(ppid(pidz));
1456 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1457 syslog(LOG_DEBUG, "rstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1458 --m;
1459 } else {
1460 kill(pid, SIGTERM);
1462 sleep(1);
1464 if ((w == 1) && (n > 0))
1465 syslog(LOG_DEBUG, "rstats stopped.\n");
1468 static void start_rstats(int new)
1470 if (nvram_match("rstats_enable", "1")) {
1471 stop_rstats();
1472 if (new) {
1473 syslog(LOG_DEBUG, "starting rstats (new datafile).\n");
1474 xstart("rstats", "--new");
1475 } else {
1476 syslog(LOG_DEBUG, "starting rstats.\n");
1477 xstart("rstats");
1482 static void stop_cstats(void)
1484 int n, m;
1485 int pid;
1486 int pidz;
1487 int ppidz;
1488 int w = 0;
1490 n = 60;
1491 m = 15;
1492 while ((n-- > 0) && ((pid = pidof("cstats")) > 0)) {
1493 w = 1;
1494 pidz = pidof("gzip");
1495 if (pidz < 1) pidz = pidof("cp");
1496 ppidz = ppid(ppid(pidz));
1497 if ((m > 0) && (pidz > 0) && (pid == ppidz)) {
1498 syslog(LOG_DEBUG, "cstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid, pidz, ppidz);
1499 --m;
1500 } else {
1501 kill(pid, SIGTERM);
1503 sleep(1);
1505 if ((w == 1) && (n > 0))
1506 syslog(LOG_DEBUG, "cstats stopped.\n");
1509 static void start_cstats(int new)
1511 if (nvram_match("cstats_enable", "1")) {
1512 stop_cstats();
1513 if (new) {
1514 syslog(LOG_DEBUG, "starting cstats (new datafile).\n");
1515 xstart("cstats", "--new");
1516 } else {
1517 syslog(LOG_DEBUG, "starting cstats.\n");
1518 xstart("cstats");
1523 // -----------------------------------------------------------------------------
1525 // !!TB - FTP Server
1527 #ifdef TCONFIG_FTP
1528 static char *get_full_storage_path(char *val)
1530 static char buf[128];
1531 int len;
1533 if (val[0] == '/')
1534 len = sprintf(buf, "%s", val);
1535 else
1536 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
1538 if (len > 1 && buf[len - 1] == '/')
1539 buf[len - 1] = 0;
1541 return buf;
1544 static char *nvram_storage_path(char *var)
1546 char *val = nvram_safe_get(var);
1547 return get_full_storage_path(val);
1550 char vsftpd_conf[] = "/etc/vsftpd.conf";
1551 char vsftpd_users[] = "/etc/vsftpd.users";
1552 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
1554 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1556 static void start_ftpd(void)
1558 char tmp[256];
1559 FILE *fp, *f;
1560 char *buf;
1561 char *p, *q;
1562 int i;
1563 char *user, *pass, *rights, *root_dir;
1565 if (getpid() != 1) {
1566 start_service("ftpd");
1567 return;
1570 if (!nvram_get_int("ftp_enable")) return;
1572 mkdir_if_none(vsftpd_users);
1573 mkdir_if_none("/var/run/vsftpd");
1575 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
1576 return;
1578 if (nvram_get_int("ftp_super"))
1580 /* rights */
1581 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
1582 if ((f = fopen(tmp, "w")))
1584 fprintf(f,
1585 "dirlist_enable=yes\n"
1586 "write_enable=yes\n"
1587 "download_enable=yes\n");
1588 fclose(f);
1592 #ifdef TCONFIG_SAMBASRV
1593 if (nvram_match("smbd_cset", "utf8"))
1594 fprintf(fp, "utf8=yes\n");
1595 #endif
1597 if (nvram_invmatch("ftp_anonymous", "0"))
1599 fprintf(fp,
1600 "anon_allow_writable_root=yes\n"
1601 "anon_world_readable_only=no\n"
1602 "anon_umask=022\n");
1604 /* rights */
1605 sprintf(tmp, "%s/ftp", vsftpd_users);
1606 if ((f = fopen(tmp, "w")))
1608 if (nvram_match("ftp_dirlist", "0"))
1609 fprintf(f, "dirlist_enable=yes\n");
1610 if (nvram_match("ftp_anonymous", "1") ||
1611 nvram_match("ftp_anonymous", "3"))
1612 fprintf(f, "write_enable=yes\n");
1613 if (nvram_match("ftp_anonymous", "1") ||
1614 nvram_match("ftp_anonymous", "2"))
1615 fprintf(f, "download_enable=yes\n");
1616 fclose(f);
1618 if (nvram_match("ftp_anonymous", "1") ||
1619 nvram_match("ftp_anonymous", "3"))
1620 fprintf(fp,
1621 "anon_upload_enable=yes\n"
1622 "anon_mkdir_write_enable=yes\n"
1623 "anon_other_write_enable=yes\n");
1624 } else {
1625 fprintf(fp, "anonymous_enable=no\n");
1628 fprintf(fp,
1629 "dirmessage_enable=yes\n"
1630 "download_enable=no\n"
1631 "dirlist_enable=no\n"
1632 "hide_ids=yes\n"
1633 "syslog_enable=yes\n"
1634 "local_enable=yes\n"
1635 "local_umask=022\n"
1636 "chmod_enable=no\n"
1637 "chroot_local_user=yes\n"
1638 "check_shell=no\n"
1639 "log_ftp_protocol=%s\n"
1640 "user_config_dir=%s\n"
1641 "passwd_file=%s\n"
1642 "listen%s=yes\n"
1643 "listen_port=%s\n"
1644 "background=yes\n"
1645 "isolate=no\n"
1646 "max_clients=%d\n"
1647 "max_per_ip=%d\n"
1648 "max_login_fails=1\n"
1649 "idle_session_timeout=%s\n"
1650 "use_sendfile=no\n"
1651 "anon_max_rate=%d\n"
1652 "local_max_rate=%d\n"
1653 "%s\n",
1654 nvram_get_int("log_ftp") ? "yes" : "no",
1655 vsftpd_users, vsftpd_passwd,
1656 #ifdef TCONFIG_IPV6
1657 ipv6_enabled() ? "_ipv6" : "",
1658 #else
1660 #endif
1661 nvram_get("ftp_port") ? : "21",
1662 nvram_get_int("ftp_max"),
1663 nvram_get_int("ftp_ipmax"),
1664 nvram_get("ftp_staytimeout") ? : "300",
1665 nvram_get_int("ftp_anonrate") * 1024,
1666 nvram_get_int("ftp_rate") * 1024,
1667 nvram_safe_get("ftp_custom"));
1669 fclose(fp);
1671 /* prepare passwd file and default users */
1672 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
1673 return;
1675 if (((user = nvram_get("http_username")) == NULL) || (*user == 0)) user = "admin";
1676 if (((pass = nvram_get("http_passwd")) == NULL) || (*pass == 0)) pass = "admin";
1678 fprintf(fp, /* anonymous, admin, nobody */
1679 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1680 "%s:%s:0:0:root:/:/sbin/nologin\n"
1681 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1682 nvram_storage_path("ftp_anonroot"), user,
1683 nvram_get_int("ftp_super") ? crypt(pass, "$1$") : "x",
1684 MOUNT_ROOT);
1686 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
1689 username<password<rights[<root_dir>]
1690 rights:
1691 Read/Write
1692 Read Only
1693 View Only
1694 Private
1696 p = buf;
1697 while ((q = strsep(&p, ">")) != NULL) {
1698 i = vstrsep(q, "<", &user, &pass, &rights, &root_dir);
1699 if (i < 3 || i > 4) continue;
1700 if (!user || !pass) continue;
1702 if (i == 3 || !root_dir || !(*root_dir))
1704 root_dir = nvram_safe_get("ftp_pubroot");
1706 /* directory */
1707 if (strncmp(rights, "Private", 7) == 0)
1709 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
1710 mkdir_if_none(tmp);
1712 else
1713 sprintf(tmp, "%s", get_full_storage_path(root_dir));
1715 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1716 user, crypt(pass, "$1$"), user, tmp);
1718 /* rights */
1719 sprintf(tmp, "%s/%s", vsftpd_users, user);
1720 if ((f = fopen(tmp, "w")))
1722 tmp[0] = 0;
1723 if (nvram_invmatch("ftp_dirlist", "1"))
1724 strcat(tmp, "dirlist_enable=yes\n");
1725 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
1726 strcat(tmp, "download_enable=yes\n");
1727 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
1728 strcat(tmp, "write_enable=yes\n");
1730 fputs(tmp, f);
1731 fclose(f);
1734 free(buf);
1737 fclose(fp);
1738 killall("vsftpd", SIGHUP);
1740 /* start vsftpd if it's not already running */
1741 if (pidof("vsftpd") <= 0)
1742 xstart("vsftpd");
1745 static void stop_ftpd(void)
1747 if (getpid() != 1) {
1748 stop_service("ftpd");
1749 return;
1752 killall_tk("vsftpd");
1753 unlink(vsftpd_passwd);
1754 unlink(vsftpd_conf);
1755 eval("rm", "-rf", vsftpd_users);
1757 #endif // TCONFIG_FTP
1759 // -----------------------------------------------------------------------------
1761 // !!TB - Samba
1763 #ifdef TCONFIG_SAMBASRV
1764 static void kill_samba(int sig)
1766 if (sig == SIGTERM) {
1767 killall_tk("smbd");
1768 killall_tk("nmbd");
1770 else {
1771 killall("smbd", sig);
1772 killall("nmbd", sig);
1776 static void start_samba(void)
1778 FILE *fp;
1779 DIR *dir = NULL;
1780 struct dirent *dp;
1781 char nlsmod[15];
1782 int mode;
1783 char *nv;
1785 if (getpid() != 1) {
1786 start_service("smbd");
1787 return;
1790 mode = nvram_get_int("smbd_enable");
1791 if (!mode || !nvram_invmatch("lan_hostname", ""))
1792 return;
1794 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
1795 return;
1797 fprintf(fp, "[global]\n"
1798 " interfaces = %s\n"
1799 " bind interfaces only = yes\n"
1800 " workgroup = %s\n"
1801 " netbios name = %s\n"
1802 " server string = %s\n"
1803 " guest account = nobody\n"
1804 " security = user\n"
1805 " %s\n"
1806 " guest ok = %s\n"
1807 " guest only = no\n"
1808 " browseable = yes\n"
1809 " syslog only = yes\n"
1810 " timestamp logs = no\n"
1811 " syslog = 1\n"
1812 " encrypt passwords = yes\n"
1813 " preserve case = yes\n"
1814 " short preserve case = yes\n",
1815 nvram_safe_get("lan_ifname"),
1816 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1817 nvram_safe_get("lan_hostname"),
1818 nvram_get("router_name") ? : "Tomato",
1819 mode == 2 ? "" : "map to guest = Bad User",
1820 mode == 2 ? "no" : "yes" // guest ok
1823 if (nvram_get_int("smbd_wins")) {
1824 nv = nvram_safe_get("wan_wins");
1825 if ((*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
1826 fprintf(fp, " wins support = yes\n");
1830 if (nvram_get_int("smbd_master")) {
1831 fprintf(fp,
1832 " domain master = yes\n"
1833 " local master = yes\n"
1834 " preferred master = yes\n"
1835 " os level = 65\n");
1838 nv = nvram_safe_get("smbd_cpage");
1839 if (*nv) {
1840 #ifndef TCONFIG_SAMBA3
1841 fprintf(fp, " client code page = %s\n", nv);
1842 #endif
1843 sprintf(nlsmod, "nls_cp%s", nv);
1845 nv = nvram_safe_get("smbd_nlsmod");
1846 if ((*nv) && (strcmp(nv, nlsmod) != 0))
1847 modprobe_r(nv);
1849 modprobe(nlsmod);
1850 nvram_set("smbd_nlsmod", nlsmod);
1853 #ifndef TCONFIG_SAMBA3
1854 if (nvram_match("smbd_cset", "utf8"))
1855 fprintf(fp, " coding system = utf8\n");
1856 else if (nvram_invmatch("smbd_cset", ""))
1857 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1858 #endif
1860 nv = nvram_safe_get("smbd_custom");
1861 /* add socket options unless overriden by the user */
1862 if (strstr(nv, "socket options") == NULL) {
1863 fprintf(fp, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1865 fprintf(fp, "%s\n\n", nv);
1867 /* configure shares */
1869 char *buf;
1870 char *p, *q;
1871 char *name, *path, *comment, *writeable, *hidden;
1872 int cnt = 0;
1874 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1876 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1878 p = buf;
1879 while ((q = strsep(&p, ">")) != NULL) {
1880 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1881 if (!path || !name) continue;
1883 /* share name */
1884 fprintf(fp, "\n[%s]\n", name);
1886 /* path */
1887 fprintf(fp, " path = %s\n", path);
1889 /* access level */
1890 if (!strcmp(writeable, "1"))
1891 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1892 if (!strcmp(hidden, "1"))
1893 fprintf(fp, " browseable = no\n");
1895 /* comment */
1896 if (comment)
1897 fprintf(fp, " comment = %s\n", comment);
1899 cnt++;
1901 free(buf);
1904 /* Share every mountpoint below MOUNT_ROOT */
1905 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1906 while ((dp = readdir(dir))) {
1907 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1909 /* Only if is a directory and is mounted */
1910 if (!dir_is_mountpoint(MOUNT_ROOT, dp->d_name))
1911 continue;
1913 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1914 fprintf(fp, "\n[%s]\n path = %s/%s\n comment = %s\n",
1915 dp->d_name, MOUNT_ROOT, dp->d_name, dp->d_name);
1916 if (nvram_match("smbd_autoshare", "3")) // Hidden
1917 fprintf(fp, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1918 dp->d_name, MOUNT_ROOT, dp->d_name);
1919 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1920 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1922 cnt++;
1926 if (dir) closedir(dir);
1928 if (cnt == 0) {
1929 /* by default share MOUNT_ROOT as read-only */
1930 fprintf(fp, "\n[share]\n"
1931 " path = %s\n"
1932 " writable = no\n",
1933 MOUNT_ROOT);
1936 fclose(fp);
1938 mkdir_if_none("/var/run/samba");
1939 mkdir_if_none("/etc/samba");
1941 /* write smbpasswd */
1942 #ifdef TCONFIG_SAMBA3
1943 eval("smbpasswd", "nobody", "\"\"");
1944 #else
1945 eval("smbpasswd", "-a", "nobody", "\"\"");
1946 #endif
1947 if (mode == 2) {
1948 char *smbd_user;
1949 if (((smbd_user = nvram_get("smbd_user")) == NULL) || (*smbd_user == 0) || !strcmp(smbd_user, "root"))
1950 smbd_user = "nas";
1951 #ifdef TCONFIG_SAMBA3
1952 eval("smbpasswd", smbd_user, nvram_safe_get("smbd_passwd"));
1953 #else
1954 eval("smbpasswd", "-a", smbd_user, nvram_safe_get("smbd_passwd"));
1955 #endif
1958 kill_samba(SIGHUP);
1959 int ret1 = 0, ret2 = 0;
1960 /* start samba if it's not already running */
1961 if (pidof("nmbd") <= 0)
1962 ret1 = xstart("nmbd", "-D");
1963 if (pidof("smbd") <= 0)
1964 ret2 = xstart("smbd", "-D");
1966 if (ret1 || ret2) kill_samba(SIGTERM);
1969 static void stop_samba(void)
1971 if (getpid() != 1) {
1972 stop_service("smbd");
1973 return;
1976 kill_samba(SIGTERM);
1977 /* clean up */
1978 unlink("/var/log/smb");
1979 unlink("/var/log/nmb");
1980 eval("rm", "-rf", "/var/run/samba");
1982 #endif // TCONFIG_SAMBASRV
1984 #ifdef TCONFIG_MEDIA_SERVER
1985 #define MEDIA_SERVER_APP "minidlna"
1987 static void start_media_server(void)
1989 FILE *f;
1990 int port, pid, https;
1991 char *dbdir;
1992 char *argv[] = { MEDIA_SERVER_APP, "-f", "/etc/"MEDIA_SERVER_APP".conf", "-R", NULL };
1993 static int once = 1;
1995 if (getpid() != 1) {
1996 start_service("media");
1997 return;
2000 if (nvram_get_int("ms_sas") == 0)
2001 once = 0;
2003 if (nvram_get_int("ms_enable") != 0) {
2004 if ((!once) && (nvram_get_int("ms_rescan") == 0)) {
2005 // no forced rescan
2006 argv[3] = NULL;
2008 nvram_unset("ms_rescan");
2010 if (f_exists("/etc/"MEDIA_SERVER_APP".alt")) {
2011 argv[2] = "/etc/"MEDIA_SERVER_APP".alt";
2013 else {
2014 if ((f = fopen(argv[2], "w")) != NULL) {
2015 port = nvram_get_int("ms_port");
2016 https = nvram_get_int("https_enable");
2017 dbdir = nvram_safe_get("ms_dbdir");
2018 if (!(*dbdir)) dbdir = NULL;
2019 mkdir_if_none(dbdir ? : "/var/run/"MEDIA_SERVER_APP);
2021 fprintf(f,
2022 "network_interface=%s\n"
2023 "port=%d\n"
2024 "friendly_name=%s\n"
2025 "db_dir=%s/.db\n"
2026 "enable_tivo=%s\n"
2027 "strict_dlna=%s\n"
2028 "presentation_url=http%s://%s:%s/nas-media.asp\n"
2029 "inotify=yes\n"
2030 "notify_interval=600\n"
2031 "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"
2032 "\n",
2033 nvram_safe_get("lan_ifname"),
2034 (port < 0) || (port >= 0xffff) ? 0 : port,
2035 nvram_get("router_name") ? : "Tomato",
2036 dbdir ? : "/var/run/"MEDIA_SERVER_APP,
2037 nvram_get_int("ms_tivo") ? "yes" : "no",
2038 nvram_get_int("ms_stdlna") ? "yes" : "no",
2039 https ? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https ? "https_lanport" : "http_lanport")
2042 // media directories
2043 char *buf, *p, *q;
2044 char *path, *restrict;
2046 if ((buf = strdup(nvram_safe_get("ms_dirs"))) != NULL) {
2047 /* path<restrict[A|V|P|] */
2049 p = buf;
2050 while ((q = strsep(&p, ">")) != NULL) {
2051 if (vstrsep(q, "<", &path, &restrict) < 1 || !path || !(*path))
2052 continue;
2053 fprintf(f, "media_dir=%s%s%s\n",
2054 restrict ? : "", (restrict && *restrict) ? "," : "", path);
2056 free(buf);
2059 fclose(f);
2063 /* start media server if it's not already running */
2064 if (pidof(MEDIA_SERVER_APP) <= 0) {
2065 if ((_eval(argv, NULL, 0, &pid) == 0) && (once)) {
2066 /* If we started the media server successfully, wait 1 sec
2067 * to let it die if it can't open the database file.
2068 * If it's still alive after that, assume it's running and
2069 * disable forced once-after-reboot rescan.
2071 sleep(1);
2072 if (pidof(MEDIA_SERVER_APP) > 0)
2073 once = 0;
2079 static void stop_media_server(void)
2081 if (getpid() != 1) {
2082 stop_service("media");
2083 return;
2086 killall_tk(MEDIA_SERVER_APP);
2088 #endif // TCONFIG_MEDIA_SERVER
2090 #ifdef TCONFIG_USB
2091 static void start_nas_services(void)
2093 if (getpid() != 1) {
2094 start_service("usbapps");
2095 return;
2098 #ifdef TCONFIG_SAMBASRV
2099 start_samba();
2100 #endif
2101 #ifdef TCONFIG_FTP
2102 start_ftpd();
2103 #endif
2104 #ifdef TCONFIG_MEDIA_SERVER
2105 start_media_server();
2106 #endif
2109 static void stop_nas_services(void)
2111 if (getpid() != 1) {
2112 stop_service("usbapps");
2113 return;
2116 #ifdef TCONFIG_MEDIA_SERVER
2117 stop_media_server();
2118 #endif
2119 #ifdef TCONFIG_FTP
2120 stop_ftpd();
2121 #endif
2122 #ifdef TCONFIG_SAMBASRV
2123 stop_samba();
2124 #endif
2127 void restart_nas_services(int stop, int start)
2129 int fd = file_lock("usb");
2130 /* restart all NAS applications */
2131 if (stop)
2132 stop_nas_services();
2133 if (start)
2134 start_nas_services();
2135 file_unlock(fd);
2137 #endif // TCONFIG_USB
2139 // -----------------------------------------------------------------------------
2141 /* -1 = Don't check for this program, it is not expected to be running.
2142 * Other = This program has been started and should be kept running. If no
2143 * process with the name is running, call func to restart it.
2144 * Note: At startup, dnsmasq forks a short-lived child which forks a
2145 * long-lived (grand)child. The parents terminate.
2146 * Many daemons use this technique.
2148 static void _check(pid_t pid, const char *name, void (*func)(void))
2150 if (pid == -1) return;
2152 if (pidof(name) > 0) return;
2154 syslog(LOG_DEBUG, "%s terminated unexpectedly, restarting.\n", name);
2155 func();
2157 // Force recheck in 500 msec
2158 setitimer(ITIMER_REAL, &pop_tv, NULL);
2161 void check_services(void)
2163 TRACE_PT("keep alive\n");
2165 // Periodically reap any zombies
2166 setitimer(ITIMER_REAL, &zombie_tv, NULL);
2168 #ifdef LINUX26
2169 _check(pid_hotplug2, "hotplug2", start_hotplug2);
2170 #endif
2171 _check(pid_dnsmasq, "dnsmasq", start_dnsmasq);
2172 _check(pid_crond, "crond", start_cron);
2173 _check(pid_igmp, "igmpproxy", start_igmp_proxy);
2174 #ifdef TCONFIG_IPV6
2175 _check(pid_radvd, "radvd", start_radvd);
2176 #endif
2178 //#ifdef TCONFIG_NOCAT
2179 // if (nvram_get_int("NC_enable"))
2180 // _check(&pid_splashd, "splashd", start_splashd);
2181 //#endif
2185 // -----------------------------------------------------------------------------
2187 void start_services(void)
2189 static int once = 1;
2191 if (once) {
2192 once = 0;
2194 if (nvram_get_int("telnetd_eas")) start_telnetd();
2195 if (nvram_get_int("sshd_eas")) start_sshd();
2198 // start_syslog();
2199 start_nas();
2200 start_zebra();
2201 #ifdef TCONFIG_SDHC
2202 start_mmc();
2203 #endif
2204 start_dnsmasq();
2205 start_cifs();
2206 start_httpd();
2207 start_cron();
2208 // start_upnp();
2209 start_rstats(0);
2210 start_cstats(0);
2211 start_sched();
2212 #ifdef TCONFIG_PPTPD
2213 start_pptpd();
2214 #endif
2215 #ifdef TCONFIG_IPV6
2216 /* note: starting radvd here might be too early in case of
2217 * DHCPv6 or 6to4 because we won't have received a prefix and
2218 * so it will disable advertisements. To restart them, we have
2219 * to send radvd a SIGHUP, or restart it.
2221 start_radvd();
2222 #endif
2223 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
2225 #ifdef TCONFIG_SNMP
2226 start_snmp();
2227 #endif
2229 start_tomatoanon();
2231 #ifdef TCONFIG_TOR
2232 start_tor();
2233 #endif
2235 #ifdef TCONFIG_BT
2236 start_bittorrent();
2237 #endif
2239 #ifdef TCONFIG_NOCAT
2240 start_splashd();
2241 #endif
2243 #ifdef TCONFIG_NFS
2244 start_nfs();
2245 #endif
2248 void stop_services(void)
2250 clear_resolv();
2252 #ifdef TCONFIG_BT
2253 stop_bittorrent();
2254 #endif
2256 #ifdef TCONFIG_NOCAT
2257 stop_splashd();
2258 #endif
2260 #ifdef TCONFIG_SNMP
2261 stop_snmp();
2262 #endif
2264 #ifdef TCONFIG_TOR
2265 stop_tor();
2266 #endif
2268 stop_tomatoanon();
2270 #ifdef TCONFIG_NFS
2271 stop_nfs();
2272 #endif
2273 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2274 #ifdef TCONFIG_IPV6
2275 stop_radvd();
2276 #endif
2277 #ifdef TCONFIG_PPTPD
2278 stop_pptpd();
2279 #endif
2280 stop_sched();
2281 stop_rstats();
2282 stop_cstats();
2283 // stop_upnp();
2284 stop_cron();
2285 stop_httpd();
2286 #ifdef TCONFIG_SDHC
2287 stop_mmc();
2288 #endif
2289 stop_cifs();
2290 stop_dnsmasq();
2291 stop_zebra();
2292 stop_nas();
2293 // stop_syslog();
2296 // -----------------------------------------------------------------------------
2298 /* nvram "action_service" is: "service-action[-modifier]"
2299 * action is something like "stop" or "start" or "restart"
2300 * optional modifier is "c" for the "service" command-line command
2302 void exec_service(void)
2304 const int A_START = 1;
2305 const int A_STOP = 2;
2306 const int A_RESTART = 1|2;
2307 char buffer[128];
2308 char *service;
2309 char *act;
2310 char *next;
2311 char *modifier;
2312 int action, user;
2313 int i;
2315 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
2316 next = buffer;
2318 TOP:
2319 act = strsep(&next, ",");
2320 service = strsep(&act, "-");
2321 if (act == NULL) {
2322 next = NULL;
2323 goto CLEAR;
2325 modifier = act;
2326 strsep(&modifier, "-");
2328 TRACE_PT("service=%s action=%s modifier=%s\n", service, act, modifier ? : "");
2330 if (strcmp(act, "start") == 0) action = A_START;
2331 else if (strcmp(act, "stop") == 0) action = A_STOP;
2332 else if (strcmp(act, "restart") == 0) action = A_RESTART;
2333 else action = 0;
2334 user = (modifier != NULL && *modifier == 'c');
2336 if (strcmp(service, "dhcpc") == 0) {
2337 if (action & A_STOP) stop_dhcpc();
2338 if (action & A_START) start_dhcpc();
2339 goto CLEAR;
2342 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
2343 if (action & A_STOP) stop_dnsmasq();
2344 if (action & A_START) {
2345 dns_to_resolv();
2346 start_dnsmasq();
2348 goto CLEAR;
2351 if (strcmp(service, "firewall") == 0) {
2352 if (action & A_STOP) {
2353 stop_firewall();
2354 stop_igmp_proxy();
2355 stop_udpxy();
2357 if (action & A_START) {
2358 start_firewall();
2359 start_igmp_proxy();
2360 start_udpxy();
2362 goto CLEAR;
2365 if (strcmp(service, "restrict") == 0) {
2366 if (action & A_STOP) {
2367 stop_firewall();
2369 if (action & A_START) {
2370 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
2372 start_firewall();
2374 // if radio was disabled by access restriction, but no rule is handling it now, enable it
2375 if (i == 1) {
2376 if (nvram_get_int("rrules_radio") < 0) {
2377 eval("radio", "on");
2381 goto CLEAR;
2384 if (strcmp(service, "arpbind") == 0) {
2385 if (action & A_STOP) stop_arpbind();
2386 if (action & A_START) start_arpbind();
2387 goto CLEAR;
2390 if (strcmp(service, "qos") == 0) {
2391 if (action & A_STOP) {
2392 stop_qos();
2394 stop_firewall(); start_firewall(); // always restarted
2395 if (action & A_START) {
2396 start_qos();
2397 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
2399 goto CLEAR;
2402 if (strcmp(service, "qoslimit") == 0) {
2403 if (action & A_STOP) {
2404 new_qoslimit_stop();
2406 #ifdef TCONFIG_NOCAT
2407 stop_splashd();
2408 #endif
2409 stop_firewall(); start_firewall(); // always restarted
2410 if (action & A_START) {
2411 new_qoslimit_start();
2413 #ifdef TCONFIG_NOCAT
2414 start_splashd();
2415 #endif
2416 goto CLEAR;
2419 if (strcmp(service, "upnp") == 0) {
2420 if (action & A_STOP) {
2421 stop_upnp();
2423 stop_firewall(); start_firewall(); // always restarted
2424 if (action & A_START) {
2425 start_upnp();
2427 goto CLEAR;
2430 if (strcmp(service, "telnetd") == 0) {
2431 if (action & A_STOP) stop_telnetd();
2432 if (action & A_START) start_telnetd();
2433 goto CLEAR;
2436 if (strcmp(service, "sshd") == 0) {
2437 if (action & A_STOP) stop_sshd();
2438 if (action & A_START) start_sshd();
2439 goto CLEAR;
2442 if (strcmp(service, "httpd") == 0) {
2443 if (action & A_STOP) stop_httpd();
2444 if (action & A_START) start_httpd();
2445 goto CLEAR;
2448 #ifdef TCONFIG_IPV6
2449 if (strcmp(service, "ipv6") == 0) {
2450 if (action & A_STOP) {
2451 stop_radvd();
2452 stop_ipv6();
2454 if (action & A_START) {
2455 start_ipv6();
2456 start_radvd();
2458 goto CLEAR;
2461 if (strcmp(service, "radvd") == 0) {
2462 if (action & A_STOP) {
2463 stop_radvd();
2465 if (action & A_START) {
2466 start_radvd();
2468 goto CLEAR;
2471 if (strncmp(service, "dhcp6", 5) == 0) {
2472 if (action & A_STOP) {
2473 stop_dhcp6c();
2475 if (action & A_START) {
2476 start_dhcp6c();
2478 goto CLEAR;
2480 #endif
2482 if (strcmp(service, "admin") == 0) {
2483 if (action & A_STOP) {
2484 stop_sshd();
2485 stop_telnetd();
2486 stop_httpd();
2488 stop_firewall(); start_firewall(); // always restarted
2489 if (action & A_START) {
2490 start_httpd();
2491 create_passwd();
2492 if (nvram_match("telnetd_eas", "1")) start_telnetd();
2493 if (nvram_match("sshd_eas", "1")) start_sshd();
2495 goto CLEAR;
2498 if (strcmp(service, "ddns") == 0) {
2499 if (action & A_STOP) stop_ddns();
2500 if (action & A_START) start_ddns();
2501 goto CLEAR;
2504 if (strcmp(service, "ntpc") == 0) {
2505 if (action & A_STOP) stop_ntpc();
2506 if (action & A_START) start_ntpc();
2507 goto CLEAR;
2510 if (strcmp(service, "logging") == 0) {
2511 if (action & A_STOP) {
2512 stop_syslog();
2514 if (action & A_START) {
2515 start_syslog();
2517 if (!user) {
2518 // always restarted except from "service" command
2519 stop_cron(); start_cron();
2520 stop_firewall(); start_firewall();
2522 goto CLEAR;
2525 if (strcmp(service, "crond") == 0) {
2526 if (action & A_STOP) {
2527 stop_cron();
2529 if (action & A_START) {
2530 start_cron();
2532 goto CLEAR;
2535 #ifdef LINUX26
2536 if (strncmp(service, "hotplug", 7) == 0) {
2537 if (action & A_STOP) {
2538 stop_hotplug2();
2540 if (action & A_START) {
2541 start_hotplug2(1);
2543 goto CLEAR;
2545 #endif
2547 if (strcmp(service, "upgrade") == 0) {
2548 if (action & A_START) {
2549 #if TOMATO_SL
2550 stop_usbevent();
2551 stop_smbd();
2552 #endif
2553 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2554 stop_jffs2();
2555 // stop_cifs();
2556 stop_zebra();
2557 stop_cron();
2558 stop_ntpc();
2559 stop_upnp();
2560 // stop_dhcpc();
2561 killall("rstats", SIGTERM);
2562 killall("cstats", SIGTERM);
2563 killall("buttons", SIGTERM);
2564 stop_syslog();
2565 remove_storage_main(1); // !!TB - USB Support
2566 stop_usb(); // !!TB - USB Support
2568 goto CLEAR;
2571 #ifdef TCONFIG_CIFS
2572 if (strcmp(service, "cifs") == 0) {
2573 if (action & A_STOP) stop_cifs();
2574 if (action & A_START) start_cifs();
2575 goto CLEAR;
2577 #endif
2579 #ifdef TCONFIG_JFFS2
2580 if (strncmp(service, "jffs", 4) == 0) {
2581 if (action & A_STOP) stop_jffs2();
2582 if (action & A_START) start_jffs2();
2583 goto CLEAR;
2585 #endif
2587 if (strcmp(service, "zebra") == 0) {
2588 if (action & A_STOP) stop_zebra();
2589 if (action & A_START) start_zebra();
2590 goto CLEAR;
2593 #ifdef TCONFIG_SDHC
2594 if (strcmp(service, "mmc") == 0) {
2595 if (action & A_STOP) stop_mmc();
2596 if (action & A_START) start_mmc();
2597 goto CLEAR;
2599 #endif
2601 if (strcmp(service, "routing") == 0) {
2602 if (action & A_STOP) {
2603 stop_zebra();
2604 do_static_routes(0); // remove old '_saved'
2605 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2606 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2607 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), "0");
2608 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2609 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), "0");
2610 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2611 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), "0");
2613 stop_firewall();
2614 start_firewall();
2615 if (action & A_START) {
2616 do_static_routes(1); // add new
2617 start_zebra();
2618 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2619 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2620 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), nvram_safe_get("lan1_stp"));
2621 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2622 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), nvram_safe_get("lan2_stp"));
2623 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2624 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), nvram_safe_get("lan3_stp"));
2626 goto CLEAR;
2629 if (strcmp(service, "ctnf") == 0) {
2630 if (action & A_START) {
2631 setup_conntrack();
2632 stop_firewall();
2633 start_firewall();
2635 goto CLEAR;
2638 if (strcmp(service, "wan") == 0) {
2639 if (action & A_STOP) {
2640 stop_wan();
2643 if (action & A_START) {
2644 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2645 start_wan(BOOT);
2646 sleep(2);
2647 force_to_dial();
2649 goto CLEAR;
2652 if (strcmp(service, "net") == 0) {
2653 if (action & A_STOP) {
2654 #ifdef TCONFIG_USB
2655 stop_nas_services();
2656 #endif
2657 #ifdef TCONFIG_IPV6
2658 stop_radvd();
2659 #endif
2660 stop_httpd();
2661 stop_dnsmasq();
2662 stop_nas();
2663 stop_wan();
2664 stop_arpbind();
2665 stop_lan();
2666 stop_vlan();
2668 if (action & A_START) {
2669 start_vlan();
2670 start_lan();
2671 start_arpbind();
2672 start_wan(BOOT);
2673 start_nas();
2674 start_dnsmasq();
2675 start_httpd();
2676 #ifdef TCONFIG_IPV6
2677 start_radvd();
2678 #endif
2679 start_wl();
2680 #ifdef TCONFIG_USB
2681 start_nas_services();
2682 #endif
2684 goto CLEAR;
2687 if (strcmp(service, "wireless") == 0) {
2688 if(action & A_STOP) {
2689 stop_wireless();
2691 if(action & A_START) {
2692 start_wireless();
2694 goto CLEAR;
2697 if (strcmp(service, "wl") == 0) {
2698 if(action & A_STOP) {
2699 stop_wireless();
2700 unload_wl();
2702 if(action & A_START) {
2703 load_wl();
2704 start_wireless();
2705 stop_wireless();
2706 start_wireless();
2708 goto CLEAR;
2711 if (strcmp(service, "nas") == 0) {
2712 if (action & A_STOP) {
2713 stop_nas();
2715 if (action & A_START) {
2716 start_nas();
2717 start_wl();
2719 goto CLEAR;
2722 if (strcmp(service, "rstats") == 0) {
2723 if (action & A_STOP) stop_rstats();
2724 if (action & A_START) start_rstats(0);
2725 goto CLEAR;
2728 if (strcmp(service, "rstatsnew") == 0) {
2729 if (action & A_STOP) stop_rstats();
2730 if (action & A_START) start_rstats(1);
2731 goto CLEAR;
2734 if (strcmp(service, "cstats") == 0) {
2735 if (action & A_STOP) stop_cstats();
2736 if (action & A_START) start_cstats(0);
2737 goto CLEAR;
2740 if (strcmp(service, "cstatsnew") == 0) {
2741 if (action & A_STOP) stop_cstats();
2742 if (action & A_START) start_cstats(1);
2743 goto CLEAR;
2746 if (strcmp(service, "sched") == 0) {
2747 if (action & A_STOP) stop_sched();
2748 if (action & A_START) start_sched();
2749 goto CLEAR;
2752 #ifdef TCONFIG_BT
2753 if (strcmp(service, "bittorrent") == 0) {
2754 if (action & A_STOP) {
2755 stop_bittorrent();
2757 stop_firewall(); start_firewall(); // always restarted
2758 if (action & A_START) {
2759 start_bittorrent();
2761 goto CLEAR;
2763 #endif
2765 #ifdef TCONFIG_NFS
2766 if (strcmp(service, "nfs") == 0) {
2767 if (action & A_STOP) stop_nfs();
2768 if (action & A_START) start_nfs();
2769 goto CLEAR;
2771 #endif
2773 #ifdef TCONFIG_SNMP
2774 if (strcmp(service, "snmp") == 0) {
2775 if (action & A_STOP) stop_snmp();
2776 if (action & A_START) start_snmp();
2777 goto CLEAR;
2779 #endif
2781 #ifdef TCONFIG_TOR
2782 if (strcmp(service, "tor") == 0) {
2783 if (action & A_STOP) stop_tor();
2785 stop_firewall(); start_firewall(); // always restarted
2787 if (action & A_START) start_tor();
2788 goto CLEAR;
2790 #endif
2792 #ifdef TCONFIG_UPS
2793 if (strcmp(service, "ups") == 0) {
2794 if (action & A_STOP) stop_ups();
2795 if (action & A_START) start_ups();
2796 goto CLEAR;
2798 #endif
2800 if (strcmp(service, "tomatoanon") == 0) {
2801 if (action & A_STOP) stop_tomatoanon();
2802 if (action & A_START) start_tomatoanon();
2803 goto CLEAR;
2806 #ifdef TCONFIG_USB
2807 // !!TB - USB Support
2808 if (strcmp(service, "usb") == 0) {
2809 if (action & A_STOP) stop_usb();
2810 if (action & A_START) {
2811 start_usb();
2812 // restart Samba and ftp since they may be killed by stop_usb()
2813 restart_nas_services(0, 1);
2814 // remount all partitions by simulating hotplug event
2815 add_remove_usbhost("-1", 1);
2817 goto CLEAR;
2820 if (strcmp(service, "usbapps") == 0) {
2821 if (action & A_STOP) stop_nas_services();
2822 if (action & A_START) start_nas_services();
2823 goto CLEAR;
2825 #endif
2827 #ifdef TCONFIG_FTP
2828 // !!TB - FTP Server
2829 if (strcmp(service, "ftpd") == 0) {
2830 if (action & A_STOP) stop_ftpd();
2831 setup_conntrack();
2832 stop_firewall();
2833 start_firewall();
2834 if (action & A_START) start_ftpd();
2835 goto CLEAR;
2837 #endif
2839 #ifdef TCONFIG_MEDIA_SERVER
2840 if (strcmp(service, "media") == 0 || strcmp(service, "dlna") == 0) {
2841 if (action & A_STOP) stop_media_server();
2842 if (action & A_START) start_media_server();
2843 goto CLEAR;
2845 #endif
2847 #ifdef TCONFIG_SAMBASRV
2848 // !!TB - Samba
2849 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
2850 if (action & A_STOP) stop_samba();
2851 if (action & A_START) {
2852 create_passwd();
2853 stop_dnsmasq();
2854 start_dnsmasq();
2855 start_samba();
2857 goto CLEAR;
2859 #endif
2861 #ifdef TCONFIG_OPENVPN
2862 if (strncmp(service, "vpnclient", 9) == 0) {
2863 if (action & A_STOP) stop_vpnclient(atoi(&service[9]));
2864 if (action & A_START) start_vpnclient(atoi(&service[9]));
2865 goto CLEAR;
2868 if (strncmp(service, "vpnserver", 9) == 0) {
2869 if (action & A_STOP) stop_vpnserver(atoi(&service[9]));
2870 if (action & A_START) start_vpnserver(atoi(&service[9]));
2871 goto CLEAR;
2873 #endif
2875 #ifdef TCONFIG_NOCAT
2876 if (strcmp(service, "splashd") == 0) {
2877 if (action & A_STOP) stop_splashd();
2878 if (action & A_START) start_splashd();
2879 goto CLEAR;
2881 #endif
2883 #ifdef TCONFIG_PPTPD
2884 if (strcmp(service, "pptpd") == 0) {
2885 if (action & A_STOP) stop_pptpd();
2886 if (action & A_START) start_pptpd();
2887 goto CLEAR;
2889 #endif
2891 #ifdef TCONFIG_PPTPD
2892 if (strcmp(service, "pptpclient") == 0) {
2893 if (action & A_STOP) stop_pptp_client();
2894 if (action & A_START) start_pptp_client();
2895 if (action & (A_START | A_STOP))
2897 stop_dnsmasq();
2898 dns_to_resolv();
2899 start_dnsmasq();
2900 if ((action & A_START) == 0)
2901 clear_pptp_route();
2903 goto CLEAR;
2905 #endif
2907 CLEAR:
2908 if (next) goto TOP;
2910 // some functions check action_service and must be cleared at end -- zzz
2911 nvram_set("action_service", "");
2913 // Force recheck in 500 msec
2914 setitimer(ITIMER_REAL, &pop_tv, NULL);
2917 static void do_service(const char *name, const char *action, int user)
2919 int n;
2920 char s[64];
2922 n = 150;
2923 while (!nvram_match("action_service", "")) {
2924 if (user) {
2925 putchar('*');
2926 fflush(stdout);
2928 else if (--n < 0) break;
2929 usleep(100 * 1000);
2932 snprintf(s, sizeof(s), "%s-%s%s", name, action, (user ? "-c" : ""));
2933 nvram_set("action_service", s);
2935 if (nvram_match("debug_rc_svc", "1")) {
2936 nvram_unset("debug_rc_svc");
2937 exec_service();
2938 } else {
2939 kill(1, SIGUSR1);
2942 n = 150;
2943 while (nvram_match("action_service", s)) {
2944 if (user) {
2945 putchar('.');
2946 fflush(stdout);
2948 else if (--n < 0) {
2949 break;
2951 usleep(100 * 1000);
2955 int service_main(int argc, char *argv[])
2957 if (argc != 3) usage_exit(argv[0], "<service> <action>");
2958 do_service(argv[1], argv[2], 1);
2959 printf("\nDone.\n");
2960 return 0;
2963 void start_service(const char *name)
2965 do_service(name, "start", 0);
2968 void stop_service(const char *name)
2970 do_service(name, "stop", 0);
2974 void restart_service(const char *name)
2976 do_service(name, "restart", 0);