MiniDLNA update: 1.0.19.1 to 1.0.20
[tomato.git] / release / src / router / rc / services.c
blob65dabbfcee75056c4fcc4b991bbf00763a77158d
1 /*
3 Copyright 2003, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Copyright 2005, Broadcom Corporation
22 All Rights Reserved.
24 THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
25 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
26 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
27 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
32 Modified for Tomato Firmware
33 Portions, Copyright (C) 2006-2009 Jonathan Zarate
36 #include "rc.h"
38 #include <arpa/inet.h>
39 #include <time.h>
40 #include <sys/time.h>
41 #include <errno.h>
43 // !!TB
44 #include <sys/mount.h>
45 #include <mntent.h>
46 #include <dirent.h>
48 // Pop an alarm to recheck pids in 500 msec.
49 static const struct itimerval pop_tv = { {0,0}, {0, 500 * 1000} };
51 // Pop an alarm to reap zombies.
52 static const struct itimerval zombie_tv = { {0,0}, {307, 0} };
54 // -----------------------------------------------------------------------------
56 static const char dmhosts[] = "/etc/dnsmasq/hosts";
57 static const char dmdhcp[] = "/etc/dnsmasq/dhcp";
58 static const char dmresolv[] = "/etc/resolv.dnsmasq";
60 static pid_t pid_dnsmasq = -1;
62 static int is_wet(int idx, int unit, int subunit, void *param)
64 return nvram_match(wl_nvname("mode", unit, subunit), "wet");
67 void start_dnsmasq()
69 FILE *f;
70 const char *nv;
71 char buf[512];
72 char lan[24];
73 const char *router_ip;
74 const char *lan_ifname;
75 char sdhcp_lease[32];
76 char *e;
77 int n;
78 char *mac, *ip, *name;
79 char *p;
80 int ipn;
81 char ipbuf[32];
82 FILE *hf, *df;
83 int dhcp_start;
84 int dhcp_count;
85 int dhcp_lease;
86 int do_dhcpd;
87 int do_dns;
89 TRACE_PT("begin\n");
91 if (getpid() != 1) {
92 start_service("dnsmasq");
93 return;
96 stop_dnsmasq();
98 if (foreach_wif(1, NULL, is_wet)) return;
100 if ((f = fopen("/etc/dnsmasq.conf", "w")) == NULL) return;
102 lan_ifname = nvram_safe_get("lan_ifname");
103 router_ip = nvram_safe_get("lan_ipaddr");
104 strlcpy(lan, router_ip, sizeof(lan));
105 if ((p = strrchr(lan, '.')) != NULL) *(p + 1) = 0;
107 fprintf(f,
108 "pid-file=/var/run/dnsmasq.pid\n"
109 "interface=%s\n",
110 lan_ifname);
111 if (((nv = nvram_get("wan_domain")) != NULL) || ((nv = nvram_get("wan_get_domain")) != NULL)) {
112 if (*nv) fprintf(f, "domain=%s\n", nv);
115 // dns
116 const dns_list_t *dns = get_dns(); // this always points to a static buffer
118 if (((nv = nvram_get("dns_minport")) != NULL) && (*nv)) n = atoi(nv);
119 else n = 4096;
120 fprintf(f,
121 "resolv-file=%s\n" // the real stuff is here
122 "addn-hosts=%s\n" // directory with additional hosts files
123 "dhcp-hostsfile=%s\n" // directory with dhcp hosts files
124 "expand-hosts\n" // expand hostnames in hosts file
125 "min-port=%u\n", // min port used for random src port
126 dmresolv, dmhosts, dmdhcp, n);
127 do_dns = nvram_match("dhcpd_dmdns", "1");
129 // DNS rebinding protection, will discard upstream RFC1918 responses
130 if (nvram_get_int("dns_norebind")) {
131 fprintf(f,
132 "stop-dns-rebind\n"
133 "rebind-localhost-ok\n");
134 // allow RFC1918 responses for server domain
135 switch (get_wan_proto()) {
136 case WP_PPTP:
137 nv = nvram_get("pptp_server_ip");
138 break;
139 case WP_L2TP:
140 nv = nvram_get("l2tp_server_ip");
141 break;
142 default:
143 nv = NULL;
144 break;
146 if (nv && *nv) fprintf(f, "rebind-domain-ok=%s\n", nv);
149 for (n = 0 ; n < dns->count; ++n) {
150 if (dns->dns[n].port != 53) {
151 fprintf(f, "server=%s#%u\n", inet_ntoa(dns->dns[n].addr), dns->dns[n].port);
155 // dhcp
156 do_dhcpd = nvram_match("lan_proto", "dhcp");
157 if (do_dhcpd) {
158 dhcp_lease = nvram_get_int("dhcp_lease");
159 if (dhcp_lease <= 0) dhcp_lease = 1440;
161 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
162 if (n < 0) strcpy(sdhcp_lease, "infinite");
163 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
165 if (!do_dns) {
166 // if not using dnsmasq for dns
168 if ((dns->count == 0) && (nvram_get_int("dhcpd_llndns"))) {
169 // no DNS might be temporary. use a low lease time to force clients to update.
170 dhcp_lease = 2;
171 strcpy(sdhcp_lease, "2m");
172 do_dns = 1;
174 else {
175 // pass the dns directly
176 buf[0] = 0;
177 for (n = 0 ; n < dns->count; ++n) {
178 if (dns->dns[n].port == 53) { // check: option 6 doesn't seem to support other ports
179 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n].addr));
182 fprintf(f, "dhcp-option=6%s\n", buf);
186 if ((p = nvram_get("dhcpd_startip")) && (*p) && (e = nvram_get("dhcpd_endip")) && (*e)) {
187 fprintf(f, "dhcp-range=%s,%s,%s,%dm\n", p, e, nvram_safe_get("lan_netmask"), dhcp_lease);
189 else {
190 // for compatibility
191 dhcp_start = nvram_get_int("dhcp_start");
192 dhcp_count = nvram_get_int("dhcp_num");
193 fprintf(f, "dhcp-range=%s%d,%s%d,%s,%dm\n",
194 lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get("lan_netmask"), dhcp_lease);
197 nv = router_ip;
198 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED)) {
199 p = nvram_safe_get("lan_gateway");
200 if ((*p) && (strcmp(p, "0.0.0.0") != 0)) nv = p;
203 n = nvram_get_int("dhcpd_lmax");
204 fprintf(f,
205 "dhcp-option=3,%s\n" // gateway
206 "dhcp-lease-max=%d\n",
208 (n > 0) ? n : 255);
210 if (nvram_get_int("dhcpd_auth") >= 0) {
211 fprintf(f, "dhcp-authoritative\n");
214 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
215 fprintf(f, "dhcp-option=44,%s\n", nv);
217 #ifdef TCONFIG_SAMBASRV
218 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
219 if ((nv == NULL) || (*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
220 // Samba will serve as a WINS server
221 fprintf(f, "dhcp-option=44,0.0.0.0\n");
224 #endif
226 else {
227 fprintf(f, "no-dhcp-interface=%s\n", lan_ifname);
230 // write static lease entries & create hosts file
232 mkdir_if_none(dmhosts);
233 snprintf(buf, sizeof(buf), "%s/hosts", dmhosts);
234 if ((hf = fopen(buf, "w")) != NULL) {
235 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
236 fprintf(hf, "%s %s\n", router_ip, nv);
237 #ifdef TCONFIG_SAMBASRV
238 else if (((nv = nvram_get("lan_hostname")) != NULL) && (*nv))
239 fprintf(hf, "%s %s\n", router_ip, nv);
240 #endif
241 p = (char *)get_wanip();
242 if ((*p == 0) || strcmp(p, "0.0.0.0") == 0)
243 p = "127.0.0.1";
244 fprintf(hf, "%s wan-ip\n", p);
245 if (nv && (*nv))
246 fprintf(hf, "%s %s-wan\n", p, nv);
249 mkdir_if_none(dmdhcp);
250 snprintf(buf, sizeof(buf), "%s/dhcp-hosts", dmdhcp);
251 df = fopen(buf, "w");
253 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
254 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
255 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 106 w/ delim
256 p = nvram_safe_get("dhcpd_static");
257 while ((e = strchr(p, '>')) != NULL) {
258 n = (e - p);
259 if (n > 105) {
260 p = e + 1;
261 continue;
264 strncpy(buf, p, n);
265 buf[n] = 0;
266 p = e + 1;
268 if ((e = strchr(buf, '<')) == NULL) continue;
269 *e = 0;
270 mac = buf;
272 ip = e + 1;
273 if ((e = strchr(ip, '<')) == NULL) continue;
274 *e = 0;
275 if (strchr(ip, '.') == NULL) {
276 ipn = atoi(ip);
277 if ((ipn <= 0) || (ipn > 255)) continue;
278 sprintf(ipbuf, "%s%d", lan, ipn);
279 ip = ipbuf;
281 else {
282 if (inet_addr(ip) == INADDR_NONE) continue;
285 name = e + 1;
287 if ((hf) && (*name != 0)) {
288 fprintf(hf, "%s %s\n", ip, name);
291 if ((do_dhcpd) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
292 if (df)
293 fprintf(df, "%s,%s,%s\n", mac, ip, sdhcp_lease);
294 else
295 fprintf(f, "dhcp-host=%s,%s,%s\n", mac, ip, sdhcp_lease);
299 if (df) fclose(df);
300 if (hf) fclose(hf);
304 #ifdef TCONFIG_OPENVPN
305 write_vpn_dnsmasq_config(f);
306 #endif
308 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
310 fappend(f, "/etc/dnsmasq.custom");
314 fclose(f);
316 if (do_dns) {
317 unlink("/etc/resolv.conf");
318 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
321 TRACE_PT("run dnsmasq\n");
323 // Default to some values we like, but allow the user to override them.
324 eval("dnsmasq", "-c", "1500", "--log-async");
326 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
327 pid_dnsmasq = -2;
330 TRACE_PT("end\n");
333 void stop_dnsmasq(void)
335 TRACE_PT("begin\n");
337 if (getpid() != 1) {
338 stop_service("dnsmasq");
339 return;
342 pid_dnsmasq = -1;
344 unlink("/etc/resolv.conf");
345 symlink(dmresolv, "/etc/resolv.conf");
347 killall_tk("dnsmasq");
349 TRACE_PT("end\n");
352 void clear_resolv(void)
354 f_write(dmresolv, NULL, 0, 0, 0); // blank
357 #ifdef TCONFIG_IPV6
358 static int write_ipv6_dns_servers(FILE *f, const char *prefix, char *dns, const char *suffix, int once)
360 char p[INET6_ADDRSTRLEN + 1], *next = NULL;
361 struct in6_addr addr;
362 int cnt = 0;
364 foreach(p, dns, next) {
365 // verify that this is a valid IPv6 address
366 if (inet_pton(AF_INET6, p, &addr) == 1) {
367 fprintf(f, "%s%s%s", (once && cnt) ? "" : prefix, p, suffix);
368 ++cnt;
372 return cnt;
374 #endif
376 void dns_to_resolv(void)
378 FILE *f;
379 const dns_list_t *dns;
380 int i;
381 mode_t m;
383 m = umask(022); // 077 from pppoecd
384 if ((f = fopen(dmresolv, "w")) != NULL) {
385 // Check for VPN DNS entries
386 if (!write_vpn_resolv(f)) {
387 #ifdef TCONFIG_IPV6
388 if (write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_dns"), "\n", 0) == 0 || nvram_get_int("dns_addget"))
389 write_ipv6_dns_servers(f, "nameserver ", nvram_safe_get("ipv6_get_dns"), "\n", 0);
390 #endif
391 dns = get_dns(); // static buffer
392 if (dns->count == 0) {
393 // Put a pseudo DNS IP to trigger Connect On Demand
394 if (nvram_match("ppp_demand", "1")) {
395 switch (get_wan_proto()) {
396 case WP_PPPOE:
397 case WP_PPTP:
398 case WP_L2TP:
399 fprintf(f, "nameserver 1.1.1.1\n");
400 break;
404 else {
405 for (i = 0; i < dns->count; i++) {
406 if (dns->dns[i].port == 53) { // resolv.conf doesn't allow for an alternate port
407 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i].addr));
412 fclose(f);
414 umask(m);
417 // -----------------------------------------------------------------------------
419 void start_httpd(void)
421 if (getpid() != 1) {
422 start_service("httpd");
423 return;
426 stop_httpd();
427 chdir("/www");
428 eval("httpd");
429 chdir("/");
432 void stop_httpd(void)
434 if (getpid() != 1) {
435 stop_service("httpd");
436 return;
439 killall_tk("httpd");
442 // -----------------------------------------------------------------------------
443 #ifdef TCONFIG_IPV6
445 static void add_ip6_lanaddr(void)
447 char ip[INET6_ADDRSTRLEN + 4];
448 const char *p;
450 p = ipv6_router_address(NULL);
451 if (*p) {
452 snprintf(ip, sizeof(ip), "%s/%d", p, nvram_get_int("ipv6_prefix_length") ? : 64);
453 eval("ip", "-6", "addr", "add", ip, "dev", nvram_safe_get("lan_ifname"));
457 void start_ipv6_tunnel(void)
459 char ip[INET6_ADDRSTRLEN + 4];
460 struct in_addr addr4;
461 struct in6_addr addr;
462 const char *wanip, *mtu, *tun_dev;
463 int service;
465 service = get_ipv6_service();
466 tun_dev = get_wan6face();
467 wanip = get_wanip();
468 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
469 modprobe("sit");
471 if (service == IPV6_ANYCAST_6TO4)
472 snprintf(ip, sizeof(ip), "192.88.99.%d", nvram_get_int("ipv6_relay"));
473 else
474 strlcpy(ip, (char *)nvram_safe_get("ipv6_tun_v4end"), sizeof(ip));
475 eval("ip", "tunnel", "add", (char *)tun_dev, "mode", "sit",
476 "remote", ip,
477 "local", (char *)wanip,
478 "ttl", nvram_safe_get("ipv6_tun_ttl"));
480 eval("ip", "link", "set", (char *)tun_dev, "mtu", (char *)mtu, "up");
481 nvram_set("ipv6_ifname", (char *)tun_dev);
483 if (service == IPV6_ANYCAST_6TO4) {
484 add_ip6_lanaddr();
485 addr4.s_addr = 0;
486 memset(&addr, 0, sizeof(addr));
487 inet_aton(wanip, &addr4);
488 addr.s6_addr16[0] = htons(0x2002);
489 ipv6_mapaddr4(&addr, 16, &addr4, 0);
490 addr.s6_addr16[7] = htons(0x0001);
491 inet_ntop(AF_INET6, &addr, ip, sizeof(ip));
492 strncat(ip, "/16", sizeof(ip));
494 else {
495 snprintf(ip, sizeof(ip), "%s/%d",
496 nvram_safe_get("ipv6_tun_addr"),
497 nvram_get_int("ipv6_tun_addrlen") ? : 64);
499 eval("ip", "addr", "add", ip, "dev", (char *)tun_dev);
500 eval("ip", "route", "add", "::/0", "dev", (char *)tun_dev);
502 // (re)start radvd
503 if (service == IPV6_ANYCAST_6TO4)
504 start_radvd();
507 void stop_ipv6_tunnel(void)
509 eval("ip", "tunnel", "del", (char *)get_wan6face());
510 if (get_ipv6_service() == IPV6_ANYCAST_6TO4) {
511 // get rid of old IPv6 address from lan iface
512 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
514 modprobe_r("sit");
517 static pid_t pid_radvd = -1;
519 void start_radvd(void)
521 FILE *f;
522 char *prefix, *ip, *mtu;
523 int do_dns, do_6to4;
524 char *argv[] = { "radvd", NULL, NULL, NULL };
525 int pid, argc, service, cnt;
527 if (getpid() != 1) {
528 start_service("radvd");
529 return;
532 stop_radvd();
534 if (ipv6_enabled() && nvram_get_int("ipv6_radvd")) {
535 service = get_ipv6_service();
536 do_6to4 = (service == IPV6_ANYCAST_6TO4);
537 mtu = NULL;
539 switch (service) {
540 case IPV6_NATIVE_DHCP:
541 prefix = "::";
542 break;
543 case IPV6_ANYCAST_6TO4:
544 case IPV6_6IN4:
545 mtu = (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
546 // fall through
547 default:
548 prefix = do_6to4 ? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
549 break;
551 if (!(*prefix)) prefix = "::";
553 // Create radvd.conf
554 if ((f = fopen("/etc/radvd.conf", "w")) == NULL) return;
556 ip = (char *)ipv6_router_address(NULL);
557 do_dns = (*ip) && nvram_match("dhcpd_dmdns", "1");
559 fprintf(f,
560 "interface %s\n"
561 "{\n"
562 " IgnoreIfMissing on;\n"
563 " AdvSendAdvert on;\n"
564 " MaxRtrAdvInterval 60;\n"
565 " AdvHomeAgentFlag off;\n"
566 " AdvManagedFlag off;\n"
567 "%s%s%s"
568 " prefix %s/64 \n"
569 " {\n"
570 " AdvOnLink on;\n"
571 " AdvAutonomous on;\n"
572 "%s"
573 "%s%s%s"
574 " };\n",
575 nvram_safe_get("lan_ifname"),
576 mtu ? " AdvLinkMTU " : "", mtu ? : "", mtu ? ";\n" : "",
577 prefix,
578 do_6to4 ? " AdvValidLifetime 300;\n AdvPreferredLifetime 120;\n" : "",
579 do_6to4 ? " Base6to4Interface " : "",
580 do_6to4 ? get_wanface() : "",
581 do_6to4 ? ";\n" : "");
583 if (do_dns) {
584 fprintf(f, " RDNSS %s {};\n", ip);
586 else {
587 cnt = write_ipv6_dns_servers(f, " RDNSS ", nvram_safe_get("ipv6_dns"), " ", 1);
588 if (cnt == 0 || nvram_get_int("dns_addget"))
589 cnt += write_ipv6_dns_servers(f, (cnt) ? "" : " RDNSS ", nvram_safe_get("ipv6_get_dns"), " ", 1);
590 if (cnt) fprintf(f, "{};\n");
593 fprintf(f,
594 "};\n"); // close "interface" section
595 fclose(f);
597 // Start radvd
598 argc = 1;
599 if (nvram_get_int("debug_ipv6")) {
600 argv[argc++] = "-d";
601 argv[argc++] = "10";
603 argv[argc] = NULL;
604 _eval(argv, NULL, 0, &pid);
606 if (!nvram_contains_word("debug_norestart", "radvd")) {
607 pid_radvd = -2;
612 void stop_radvd(void)
614 if (getpid() != 1) {
615 stop_service("radvd");
616 return;
619 pid_radvd = -1;
620 killall_tk("radvd");
623 void start_ipv6(void)
625 int service;
627 service = get_ipv6_service();
628 enable_ip_forward();
630 // Check if turned on
631 switch (service) {
632 case IPV6_NATIVE:
633 case IPV6_6IN4:
634 case IPV6_MANUAL:
635 add_ip6_lanaddr();
636 break;
637 case IPV6_NATIVE_DHCP:
638 case IPV6_ANYCAST_6TO4:
639 nvram_set("ipv6_rtr_addr", "");
640 nvram_set("ipv6_prefix", "");
641 break;
644 if (service != IPV6_DISABLED) {
645 if ((nvram_get_int("ipv6_accept_ra") & 2) != 0 && !nvram_get_int("ipv6_radvd"))
646 accept_ra(nvram_safe_get("lan_ifname"));
650 void stop_ipv6(void)
652 stop_ipv6_tunnel();
653 stop_dhcp6c();
654 eval("ip", "-6", "addr", "flush", "scope", "global");
657 #endif
659 // -----------------------------------------------------------------------------
661 void start_upnp(void)
663 if (getpid() != 1) {
664 start_service("upnp");
665 return;
668 if (get_wan_proto() == WP_DISABLED) return;
670 int enable;
671 FILE *f;
672 int upnp_port;
674 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
675 mkdir("/etc/upnp", 0777);
676 if (f_exists("/etc/upnp/config.alt")) {
677 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
679 else {
680 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
681 upnp_port = nvram_get_int("upnp_port");
682 if ((upnp_port < 0) || (upnp_port >= 0xFFFF)) upnp_port = 0;
684 char *lanip = nvram_safe_get("lan_ipaddr");
685 char *lanmask = nvram_safe_get("lan_netmask");
687 fprintf(f,
688 "ext_ifname=%s\n"
689 "listening_ip=%s/%s\n"
690 "port=%d\n"
691 "enable_upnp=%s\n"
692 "enable_natpmp=%s\n"
693 "secure_mode=%s\n"
694 "upnp_forward_chain=upnp\n"
695 "upnp_nat_chain=upnp\n"
696 "notify_interval=%d\n"
697 "system_uptime=yes\n"
698 "\n"
700 get_wanface(),
701 lanip, lanmask,
702 upnp_port,
703 (enable & 1) ? "yes" : "no", // upnp enable
704 (enable & 2) ? "yes" : "no", // natpmp enable
705 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
706 nvram_get_int("upnp_ssdp_interval")
709 if (nvram_get_int("upnp_clean")) {
710 int interval = nvram_get_int("upnp_clean_interval");
711 if (interval < 60) interval = 60;
712 fprintf(f,
713 "clean_ruleset_interval=%d\n"
714 "clean_ruleset_threshold=%d\n",
715 interval,
716 nvram_get_int("upnp_clean_threshold")
719 else
720 fprintf(f,"clean_ruleset_interval=0\n");
722 if (nvram_match("upnp_mnp", "1")) {
723 int https = nvram_get_int("https_enable");
724 fprintf(f, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
725 https ? "s" : "", lanip,
726 nvram_safe_get(https ? "https_lanport" : "http_lanport"));
728 else {
729 // Empty parameters are not included into XML service description
730 fprintf(f, "presentation_url=\n");
733 char uuid[45];
734 f_read_string("/proc/sys/kernel/random/uuid", uuid, sizeof(uuid));
735 fprintf(f, "uuid=%s\n", uuid);
737 int ports[4];
738 if ((ports[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
739 (ports[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
740 (ports[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
741 (ports[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
742 fprintf(f,
743 "allow %d-%d %s/%s %d-%d\n",
744 ports[0], ports[1],
745 lanip, lanmask,
746 ports[2], ports[3]
749 else {
750 // by default allow only redirection of ports above 1024
751 fprintf(f, "allow 1024-65535 %s/%s 1024-65535\n", lanip, lanmask);
754 fappend(f, "/etc/upnp/config.custom");
755 fprintf(f, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
756 fclose(f);
758 xstart("miniupnpd", "-f", "/etc/upnp/config");
764 void stop_upnp(void)
766 if (getpid() != 1) {
767 stop_service("upnp");
768 return;
771 killall_tk("miniupnpd");
774 // -----------------------------------------------------------------------------
776 static pid_t pid_crond = -1;
778 void start_cron(void)
780 stop_cron();
782 eval("crond", nvram_contains_word("log_events", "crond") ? NULL : "-l", "9");
783 if (!nvram_contains_word("debug_norestart", "crond")) {
784 pid_crond = -2;
788 void stop_cron(void)
790 pid_crond = -1;
791 killall_tk("crond");
794 // -----------------------------------------------------------------------------
795 #ifdef LINUX26
797 static pid_t pid_hotplug2 = -1;
799 void start_hotplug2()
801 stop_hotplug2();
803 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE, 0);
804 xstart("hotplug2", "--persistent", "--no-coldplug");
805 // FIXME: Don't remember exactly why I put "sleep" here -
806 // but it was not for a race with check_services()... - TB
807 sleep(1);
809 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
810 pid_hotplug2 = -2;
814 void stop_hotplug2(void)
816 pid_hotplug2 = -1;
817 killall_tk("hotplug2");
820 #endif /* LINUX26 */
821 // -----------------------------------------------------------------------------
823 // Written by Sparq in 2002/07/16
824 void start_zebra(void)
826 #ifdef TCONFIG_ZEBRA
827 if (getpid() != 1) {
828 start_service("zebra");
829 return;
832 FILE *fp;
834 char *lan_tx = nvram_safe_get("dr_lan_tx");
835 char *lan_rx = nvram_safe_get("dr_lan_rx");
836 char *wan_tx = nvram_safe_get("dr_wan_tx");
837 char *wan_rx = nvram_safe_get("dr_wan_rx");
839 if ((*lan_tx == '0') && (*lan_rx == '0') && (*wan_tx == '0') && (*wan_rx == '0')) {
840 return;
843 // empty
844 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
845 fclose(fp);
849 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
850 char *lan_ifname = nvram_safe_get("lan_ifname");
851 char *wan_ifname = nvram_safe_get("wan_ifname");
853 fprintf(fp, "router rip\n");
854 fprintf(fp, "network %s\n", lan_ifname);
855 fprintf(fp, "network %s\n", wan_ifname);
856 fprintf(fp, "redistribute connected\n");
857 //fprintf(fp, "redistribute static\n");
859 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
860 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
862 fprintf(fp, "interface %s\n", lan_ifname);
863 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
864 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
866 fprintf(fp, "interface %s\n", wan_ifname);
867 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
868 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
870 fprintf(fp, "router rip\n");
871 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
872 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
873 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
874 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
875 fprintf(fp, "access-list private deny any\n");
877 //fprintf(fp, "debug rip events\n");
878 //fprintf(fp, "log file /etc/ripd.log\n");
879 fclose(fp);
882 xstart("zebra", "-d");
883 xstart("ripd", "-d");
884 #endif
887 void stop_zebra(void)
889 #ifdef TCONFIG_ZEBRA
890 if (getpid() != 1) {
891 stop_service("zebra");
892 return;
895 killall("zebra", SIGTERM);
896 killall("ripd", SIGTERM);
898 unlink("/etc/zebra.conf");
899 unlink("/etc/ripd.conf");
900 #endif
903 // -----------------------------------------------------------------------------
905 void start_syslog(void)
907 char *argv[16];
908 int argc;
909 char *nv;
910 char *b_opt = "";
911 char rem[256];
912 int n;
913 char s[64];
914 char cfg[256];
915 char *rot_siz = "50";
916 char *log_file_path;
918 argv[0] = "syslogd";
919 argc = 1;
921 if (nvram_match("log_remote", "1")) {
922 nv = nvram_safe_get("log_remoteip");
923 if (*nv) {
924 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
925 argv[argc++] = "-R";
926 argv[argc++] = rem;
930 if (nvram_match("log_file", "1")) {
931 argv[argc++] = "-L";
933 // log to custom path - shibby
934 if (nvram_match("log_file_custom", "1")) {
935 log_file_path = nvram_safe_get("log_file_path");
936 argv[argc++] = "-s";
937 argv[argc++] = "5000";
938 argv[argc++] = "-b";
939 argv[argc++] = "5";
940 argv[argc++] = "-O";
941 argv[argc++] = log_file_path;
942 remove("/var/log/messages");
943 symlink(log_file_path, "/var/log/messages");
945 else
947 /* Read options: rotate_size(kb) num_backups logfilename.
948 * Ignore these settings and use defaults if the logfile cannot be written to.
950 if (f_read_string("/etc/syslogd.cfg", cfg, sizeof(cfg)) > 0) {
951 if ((nv = strchr(cfg, '\n')))
952 *nv = 0;
954 if ((nv = strtok(cfg, " \t"))) {
955 if (isdigit(*nv))
956 rot_siz = nv;
959 if ((nv = strtok(NULL, " \t")))
960 b_opt = nv;
962 if ((nv = strtok(NULL, " \t")) && *nv == '/') {
963 if (f_write(nv, cfg, 0, FW_APPEND, 0) >= 0) {
964 argv[argc++] = "-O";
965 argv[argc++] = nv;
967 else {
968 rot_siz = "50";
969 b_opt = "";
974 if (nvram_match("log_file_custom", "0")) {
975 argv[argc++] = "-s";
976 argv[argc++] = rot_siz;
977 remove("/var/log/messages");
980 if (isdigit(*b_opt)) {
981 argv[argc++] = "-b";
982 argv[argc++] = b_opt;
986 if (argc > 1) {
987 argv[argc] = NULL;
988 _eval(argv, NULL, 0, NULL);
990 argv[0] = "klogd";
991 argv[1] = NULL;
992 _eval(argv, NULL, 0, NULL);
994 // used to be available in syslogd -m
995 n = nvram_get_int("log_mark");
996 if (n > 0) {
997 // n is in minutes
998 if (n < 60)
999 sprintf(rem, "*/%d * * * *", n);
1000 else if (n < 60 * 24)
1001 sprintf(rem, "0 */%d * * *", n / 60);
1002 else
1003 sprintf(rem, "0 0 */%d * *", n / (60 * 24));
1004 sprintf(s, "%s logger -p syslog.info -- -- MARK --", rem);
1005 eval("cru", "a", "syslogdmark", s);
1007 else {
1008 eval("cru", "d", "syslogdmark");
1013 void stop_syslog(void)
1015 killall("klogd", SIGTERM);
1016 killall("syslogd", SIGTERM);
1019 // -----------------------------------------------------------------------------
1021 static pid_t pid_igmp = -1;
1023 void start_igmp_proxy(void)
1025 FILE *fp;
1027 pid_igmp = -1;
1028 if (nvram_match("multicast_pass", "1")) {
1029 if (get_wan_proto() == WP_DISABLED)
1030 return;
1032 if (f_exists("/etc/igmp.alt")) {
1033 eval("igmpproxy", "/etc/igmp.alt");
1035 else if ((fp = fopen("/etc/igmp.conf", "w")) != NULL) {
1036 fprintf(fp,
1037 "quickleave\n"
1038 "phyint %s upstream\n"
1039 "\taltnet %s\n"
1040 "phyint %s downstream ratelimit 0\n",
1041 nvram_safe_get("wan_ifname"),
1042 nvram_get("multicast_altnet") ? : "0.0.0.0/0",
1043 nvram_safe_get("lan_ifname"));
1044 fclose(fp);
1045 eval("igmpproxy", "/etc/igmp.conf");
1047 else {
1048 return;
1050 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1051 pid_igmp = -2;
1056 void stop_igmp_proxy(void)
1058 pid_igmp = -1;
1059 killall_tk("igmpproxy");
1062 #ifdef TCONFIG_NOCAT
1064 static pid_t pid_splashd = -1;
1065 void start_splashd(void)
1067 pid_splashd = -1;
1068 start_nocat();
1069 if (!nvram_contains_word("debug_norestart", "splashd")) {
1070 pid_splashd = -2;
1074 void stop_splashd(void)
1076 pid_splashd = -1;
1077 stop_nocat();
1078 start_wan(BOOT);
1080 #endif
1082 // -----------------------------------------------------------------------------
1084 void set_tz(void)
1086 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
1089 void start_ntpc(void)
1091 set_tz();
1093 stop_ntpc();
1095 if (nvram_get_int("ntp_updates") >= 0) {
1096 xstart("ntpsync", "--init");
1100 void stop_ntpc(void)
1102 killall("ntpsync", SIGTERM);
1105 // -----------------------------------------------------------------------------
1107 static void stop_rstats(void)
1109 int n;
1110 int pid;
1112 n = 60;
1113 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
1114 if (kill(pid, SIGTERM) != 0) break;
1115 sleep(1);
1119 static void start_rstats(int new)
1121 if (nvram_match("rstats_enable", "1")) {
1122 stop_rstats();
1123 if (new) xstart("rstats", "--new");
1124 else xstart("rstats");
1128 // -----------------------------------------------------------------------------
1130 // !!TB - FTP Server
1132 #ifdef TCONFIG_FTP
1133 static char *get_full_storage_path(char *val)
1135 static char buf[128];
1136 int len;
1138 if (val[0] == '/')
1139 len = sprintf(buf, "%s", val);
1140 else
1141 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
1143 if (len > 1 && buf[len - 1] == '/')
1144 buf[len - 1] = 0;
1146 return buf;
1149 static char *nvram_storage_path(char *var)
1151 char *val = nvram_safe_get(var);
1152 return get_full_storage_path(val);
1155 char vsftpd_conf[] = "/etc/vsftpd.conf";
1156 char vsftpd_users[] = "/etc/vsftpd.users";
1157 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
1159 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1161 static void start_ftpd(void)
1163 char tmp[256];
1164 FILE *fp, *f;
1165 char *buf;
1166 char *p, *q;
1167 char *user, *pass, *rights;
1169 if (getpid() != 1) {
1170 start_service("ftpd");
1171 return;
1174 if (!nvram_get_int("ftp_enable")) return;
1176 mkdir_if_none(vsftpd_users);
1177 mkdir_if_none("/var/run/vsftpd");
1179 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
1180 return;
1182 if (nvram_get_int("ftp_super"))
1184 /* rights */
1185 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
1186 if ((f = fopen(tmp, "w")))
1188 fprintf(f,
1189 "dirlist_enable=yes\n"
1190 "write_enable=yes\n"
1191 "download_enable=yes\n");
1192 fclose(f);
1196 #ifdef TCONFIG_SAMBASRV
1197 if (nvram_match("smbd_cset", "utf8"))
1198 fprintf(fp, "utf8=yes\n");
1199 #endif
1201 if (nvram_invmatch("ftp_anonymous", "0"))
1203 fprintf(fp,
1204 "anon_allow_writable_root=yes\n"
1205 "anon_world_readable_only=no\n"
1206 "anon_umask=022\n");
1208 /* rights */
1209 sprintf(tmp, "%s/ftp", vsftpd_users);
1210 if ((f = fopen(tmp, "w")))
1212 if (nvram_match("ftp_dirlist", "0"))
1213 fprintf(f, "dirlist_enable=yes\n");
1214 if (nvram_match("ftp_anonymous", "1") ||
1215 nvram_match("ftp_anonymous", "3"))
1216 fprintf(f, "write_enable=yes\n");
1217 if (nvram_match("ftp_anonymous", "1") ||
1218 nvram_match("ftp_anonymous", "2"))
1219 fprintf(f, "download_enable=yes\n");
1220 fclose(f);
1222 if (nvram_match("ftp_anonymous", "1") ||
1223 nvram_match("ftp_anonymous", "3"))
1224 fprintf(fp,
1225 "anon_upload_enable=yes\n"
1226 "anon_mkdir_write_enable=yes\n"
1227 "anon_other_write_enable=yes\n");
1228 } else {
1229 fprintf(fp, "anonymous_enable=no\n");
1232 fprintf(fp,
1233 "dirmessage_enable=yes\n"
1234 "download_enable=no\n"
1235 "dirlist_enable=no\n"
1236 "hide_ids=yes\n"
1237 "syslog_enable=yes\n"
1238 "local_enable=yes\n"
1239 "local_umask=022\n"
1240 "chmod_enable=no\n"
1241 "chroot_local_user=yes\n"
1242 "check_shell=no\n"
1243 "log_ftp_protocol=%s\n"
1244 "user_config_dir=%s\n"
1245 "passwd_file=%s\n"
1246 "listen%s=yes\n"
1247 "listen_port=%s\n"
1248 "background=yes\n"
1249 "isolate=no\n"
1250 "max_clients=%d\n"
1251 "max_per_ip=%d\n"
1252 "max_login_fails=1\n"
1253 "idle_session_timeout=%s\n"
1254 "use_sendfile=no\n"
1255 "anon_max_rate=%d\n"
1256 "local_max_rate=%d\n"
1257 "%s\n",
1258 nvram_get_int("log_ftp") ? "yes" : "no",
1259 vsftpd_users, vsftpd_passwd,
1260 #ifdef TCONFIG_IPV6
1261 ipv6_enabled() ? "_ipv6" : "",
1262 #else
1264 #endif
1265 nvram_get("ftp_port") ? : "21",
1266 nvram_get_int("ftp_max"),
1267 nvram_get_int("ftp_ipmax"),
1268 nvram_get("ftp_staytimeout") ? : "300",
1269 nvram_get_int("ftp_anonrate") * 1024,
1270 nvram_get_int("ftp_rate") * 1024,
1271 nvram_safe_get("ftp_custom"));
1273 fclose(fp);
1275 /* prepare passwd file and default users */
1276 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
1277 return;
1279 if (((user = nvram_get("http_username")) == NULL) || (*user == 0)) user = "admin";
1280 if (((pass = nvram_get("http_passwd")) == NULL) || (*pass == 0)) pass = "admin";
1282 fprintf(fp, /* anonymous, admin, nobody */
1283 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1284 "%s:%s:0:0:root:/:/sbin/nologin\n"
1285 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1286 nvram_storage_path("ftp_anonroot"), user,
1287 nvram_get_int("ftp_super") ? crypt(pass, "$1$") : "x",
1288 MOUNT_ROOT);
1290 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
1293 username<password<rights
1294 rights:
1295 Read/Write
1296 Read Only
1297 View Only
1298 Private
1300 p = buf;
1301 while ((q = strsep(&p, ">")) != NULL) {
1302 if (vstrsep(q, "<", &user, &pass, &rights) != 3) continue;
1303 if (!user || !pass) continue;
1305 /* directory */
1306 if (strncmp(rights, "Private", 7) == 0)
1308 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
1309 mkdir_if_none(tmp);
1311 else
1312 sprintf(tmp, "%s", nvram_storage_path("ftp_pubroot"));
1314 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1315 user, crypt(pass, "$1$"), user, tmp);
1317 /* rights */
1318 sprintf(tmp, "%s/%s", vsftpd_users, user);
1319 if ((f = fopen(tmp, "w")))
1321 tmp[0] = 0;
1322 if (nvram_invmatch("ftp_dirlist", "1"))
1323 strcat(tmp, "dirlist_enable=yes\n");
1324 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
1325 strcat(tmp, "download_enable=yes\n");
1326 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
1327 strcat(tmp, "write_enable=yes\n");
1329 fputs(tmp, f);
1330 fclose(f);
1333 free(buf);
1336 fclose(fp);
1337 killall("vsftpd", SIGHUP);
1339 /* start vsftpd if it's not already running */
1340 if (pidof("vsftpd") <= 0)
1341 xstart("vsftpd");
1344 static void stop_ftpd(void)
1346 if (getpid() != 1) {
1347 stop_service("ftpd");
1348 return;
1351 killall_tk("vsftpd");
1352 unlink(vsftpd_passwd);
1353 unlink(vsftpd_conf);
1354 eval("rm", "-rf", vsftpd_users);
1356 #endif // TCONFIG_FTP
1358 // -----------------------------------------------------------------------------
1360 // !!TB - Samba
1362 #ifdef TCONFIG_SAMBASRV
1363 static void kill_samba(int sig)
1365 if (sig == SIGTERM) {
1366 killall_tk("smbd");
1367 killall_tk("nmbd");
1369 else {
1370 killall("smbd", sig);
1371 killall("nmbd", sig);
1375 static void start_samba(void)
1377 FILE *fp;
1378 DIR *dir = NULL;
1379 struct dirent *dp;
1380 char nlsmod[15];
1381 int mode;
1382 char *nv;
1384 if (getpid() != 1) {
1385 start_service("smbd");
1386 return;
1389 mode = nvram_get_int("smbd_enable");
1390 if (!mode || !nvram_invmatch("lan_hostname", ""))
1391 return;
1393 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
1394 return;
1396 fprintf(fp, "[global]\n"
1397 " interfaces = %s\n"
1398 " bind interfaces only = yes\n"
1399 " workgroup = %s\n"
1400 " netbios name = %s\n"
1401 " server string = %s\n"
1402 " guest account = nobody\n"
1403 " security = user\n"
1404 " %s\n"
1405 " guest ok = %s\n"
1406 " guest only = no\n"
1407 " browseable = yes\n"
1408 " syslog only = yes\n"
1409 " timestamp logs = no\n"
1410 " syslog = 1\n"
1411 " encrypt passwords = yes\n"
1412 " preserve case = yes\n"
1413 " short preserve case = yes\n",
1414 nvram_safe_get("lan_ifname"),
1415 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1416 nvram_safe_get("lan_hostname"),
1417 nvram_get("router_name") ? : "Tomato",
1418 mode == 2 ? "" : "map to guest = Bad User",
1419 mode == 2 ? "no" : "yes" // guest ok
1422 if (nvram_get_int("smbd_wins")) {
1423 nv = nvram_safe_get("wan_wins");
1424 if ((*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
1425 fprintf(fp, " wins support = yes\n");
1429 if (nvram_get_int("smbd_master")) {
1430 fprintf(fp,
1431 " domain master = yes\n"
1432 " local master = yes\n"
1433 " preferred master = yes\n"
1434 " os level = 65\n");
1437 nv = nvram_safe_get("smbd_cpage");
1438 if (*nv) {
1439 #ifndef TCONFIG_SAMBA3
1440 fprintf(fp, " client code page = %s\n", nv);
1441 #endif
1442 sprintf(nlsmod, "nls_cp%s", nv);
1444 nv = nvram_safe_get("smbd_nlsmod");
1445 if ((*nv) && (strcmp(nv, nlsmod) != 0))
1446 modprobe_r(nv);
1448 modprobe(nlsmod);
1449 nvram_set("smbd_nlsmod", nlsmod);
1452 #ifndef TCONFIG_SAMBA3
1453 if (nvram_match("smbd_cset", "utf8"))
1454 fprintf(fp, " coding system = utf8\n");
1455 else if (nvram_invmatch("smbd_cset", ""))
1456 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1457 #endif
1459 nv = nvram_safe_get("smbd_custom");
1460 /* add socket options unless overriden by the user */
1461 if (strstr(nv, "socket options") == NULL) {
1462 fprintf(fp, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1464 fprintf(fp, "%s\n\n", nv);
1466 /* configure shares */
1468 char *buf;
1469 char *p, *q;
1470 char *name, *path, *comment, *writeable, *hidden;
1471 int cnt = 0;
1473 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1475 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1477 p = buf;
1478 while ((q = strsep(&p, ">")) != NULL) {
1479 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1480 if (!path || !name) continue;
1482 /* share name */
1483 fprintf(fp, "\n[%s]\n", name);
1485 /* path */
1486 fprintf(fp, " path = %s\n", path);
1488 /* access level */
1489 if (!strcmp(writeable, "1"))
1490 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1491 if (!strcmp(hidden, "1"))
1492 fprintf(fp, " browseable = no\n");
1494 /* comment */
1495 if (comment)
1496 fprintf(fp, " comment = %s\n", comment);
1498 cnt++;
1500 free(buf);
1503 /* Share every mountpoint below MOUNT_ROOT */
1504 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1505 while ((dp = readdir(dir))) {
1506 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1508 /* Only if is a directory and is mounted */
1509 if (!dir_is_mountpoint(MOUNT_ROOT, dp->d_name))
1510 continue;
1512 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1513 fprintf(fp, "\n[%s]\n path = %s/%s\n comment = %s\n",
1514 dp->d_name, MOUNT_ROOT, dp->d_name, dp->d_name);
1515 if (nvram_match("smbd_autoshare", "3")) // Hidden
1516 fprintf(fp, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1517 dp->d_name, MOUNT_ROOT, dp->d_name);
1518 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1519 fprintf(fp, " writable = yes\n delete readonly = yes\n force user = root\n");
1521 cnt++;
1525 if (dir) closedir(dir);
1527 if (cnt == 0) {
1528 /* by default share MOUNT_ROOT as read-only */
1529 fprintf(fp, "\n[share]\n"
1530 " path = %s\n"
1531 " writable = no\n",
1532 MOUNT_ROOT);
1535 fclose(fp);
1537 mkdir_if_none("/var/run/samba");
1538 mkdir_if_none("/etc/samba");
1540 /* write smbpasswd */
1541 #ifdef TCONFIG_SAMBA3
1542 eval("smbpasswd", "nobody", "\"\"");
1543 #else
1544 eval("smbpasswd", "-a", "nobody", "\"\"");
1545 #endif
1546 if (mode == 2) {
1547 char *smbd_user;
1548 if (((smbd_user = nvram_get("smbd_user")) == NULL) || (*smbd_user == 0) || !strcmp(smbd_user, "root"))
1549 smbd_user = "nas";
1550 #ifdef TCONFIG_SAMBA3
1551 eval("smbpasswd", smbd_user, nvram_safe_get("smbd_passwd"));
1552 #else
1553 eval("smbpasswd", "-a", smbd_user, nvram_safe_get("smbd_passwd"));
1554 #endif
1557 kill_samba(SIGHUP);
1558 int ret1 = 0, ret2 = 0;
1559 /* start samba if it's not already running */
1560 if (pidof("nmbd") <= 0)
1561 ret1 = xstart("nmbd", "-D");
1562 if (pidof("smbd") <= 0)
1563 ret2 = xstart("smbd", "-D");
1565 if (ret1 || ret2) kill_samba(SIGTERM);
1568 static void stop_samba(void)
1570 if (getpid() != 1) {
1571 stop_service("smbd");
1572 return;
1575 kill_samba(SIGTERM);
1576 /* clean up */
1577 unlink("/var/log/smb");
1578 unlink("/var/log/nmb");
1579 eval("rm", "-rf", "/var/run/samba");
1581 #endif // TCONFIG_SAMBASRV
1583 #ifdef TCONFIG_MEDIA_SERVER
1584 #define MEDIA_SERVER_APP "minidlna"
1586 static void start_media_server(void)
1588 FILE *f;
1589 int port, pid, https;
1590 char *dbdir;
1591 char *argv[] = { MEDIA_SERVER_APP, "-f", "/etc/"MEDIA_SERVER_APP".conf", "-R", NULL };
1592 static int once = 1;
1594 if (getpid() != 1) {
1595 start_service("media");
1596 return;
1599 if (nvram_get_int("ms_sas") == 0)
1600 once = 0;
1602 if (nvram_get_int("ms_enable") != 0) {
1603 if ((!once) && (nvram_get_int("ms_rescan") == 0)) {
1604 // no forced rescan
1605 argv[3] = NULL;
1607 nvram_unset("ms_rescan");
1609 if (f_exists("/etc/"MEDIA_SERVER_APP".alt")) {
1610 argv[2] = "/etc/"MEDIA_SERVER_APP".alt";
1612 else {
1613 if ((f = fopen(argv[2], "w")) != NULL) {
1614 port = nvram_get_int("ms_port");
1615 https = nvram_get_int("https_enable");
1616 dbdir = nvram_safe_get("ms_dbdir");
1617 if (!(*dbdir)) dbdir = NULL;
1618 mkdir_if_none(dbdir ? : "/var/run/"MEDIA_SERVER_APP);
1620 fprintf(f,
1621 "network_interface=%s\n"
1622 "port=%d\n"
1623 "friendly_name=%s\n"
1624 "db_dir=%s/.db\n"
1625 "enable_tivo=%s\n"
1626 "strict_dlna=%s\n"
1627 "presentation_url=http%s://%s:%s/nas-media.asp\n"
1628 "inotify=yes\n"
1629 "notify_interval=600\n"
1630 "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"
1631 "\n",
1632 nvram_safe_get("lan_ifname"),
1633 (port < 0) || (port >= 0xffff) ? 0 : port,
1634 nvram_get("router_name") ? : "Tomato",
1635 dbdir ? : "/var/run/"MEDIA_SERVER_APP,
1636 nvram_get_int("ms_tivo") ? "yes" : "no",
1637 nvram_get_int("ms_stdlna") ? "yes" : "no",
1638 https ? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https ? "https_lanport" : "http_lanport")
1641 // media directories
1642 char *buf, *p, *q;
1643 char *path, *restrict;
1645 if ((buf = strdup(nvram_safe_get("ms_dirs"))) != NULL) {
1646 /* path<restrict[A|V|P|] */
1648 p = buf;
1649 while ((q = strsep(&p, ">")) != NULL) {
1650 if (vstrsep(q, "<", &path, &restrict) < 1 || !path || !(*path))
1651 continue;
1652 fprintf(f, "media_dir=%s%s%s\n",
1653 restrict ? : "", (restrict && *restrict) ? "," : "", path);
1655 free(buf);
1658 fclose(f);
1662 /* start media server if it's not already running */
1663 if (pidof(MEDIA_SERVER_APP) <= 0) {
1664 if ((_eval(argv, NULL, 0, &pid) == 0) && (once)) {
1665 /* If we started the media server successfully, wait 1 sec
1666 * to let it die if it can't open the database file.
1667 * If it's still alive after that, assume it's running and
1668 * disable forced once-after-reboot rescan.
1670 sleep(1);
1671 if (pidof(MEDIA_SERVER_APP) > 0)
1672 once = 0;
1678 static void stop_media_server(void)
1680 if (getpid() != 1) {
1681 stop_service("media");
1682 return;
1685 killall_tk(MEDIA_SERVER_APP);
1687 #endif // TCONFIG_MEDIA_SERVER
1689 #ifdef TCONFIG_USB
1690 static void start_nas_services(void)
1692 if (getpid() != 1) {
1693 start_service("usbapps");
1694 return;
1697 #ifdef TCONFIG_SAMBASRV
1698 start_samba();
1699 #endif
1700 #ifdef TCONFIG_FTP
1701 start_ftpd();
1702 #endif
1703 #ifdef TCONFIG_MEDIA_SERVER
1704 start_media_server();
1705 #endif
1708 static void stop_nas_services(void)
1710 if (getpid() != 1) {
1711 stop_service("usbapps");
1712 return;
1715 #ifdef TCONFIG_MEDIA_SERVER
1716 stop_media_server();
1717 #endif
1718 #ifdef TCONFIG_FTP
1719 stop_ftpd();
1720 #endif
1721 #ifdef TCONFIG_SAMBASRV
1722 stop_samba();
1723 #endif
1726 void restart_nas_services(int stop, int start)
1728 int fd = file_lock("usb");
1729 /* restart all NAS applications */
1730 if (stop)
1731 stop_nas_services();
1732 if (start)
1733 start_nas_services();
1734 file_unlock(fd);
1736 #endif // TCONFIG_USB
1738 // -----------------------------------------------------------------------------
1740 /* -1 = Don't check for this program, it is not expected to be running.
1741 * Other = This program has been started and should be kept running. If no
1742 * process with the name is running, call func to restart it.
1743 * Note: At startup, dnsmasq forks a short-lived child which forks a
1744 * long-lived (grand)child. The parents terminate.
1745 * Many daemons use this technique.
1747 static void _check(pid_t pid, const char *name, void (*func)(void))
1749 if (pid == -1) return;
1751 if (pidof(name) > 0) return;
1753 syslog(LOG_DEBUG, "%s terminated unexpectedly, restarting.\n", name);
1754 func();
1756 // Force recheck in 500 msec
1757 setitimer(ITIMER_REAL, &pop_tv, NULL);
1760 void check_services(void)
1762 TRACE_PT("keep alive\n");
1764 // Periodically reap any zombies
1765 setitimer(ITIMER_REAL, &zombie_tv, NULL);
1767 #ifdef LINUX26
1768 _check(pid_hotplug2, "hotplug2", start_hotplug2);
1769 #endif
1770 _check(pid_dnsmasq, "dnsmasq", start_dnsmasq);
1771 _check(pid_crond, "crond", start_cron);
1772 _check(pid_igmp, "igmpproxy", start_igmp_proxy);
1773 #ifdef TCONFIG_IPV6
1774 _check(pid_radvd, "radvd", start_radvd);
1775 #endif
1777 //#ifdef TCONFIG_NOCAT
1778 // if (nvram_get_int("NC_enable"))
1779 // _check(&pid_splashd, "splashd", start_splashd);
1780 //#endif
1784 // -----------------------------------------------------------------------------
1786 void start_services(void)
1788 static int once = 1;
1790 if (once) {
1791 once = 0;
1793 if (nvram_get_int("telnetd_eas")) start_telnetd();
1794 if (nvram_get_int("sshd_eas")) start_sshd();
1797 // start_syslog();
1798 start_nas();
1799 start_zebra();
1800 start_dnsmasq();
1801 start_cifs();
1802 start_httpd();
1803 start_cron();
1804 // start_upnp();
1805 start_rstats(0);
1806 start_sched();
1807 #ifdef TCONFIG_IPV6
1808 /* note: starting radvd here might be too early in case of
1809 * DHCPv6 or 6to4 because we won't have received a prefix and
1810 * so it will disable advertisements. To restart them, we have
1811 * to send radvd a SIGHUP, or restart it.
1813 start_radvd();
1814 #endif
1815 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
1817 #ifdef TCONFIG_BT
1818 start_bittorrent();
1819 #endif
1821 #ifdef TCONFIG_NFS
1822 start_nfs();
1823 #endif
1826 void stop_services(void)
1828 clear_resolv();
1830 #ifdef TCONFIG_BT
1831 stop_bittorrent();
1832 #endif
1834 #ifdef TCONFIG_NFS
1835 stop_nfs();
1836 #endif
1837 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
1838 #ifdef TCONFIG_IPV6
1839 stop_radvd();
1840 #endif
1841 stop_sched();
1842 stop_rstats();
1843 // stop_upnp();
1844 stop_cron();
1845 stop_httpd();
1846 stop_cifs();
1847 stop_dnsmasq();
1848 stop_zebra();
1849 stop_nas();
1850 // stop_syslog();
1853 // -----------------------------------------------------------------------------
1855 /* nvram "action_service" is: "service-action[-modifier]"
1856 * action is something like "stop" or "start" or "restart"
1857 * optional modifier is "c" for the "service" command-line command
1859 void exec_service(void)
1861 const int A_START = 1;
1862 const int A_STOP = 2;
1863 const int A_RESTART = 1|2;
1864 char buffer[128];
1865 char *service;
1866 char *act;
1867 char *next;
1868 char *modifier;
1869 int action, user;
1870 int i;
1872 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
1873 next = buffer;
1875 TOP:
1876 act = strsep(&next, ",");
1877 service = strsep(&act, "-");
1878 if (act == NULL) {
1879 next = NULL;
1880 goto CLEAR;
1882 modifier = act;
1883 strsep(&modifier, "-");
1885 TRACE_PT("service=%s action=%s modifier=%s\n", service, act, modifier ? : "");
1887 if (strcmp(act, "start") == 0) action = A_START;
1888 else if (strcmp(act, "stop") == 0) action = A_STOP;
1889 else if (strcmp(act, "restart") == 0) action = A_RESTART;
1890 else action = 0;
1891 user = (modifier != NULL && *modifier == 'c');
1893 if (strcmp(service, "dhcpc") == 0) {
1894 if (action & A_STOP) stop_dhcpc();
1895 if (action & A_START) start_dhcpc();
1896 goto CLEAR;
1899 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
1900 if (action & A_STOP) stop_dnsmasq();
1901 if (action & A_START) {
1902 dns_to_resolv();
1903 start_dnsmasq();
1905 goto CLEAR;
1908 if (strcmp(service, "firewall") == 0) {
1909 if (action & A_STOP) {
1910 stop_firewall();
1911 stop_igmp_proxy();
1913 if (action & A_START) {
1914 start_firewall();
1915 start_igmp_proxy();
1917 goto CLEAR;
1920 if (strcmp(service, "restrict") == 0) {
1921 if (action & A_STOP) {
1922 stop_firewall();
1924 if (action & A_START) {
1925 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
1927 start_firewall();
1929 // if radio was disabled by access restriction, but no rule is handling it now, enable it
1930 if (i == 1) {
1931 if (nvram_get_int("rrules_radio") < 0) {
1932 eval("radio", "on");
1936 goto CLEAR;
1939 if (strcmp(service, "qos") == 0) {
1940 if (action & A_STOP) {
1941 stop_qos();
1943 stop_firewall(); start_firewall(); // always restarted
1944 if (action & A_START) {
1945 // start_qos();
1946 start_cmon(); // cmon start also qos
1947 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
1949 goto CLEAR;
1952 if (strcmp(service, "qoslimit") == 0) {
1953 if (action & A_STOP) {
1954 new_qoslimit_stop();
1956 stop_firewall(); start_firewall(); // always restarted
1957 if (action & A_START) {
1958 // new_qoslimit_start();
1959 start_cmon(); //cmon start also qoslimit
1961 goto CLEAR;
1964 if (strcmp(service, "arpbind") == 0) {
1965 if (action & A_STOP) new_arpbind_stop();
1966 if (action & A_START) new_arpbind_start();
1967 goto CLEAR;
1970 if (strcmp(service, "cmon") == 0) {
1971 if (action & A_STOP) { stop_cmon(); }
1973 start_qos(); new_qoslimit_start(); // start features after firewall restart
1975 if (action & A_START) { start_cmon(); }
1976 goto CLEAR;
1979 if (strcmp(service, "upnp") == 0) {
1980 if (action & A_STOP) {
1981 stop_upnp();
1983 stop_firewall(); start_firewall(); // always restarted
1984 if (action & A_START) {
1985 start_upnp();
1987 goto CLEAR;
1990 if (strcmp(service, "telnetd") == 0) {
1991 if (action & A_STOP) stop_telnetd();
1992 if (action & A_START) start_telnetd();
1993 goto CLEAR;
1996 if (strcmp(service, "sshd") == 0) {
1997 if (action & A_STOP) stop_sshd();
1998 if (action & A_START) start_sshd();
1999 goto CLEAR;
2002 if (strcmp(service, "httpd") == 0) {
2003 if (action & A_STOP) stop_httpd();
2004 if (action & A_START) start_httpd();
2005 goto CLEAR;
2008 #ifdef TCONFIG_IPV6
2009 if (strcmp(service, "ipv6") == 0) {
2010 if (action & A_STOP) {
2011 stop_radvd();
2012 stop_ipv6();
2014 if (action & A_START) {
2015 start_ipv6();
2016 start_radvd();
2018 goto CLEAR;
2021 if (strcmp(service, "radvd") == 0) {
2022 if (action & A_STOP) {
2023 stop_radvd();
2025 if (action & A_START) {
2026 start_radvd();
2028 goto CLEAR;
2031 if (strncmp(service, "dhcp6", 5) == 0) {
2032 if (action & A_STOP) {
2033 stop_dhcp6c();
2035 if (action & A_START) {
2036 start_dhcp6c();
2038 goto CLEAR;
2040 #endif
2042 if (strcmp(service, "admin") == 0) {
2043 if (action & A_STOP) {
2044 stop_sshd();
2045 stop_telnetd();
2046 stop_httpd();
2048 stop_firewall(); start_firewall(); // always restarted
2049 if (action & A_START) {
2050 start_httpd();
2051 create_passwd();
2052 if (nvram_match("telnetd_eas", "1")) start_telnetd();
2053 if (nvram_match("sshd_eas", "1")) start_sshd();
2055 goto CLEAR;
2058 if (strcmp(service, "ddns") == 0) {
2059 if (action & A_STOP) stop_ddns();
2060 if (action & A_START) start_ddns();
2061 goto CLEAR;
2064 if (strcmp(service, "ntpc") == 0) {
2065 if (action & A_STOP) stop_ntpc();
2066 if (action & A_START) start_ntpc();
2067 goto CLEAR;
2070 if (strcmp(service, "logging") == 0) {
2071 if (action & A_STOP) {
2072 stop_syslog();
2074 if (action & A_START) {
2075 start_syslog();
2077 if (!user) {
2078 // always restarted except from "service" command
2079 stop_cron(); start_cron();
2080 stop_firewall(); start_firewall();
2082 goto CLEAR;
2085 if (strcmp(service, "crond") == 0) {
2086 if (action & A_STOP) {
2087 stop_cron();
2089 if (action & A_START) {
2090 start_cron();
2092 goto CLEAR;
2095 #ifdef LINUX26
2096 if (strncmp(service, "hotplug", 7) == 0) {
2097 if (action & A_STOP) {
2098 stop_hotplug2();
2100 if (action & A_START) {
2101 start_hotplug2(1);
2103 goto CLEAR;
2105 #endif
2107 if (strcmp(service, "upgrade") == 0) {
2108 if (action & A_START) {
2109 #if TOMATO_SL
2110 stop_usbevent();
2111 stop_smbd();
2112 #endif
2113 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2114 stop_jffs2();
2115 // stop_cifs();
2116 stop_zebra();
2117 stop_cron();
2118 stop_ntpc();
2119 stop_upnp();
2120 // stop_dhcpc();
2121 killall("rstats", SIGTERM);
2122 killall("buttons", SIGTERM);
2123 stop_syslog();
2124 remove_storage_main(1); // !!TB - USB Support
2125 stop_usb(); // !!TB - USB Support
2127 goto CLEAR;
2130 #ifdef TCONFIG_CIFS
2131 if (strcmp(service, "cifs") == 0) {
2132 if (action & A_STOP) stop_cifs();
2133 if (action & A_START) start_cifs();
2134 goto CLEAR;
2136 #endif
2138 #ifdef TCONFIG_JFFS2
2139 if (strncmp(service, "jffs", 4) == 0) {
2140 if (action & A_STOP) stop_jffs2();
2141 if (action & A_START) start_jffs2();
2142 goto CLEAR;
2144 #endif
2146 if (strcmp(service, "zebra") == 0) {
2147 if (action & A_STOP) stop_zebra();
2148 if (action & A_START) start_zebra();
2149 goto CLEAR;
2152 if (strcmp(service, "routing") == 0) {
2153 if (action & A_STOP) {
2154 stop_zebra();
2155 do_static_routes(0); // remove old '_saved'
2156 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2158 stop_firewall();
2159 start_firewall();
2160 if (action & A_START) {
2161 do_static_routes(1); // add new
2162 start_zebra();
2163 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2165 goto CLEAR;
2168 if (strcmp(service, "ctnf") == 0) {
2169 if (action & A_START) {
2170 setup_conntrack();
2171 stop_firewall();
2172 start_firewall();
2174 goto CLEAR;
2177 if (strcmp(service, "wan") == 0) {
2178 if (action & A_STOP) {
2179 stop_wan();
2182 if (action & A_START) {
2183 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2184 start_wan(BOOT);
2185 sleep(2);
2186 force_to_dial();
2188 goto CLEAR;
2191 if (strcmp(service, "net") == 0) {
2192 if (action & A_STOP) {
2193 #ifdef TCONFIG_USB
2194 stop_nas_services();
2195 #endif
2196 #ifdef TCONFIG_IPV6
2197 stop_radvd();
2198 #endif
2199 stop_httpd();
2200 stop_dnsmasq();
2201 stop_nas();
2202 stop_wan();
2203 stop_lan();
2204 stop_vlan();
2206 if (action & A_START) {
2207 start_vlan();
2208 start_lan();
2209 start_wan(BOOT);
2210 start_nas();
2211 start_dnsmasq();
2212 start_httpd();
2213 #ifdef TCONFIG_IPV6
2214 start_radvd();
2215 #endif
2216 start_wl();
2217 #ifdef TCONFIG_USB
2218 start_nas_services();
2219 #endif
2221 goto CLEAR;
2224 if (strcmp(service, "nas") == 0) {
2225 if (action & A_STOP) {
2226 stop_nas();
2228 if (action & A_START) {
2229 start_nas();
2230 start_wl();
2232 goto CLEAR;
2235 if (strcmp(service, "rstats") == 0) {
2236 if (action & A_STOP) stop_rstats();
2237 if (action & A_START) start_rstats(0);
2238 goto CLEAR;
2241 if (strcmp(service, "rstatsnew") == 0) {
2242 if (action & A_STOP) stop_rstats();
2243 if (action & A_START) start_rstats(1);
2244 goto CLEAR;
2247 if (strcmp(service, "sched") == 0) {
2248 if (action & A_STOP) stop_sched();
2249 if (action & A_START) start_sched();
2250 goto CLEAR;
2253 #ifdef TCONFIG_BT
2254 if (strcmp(service, "bittorrent") == 0) {
2255 if (action & A_STOP) {
2256 stop_bittorrent();
2258 stop_firewall(); start_firewall(); // always restarted
2259 if (action & A_START) {
2260 start_bittorrent();
2262 goto CLEAR;
2264 #endif
2266 #ifdef TCONFIG_NFS
2267 if (strcmp(service, "nfs") == 0) {
2268 if (action & A_STOP) stop_nfs();
2269 if (action & A_START) start_nfs();
2270 goto CLEAR;
2272 #endif
2274 #ifdef TCONFIG_USB
2275 // !!TB - USB Support
2276 if (strcmp(service, "usb") == 0) {
2277 if (action & A_STOP) stop_usb();
2278 if (action & A_START) {
2279 start_usb();
2280 // restart Samba and ftp since they may be killed by stop_usb()
2281 restart_nas_services(0, 1);
2282 // remount all partitions by simulating hotplug event
2283 add_remove_usbhost("-1", 1);
2285 goto CLEAR;
2288 if (strcmp(service, "usbapps") == 0) {
2289 if (action & A_STOP) stop_nas_services();
2290 if (action & A_START) start_nas_services();
2291 goto CLEAR;
2293 #endif
2295 #ifdef TCONFIG_FTP
2296 // !!TB - FTP Server
2297 if (strcmp(service, "ftpd") == 0) {
2298 if (action & A_STOP) stop_ftpd();
2299 setup_conntrack();
2300 stop_firewall();
2301 start_firewall();
2302 if (action & A_START) start_ftpd();
2303 goto CLEAR;
2305 #endif
2307 #ifdef TCONFIG_MEDIA_SERVER
2308 if (strcmp(service, "media") == 0 || strcmp(service, "dlna") == 0) {
2309 if (action & A_STOP) stop_media_server();
2310 if (action & A_START) start_media_server();
2311 goto CLEAR;
2313 #endif
2315 #ifdef TCONFIG_SAMBASRV
2316 // !!TB - Samba
2317 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
2318 if (action & A_STOP) stop_samba();
2319 if (action & A_START) {
2320 create_passwd();
2321 stop_dnsmasq();
2322 start_dnsmasq();
2323 start_samba();
2325 goto CLEAR;
2327 #endif
2329 #ifdef TCONFIG_OPENVPN
2330 if (strncmp(service, "vpnclient", 9) == 0) {
2331 if (action & A_STOP) stop_vpnclient(atoi(&service[9]));
2332 if (action & A_START) start_vpnclient(atoi(&service[9]));
2333 goto CLEAR;
2336 if (strncmp(service, "vpnserver", 9) == 0) {
2337 if (action & A_STOP) stop_vpnserver(atoi(&service[9]));
2338 if (action & A_START) start_vpnserver(atoi(&service[9]));
2339 goto CLEAR;
2341 #endif
2343 #ifdef TCONFIG_NOCAT
2344 if (strcmp(service, "splashd") == 0) {
2345 if (action & A_STOP) stop_splashd();
2346 if (action & A_START) start_splashd();
2347 goto CLEAR;
2349 #endif
2351 CLEAR:
2352 if (next) goto TOP;
2354 // some functions check action_service and must be cleared at end -- zzz
2355 nvram_set("action_service", "");
2357 // Force recheck in 500 msec
2358 setitimer(ITIMER_REAL, &pop_tv, NULL);
2361 static void do_service(const char *name, const char *action, int user)
2363 int n;
2364 char s[64];
2366 n = 150;
2367 while (!nvram_match("action_service", "")) {
2368 if (user) {
2369 putchar('*');
2370 fflush(stdout);
2372 else if (--n < 0) break;
2373 usleep(100 * 1000);
2376 snprintf(s, sizeof(s), "%s-%s%s", name, action, (user ? "-c" : ""));
2377 nvram_set("action_service", s);
2378 kill(1, SIGUSR1);
2380 n = 150;
2381 while (nvram_match("action_service", s)) {
2382 if (user) {
2383 putchar('.');
2384 fflush(stdout);
2386 else if (--n < 0) {
2387 break;
2389 usleep(100 * 1000);
2393 int service_main(int argc, char *argv[])
2395 if (argc != 3) usage_exit(argv[0], "<service> <action>");
2396 do_service(argv[1], argv[2], 1);
2397 printf("\nDone.\n");
2398 return 0;
2401 void start_service(const char *name)
2403 do_service(name, "start", 0);
2406 void stop_service(const char *name)
2408 do_service(name, "stop", 0);
2412 void restart_service(const char *name)
2414 do_service(name, "restart", 0);