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
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
38 #include <arpa/inet.h>
44 #include <sys/mount.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");
73 const char *router_ip
;
77 char *mac
, *ip
, *name
;
92 start_service("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");
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
);
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
);
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")) {
128 "rebind-localhost-ok\n");
129 // allow RFC1918 responses for server domain
130 switch (get_wan_proto()) {
132 nv
= nvram_get("pptp_server_ip");
135 nv
= nvram_get("l2tp_server_ip");
141 if (nv
&& *nv
) fprintf(f
, "rebind-domain-ok=%s\n", nv
);
144 for (n
= 0 ; n
< dns
->count
; ++n
) {
145 if (dns
->dns
[n
].port
!= 53) {
146 fprintf(f
, "server=%s#%u\n", inet_ntoa(dns
->dns
[n
].addr
), dns
->dns
[n
].port
);
150 if (nvram_get_int("dhcpd_static_only")) {
151 fprintf(f
, "dhcp-ignore=tag:!known\n");
156 char lanN_proto
[] = "lanXX_proto";
157 char lanN_ifname
[] = "lanXX_ifname";
158 char lanN_ipaddr
[] = "lanXX_ipaddr";
159 char lanN_netmask
[] = "lanXX_netmask";
160 char dhcpdN_startip
[] = "dhcpdXX_startip";
161 char dhcpdN_endip
[] = "dhcpdXX_endip";
162 char dhcpN_start
[] = "dhcpXX_start";
163 char dhcpN_num
[] = "dhcpXX_num";
164 char dhcpN_lease
[] = "dhcpXX_lease";
166 for(br
=0 ; br
<=3 ; br
++) {
167 char bridge
[2] = "0";
173 sprintf(lanN_proto
, "lan%s_proto", bridge
);
174 sprintf(lanN_ifname
, "lan%s_ifname", bridge
);
175 sprintf(lanN_ipaddr
, "lan%s_ipaddr", bridge
);
176 do_dhcpd
= nvram_match(lanN_proto
, "dhcp");
180 router_ip
= nvram_safe_get(lanN_ipaddr
);
181 strlcpy(lan
, router_ip
, sizeof(lan
));
182 if ((p
= strrchr(lan
, '.')) != NULL
) *(p
+ 1) = 0;
186 nvram_safe_get(lanN_ifname
));
188 sprintf(dhcpN_lease
, "dhcp%s_lease", bridge
);
189 dhcp_lease
= nvram_get_int(dhcpN_lease
);
191 if (dhcp_lease
<= 0) dhcp_lease
= 1440;
193 if ((e
= nvram_get("dhcpd_slt")) != NULL
) n
= atoi(e
); else n
= 0;
194 if (n
< 0) strcpy(sdhcp_lease
, "infinite");
195 else sprintf(sdhcp_lease
, "%dm", (n
> 0) ? n
: dhcp_lease
);
198 // if not using dnsmasq for dns
200 if ((dns
->count
== 0) && (nvram_get_int("dhcpd_llndns"))) {
201 // no DNS might be temporary. use a low lease time to force clients to update.
203 strcpy(sdhcp_lease
, "2m");
207 // pass the dns directly
209 for (n
= 0 ; n
< dns
->count
; ++n
) {
210 if (dns
->dns
[n
].port
== 53) { // check: option 6 doesn't seem to support other ports
211 sprintf(buf
+ strlen(buf
), ",%s", inet_ntoa(dns
->dns
[n
].addr
));
214 fprintf(f
, "dhcp-option=%s,6%s\n", nvram_safe_get(lanN_ifname
), buf
);
218 sprintf(dhcpdN_startip
, "dhcpd%s_startip", bridge
);
219 sprintf(dhcpdN_endip
, "dhcpd%s_endip", bridge
);
220 sprintf(lanN_netmask
, "lan%s_netmask", bridge
);
222 if ((p
= nvram_get(dhcpdN_startip
)) && (*p
) && (e
= nvram_get(dhcpdN_endip
)) && (*e
)) {
223 fprintf(f
, "dhcp-range=%s,%s,%s,%s,%dm\n", nvram_safe_get(lanN_ifname
), p
, e
, nvram_safe_get(lanN_netmask
), dhcp_lease
);
227 sprintf(dhcpN_start
, "dhcp%s_start", bridge
);
228 sprintf(dhcpN_num
, "dhcp%s_num", bridge
);
229 sprintf(lanN_netmask
, "lan%s_netmask", bridge
);
230 dhcp_start
= nvram_get_int(dhcpN_start
);
231 dhcp_count
= nvram_get_int(dhcpN_num
);
232 fprintf(f
, "dhcp-range=%s,%s%d,%s%d,%s,%dm\n",
233 nvram_safe_get(lanN_ifname
), lan
, dhcp_start
, lan
, dhcp_start
+ dhcp_count
- 1, nvram_safe_get(lanN_netmask
), dhcp_lease
);
236 nv
= nvram_safe_get(lanN_ipaddr
);
237 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED
)) {
238 p
= nvram_safe_get("lan_gateway");
239 if ((*p
) && (strcmp(p
, "0.0.0.0") != 0)) nv
= p
;
243 "dhcp-option=%s,3,%s\n", // gateway
244 nvram_safe_get(lanN_ifname
), nv
);
246 if (((nv
= nvram_get("wan_wins")) != NULL
) && (*nv
) && (strcmp(nv
, "0.0.0.0") != 0)) {
247 fprintf(f
, "dhcp-option=%s,44,%s\n", nvram_safe_get(lanN_ifname
), nv
);
249 #ifdef TCONFIG_SAMBASRV
250 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
251 if ((nv
== NULL
) || (*nv
== 0) || (strcmp(nv
, "0.0.0.0") == 0)) {
252 // Samba will serve as a WINS server
253 fprintf(f
, "dhcp-option=%s,44,0.0.0.0\n", nvram_safe_get(lanN_ifname
));
258 if (strcmp(nvram_safe_get(lanN_ifname
),"")!=0) {
259 fprintf(f
, "interface=%s\n", nvram_safe_get(lanN_ifname
));
260 fprintf(f
, "no-dhcp-interface=%s\n", nvram_safe_get(lanN_ifname
));
263 // write static lease entries & create hosts file
265 mkdir_if_none(dmhosts
);
266 snprintf(buf
, sizeof(buf
), "%s/hosts", dmhosts
);
267 if ((hf
= fopen(buf
, "w")) != NULL
) {
268 if (((nv
= nvram_get("wan_hostname")) != NULL
) && (*nv
))
269 fprintf(hf
, "%s %s\n", router_ip
, nv
);
270 #ifdef TCONFIG_SAMBASRV
271 else if (((nv
= nvram_get("lan_hostname")) != NULL
) && (*nv
))
272 fprintf(hf
, "%s %s\n", router_ip
, nv
);
274 p
= (char *)get_wanip();
275 if ((*p
== 0) || strcmp(p
, "0.0.0.0") == 0)
277 fprintf(hf
, "%s wan-ip\n", p
);
279 fprintf(hf
, "%s %s-wan\n", p
, nv
);
282 mkdir_if_none(dmdhcp
);
283 snprintf(buf
, sizeof(buf
), "%s/dhcp-hosts", dmdhcp
);
284 df
= fopen(buf
, "w");
286 // PREVIOUS/OLD FORMAT:
287 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
288 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
289 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 106 w/ delim
291 // NEW FORMAT (+static ARP binding after hostname):
292 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 55 w/ delim
293 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 87 w/ delim
294 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz<a> = 108 w/ delim
296 p
= nvram_safe_get("dhcpd_static");
297 while ((e
= strchr(p
, '>')) != NULL
) {
308 if ((e
= strchr(buf
, '<')) == NULL
) continue;
313 if ((e
= strchr(ip
, '<')) == NULL
) continue;
315 if (strchr(ip
, '.') == NULL
) {
317 if ((ipn
<= 0) || (ipn
> 255)) continue;
318 sprintf(ipbuf
, "%s%d", lan
, ipn
);
322 if (inet_addr(ip
) == INADDR_NONE
) continue;
327 if ((e
= strchr(name
, '<')) != NULL
) {
331 if ((hf
) && (*name
!= 0)) {
332 fprintf(hf
, "%s %s\n", ip
, name
);
335 if ((do_dhcpd_hosts
> 0) && (*mac
!= 0) && (strcmp(mac
, "00:00:00:00:00:00") != 0)) {
336 if (nvram_get_int("dhcpd_slt") == 0) {
337 fprintf(f
, "dhcp-host=%s,%s\n", mac
, ip
);
339 fprintf(f
, "dhcp-host=%s,%s,%s\n", mac
, ip
, sdhcp_lease
);
347 n
= nvram_get_int("dhcpd_lmax");
349 "dhcp-lease-max=%d\n",
351 if (nvram_get_int("dhcpd_auth") >= 0) {
352 fprintf(f
, "dhcp-authoritative\n");
357 #ifdef TCONFIG_OPENVPN
358 write_vpn_dnsmasq_config(f
);
361 fprintf(f
, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
363 fappend(f
, "/etc/dnsmasq.custom");
370 unlink("/etc/resolv.conf");
371 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
374 TRACE_PT("run dnsmasq\n");
376 // Default to some values we like, but allow the user to override them.
377 eval("dnsmasq", "-c", "1500", "--log-async");
379 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
386 void stop_dnsmasq(void)
391 stop_service("dnsmasq");
397 unlink("/etc/resolv.conf");
398 symlink(dmresolv
, "/etc/resolv.conf");
400 killall_tk("dnsmasq");
405 void clear_resolv(void)
407 f_write(dmresolv
, NULL
, 0, 0, 0); // blank
411 static int write_ipv6_dns_servers(FILE *f
, const char *prefix
, char *dns
, const char *suffix
, int once
)
413 char p
[INET6_ADDRSTRLEN
+ 1], *next
= NULL
;
414 struct in6_addr addr
;
417 foreach(p
, dns
, next
) {
418 // verify that this is a valid IPv6 address
419 if (inet_pton(AF_INET6
, p
, &addr
) == 1) {
420 fprintf(f
, "%s%s%s", (once
&& cnt
) ? "" : prefix
, p
, suffix
);
429 void dns_to_resolv(void)
432 const dns_list_t
*dns
;
436 m
= umask(022); // 077 from pppoecd
437 if ((f
= fopen(dmresolv
, "w")) != NULL
) {
438 // Check for VPN DNS entries
439 if (!write_vpn_resolv(f
)) {
441 if (write_ipv6_dns_servers(f
, "nameserver ", nvram_safe_get("ipv6_dns"), "\n", 0) == 0 || nvram_get_int("dns_addget"))
442 write_ipv6_dns_servers(f
, "nameserver ", nvram_safe_get("ipv6_get_dns"), "\n", 0);
444 dns
= get_dns(); // static buffer
445 if (dns
->count
== 0) {
446 // Put a pseudo DNS IP to trigger Connect On Demand
447 if (nvram_match("ppp_demand", "1")) {
448 switch (get_wan_proto()) {
453 fprintf(f
, "nameserver 1.1.1.1\n");
459 for (i
= 0; i
< dns
->count
; i
++) {
460 if (dns
->dns
[i
].port
== 53) { // resolv.conf doesn't allow for an alternate port
461 fprintf(f
, "nameserver %s\n", inet_ntoa(dns
->dns
[i
].addr
));
471 // -----------------------------------------------------------------------------
473 void start_httpd(void)
476 start_service("httpd");
486 void stop_httpd(void)
489 stop_service("httpd");
496 // -----------------------------------------------------------------------------
499 static void add_ip6_lanaddr(void)
501 char ip
[INET6_ADDRSTRLEN
+ 4];
504 p
= ipv6_router_address(NULL
);
506 snprintf(ip
, sizeof(ip
), "%s/%d", p
, nvram_get_int("ipv6_prefix_length") ? : 64);
507 eval("ip", "-6", "addr", "add", ip
, "dev", nvram_safe_get("lan_ifname"));
511 void start_ipv6_tunnel(void)
513 char ip
[INET6_ADDRSTRLEN
+ 4];
514 struct in_addr addr4
;
515 struct in6_addr addr
;
516 const char *wanip
, *mtu
, *tun_dev
;
519 service
= get_ipv6_service();
520 tun_dev
= get_wan6face();
522 mtu
= (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
525 if (service
== IPV6_ANYCAST_6TO4
)
526 snprintf(ip
, sizeof(ip
), "192.88.99.%d", nvram_get_int("ipv6_relay"));
528 strlcpy(ip
, (char *)nvram_safe_get("ipv6_tun_v4end"), sizeof(ip
));
529 eval("ip", "tunnel", "add", (char *)tun_dev
, "mode", "sit",
531 "local", (char *)wanip
,
532 "ttl", nvram_safe_get("ipv6_tun_ttl"));
534 eval("ip", "link", "set", (char *)tun_dev
, "mtu", (char *)mtu
, "up");
535 nvram_set("ipv6_ifname", (char *)tun_dev
);
537 if (service
== IPV6_ANYCAST_6TO4
) {
540 memset(&addr
, 0, sizeof(addr
));
541 inet_aton(wanip
, &addr4
);
542 addr
.s6_addr16
[0] = htons(0x2002);
543 ipv6_mapaddr4(&addr
, 16, &addr4
, 0);
544 addr
.s6_addr16
[7] = htons(0x0001);
545 inet_ntop(AF_INET6
, &addr
, ip
, sizeof(ip
));
546 strncat(ip
, "/16", sizeof(ip
));
549 snprintf(ip
, sizeof(ip
), "%s/%d",
550 nvram_safe_get("ipv6_tun_addr"),
551 nvram_get_int("ipv6_tun_addrlen") ? : 64);
553 eval("ip", "addr", "add", ip
, "dev", (char *)tun_dev
);
554 eval("ip", "route", "add", "::/0", "dev", (char *)tun_dev
);
557 if (service
== IPV6_ANYCAST_6TO4
)
561 void stop_ipv6_tunnel(void)
563 eval("ip", "tunnel", "del", (char *)get_wan6face());
564 if (get_ipv6_service() == IPV6_ANYCAST_6TO4
) {
565 // get rid of old IPv6 address from lan iface
566 eval("ip", "-6", "addr", "flush", "dev", nvram_safe_get("lan_ifname"), "scope", "global");
571 static pid_t pid_radvd
= -1;
573 void start_radvd(void)
576 char *prefix
, *ip
, *mtu
;
578 char *argv
[] = { "radvd", NULL
, NULL
, NULL
};
579 int pid
, argc
, service
, cnt
;
582 start_service("radvd");
588 if (ipv6_enabled() && nvram_get_int("ipv6_radvd")) {
589 service
= get_ipv6_service();
590 do_6to4
= (service
== IPV6_ANYCAST_6TO4
);
594 case IPV6_NATIVE_DHCP
:
597 case IPV6_ANYCAST_6TO4
:
599 mtu
= (nvram_get_int("ipv6_tun_mtu") > 0) ? nvram_safe_get("ipv6_tun_mtu") : "1480";
602 prefix
= do_6to4
? "0:0:0:1::" : nvram_safe_get("ipv6_prefix");
605 if (!(*prefix
)) prefix
= "::";
608 if ((f
= fopen("/etc/radvd.conf", "w")) == NULL
) return;
610 ip
= (char *)ipv6_router_address(NULL
);
611 do_dns
= (*ip
) && nvram_match("dhcpd_dmdns", "1");
616 " IgnoreIfMissing on;\n"
617 " AdvSendAdvert on;\n"
618 " MaxRtrAdvInterval 60;\n"
619 " AdvHomeAgentFlag off;\n"
620 " AdvManagedFlag off;\n"
625 " AdvAutonomous on;\n"
629 nvram_safe_get("lan_ifname"),
630 mtu
? " AdvLinkMTU " : "", mtu
? : "", mtu
? ";\n" : "",
632 do_6to4
? " AdvValidLifetime 300;\n AdvPreferredLifetime 120;\n" : "",
633 do_6to4
? " Base6to4Interface " : "",
634 do_6to4
? get_wanface() : "",
635 do_6to4
? ";\n" : "");
638 fprintf(f
, " RDNSS %s {};\n", ip
);
641 cnt
= write_ipv6_dns_servers(f
, " RDNSS ", nvram_safe_get("ipv6_dns"), " ", 1);
642 if (cnt
== 0 || nvram_get_int("dns_addget"))
643 cnt
+= write_ipv6_dns_servers(f
, (cnt
) ? "" : " RDNSS ", nvram_safe_get("ipv6_get_dns"), " ", 1);
644 if (cnt
) fprintf(f
, "{};\n");
648 "};\n"); // close "interface" section
653 if (nvram_get_int("debug_ipv6")) {
658 _eval(argv
, NULL
, 0, &pid
);
660 if (!nvram_contains_word("debug_norestart", "radvd")) {
666 void stop_radvd(void)
669 stop_service("radvd");
677 void start_ipv6(void)
681 service
= get_ipv6_service();
684 // Check if turned on
691 case IPV6_NATIVE_DHCP
:
692 case IPV6_ANYCAST_6TO4
:
693 nvram_set("ipv6_rtr_addr", "");
694 nvram_set("ipv6_prefix", "");
698 if (service
!= IPV6_DISABLED
) {
699 if ((nvram_get_int("ipv6_accept_ra") & 2) != 0 && !nvram_get_int("ipv6_radvd"))
700 accept_ra(nvram_safe_get("lan_ifname"));
708 eval("ip", "-6", "addr", "flush", "scope", "global");
713 // -----------------------------------------------------------------------------
715 void start_upnp(void)
718 start_service("upnp");
722 if (get_wan_proto() == WP_DISABLED
) return;
728 if (((enable
= nvram_get_int("upnp_enable")) & 3) != 0) {
729 mkdir("/etc/upnp", 0777);
730 if (f_exists("/etc/upnp/config.alt")) {
731 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
734 if ((f
= fopen("/etc/upnp/config", "w")) != NULL
) {
735 upnp_port
= nvram_get_int("upnp_port");
736 if ((upnp_port
< 0) || (upnp_port
>= 0xFFFF)) upnp_port
= 0;
745 "upnp_forward_chain=upnp\n"
746 "upnp_nat_chain=upnp\n"
747 "notify_interval=%d\n"
748 "system_uptime=yes\n"
753 (enable
& 1) ? "yes" : "no", // upnp enable
754 (enable
& 2) ? "yes" : "no", // natpmp enable
755 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
756 nvram_get_int("upnp_ssdp_interval")
759 if (nvram_get_int("upnp_clean")) {
760 int interval
= nvram_get_int("upnp_clean_interval");
761 if (interval
< 60) interval
= 60;
763 "clean_ruleset_interval=%d\n"
764 "clean_ruleset_threshold=%d\n",
766 nvram_get_int("upnp_clean_threshold")
770 fprintf(f
,"clean_ruleset_interval=0\n");
772 if (nvram_match("upnp_mnp", "1")) {
773 int https
= nvram_get_int("https_enable");
774 fprintf(f
, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
775 https
? "s" : "", nvram_safe_get("lan_ipaddr"),
776 nvram_safe_get(https
? "https_lanport" : "http_lanport"));
779 // Empty parameters are not included into XML service description
780 fprintf(f
, "presentation_url=\n");
784 f_read_string("/proc/sys/kernel/random/uuid", uuid
, sizeof(uuid
));
785 fprintf(f
, "uuid=%s\n", uuid
);
787 char lanN_ipaddr
[] = "lanXX_ipaddr";
788 char lanN_netmask
[] = "lanXX_netmask";
789 char upnp_lanN
[] = "upnp_lanXX";
792 for(br
=0 ; br
<4 ; br
++) {
793 char bridge
[2] = "0";
799 sprintf(lanN_ipaddr
, "lan%s_ipaddr", bridge
);
800 sprintf(lanN_netmask
, "lan%s_netmask", bridge
);
801 sprintf(upnp_lanN
, "upnp_lan%s", bridge
);
803 char *lanip
= nvram_safe_get(lanN_ipaddr
);
804 char *lanmask
= nvram_safe_get(lanN_netmask
);
805 char *lanlisten
= nvram_safe_get(upnp_lanN
);
806 if((strcmp(lanlisten
,"1")==0) && (strcmp(lanip
,"")!=0) && (strcmp(lanip
,"0.0.0.0")!=0)) {
808 "listening_ip=%s/%s\n",
811 if ((ports
[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
812 (ports
[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
813 (ports
[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
814 (ports
[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
816 "allow %d-%d %s/%s %d-%d\n",
823 // by default allow only redirection of ports above 1024
824 fprintf(f
, "allow 1024-65535 %s/%s 1024-65535\n", lanip
, lanmask
);
829 fappend(f
, "/etc/upnp/config.custom");
830 fprintf(f
, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
833 xstart("miniupnpd", "-f", "/etc/upnp/config");
842 stop_service("upnp");
846 killall_tk("miniupnpd");
849 // -----------------------------------------------------------------------------
851 static pid_t pid_crond
= -1;
853 void start_cron(void)
857 eval("crond", nvram_contains_word("log_events", "crond") ? NULL
: "-l", "9");
858 if (!nvram_contains_word("debug_norestart", "crond")) {
869 // -----------------------------------------------------------------------------
872 static pid_t pid_hotplug2
= -1;
874 void start_hotplug2()
878 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE
, 0);
879 xstart("hotplug2", "--persistent", "--no-coldplug");
880 // FIXME: Don't remember exactly why I put "sleep" here -
881 // but it was not for a race with check_services()... - TB
884 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
889 void stop_hotplug2(void)
892 killall_tk("hotplug2");
896 // -----------------------------------------------------------------------------
898 // Written by Sparq in 2002/07/16
899 void start_zebra(void)
903 start_service("zebra");
909 char *lan_tx
= nvram_safe_get("dr_lan_tx");
910 char *lan_rx
= nvram_safe_get("dr_lan_rx");
911 char *lan1_tx
= nvram_safe_get("dr_lan1_tx");
912 char *lan1_rx
= nvram_safe_get("dr_lan1_rx");
913 char *lan2_tx
= nvram_safe_get("dr_lan2_tx");
914 char *lan2_rx
= nvram_safe_get("dr_lan2_rx");
915 char *lan3_tx
= nvram_safe_get("dr_lan3_tx");
916 char *lan3_rx
= nvram_safe_get("dr_lan3_rx");
917 char *wan_tx
= nvram_safe_get("dr_wan_tx");
918 char *wan_rx
= nvram_safe_get("dr_wan_rx");
920 if ((*lan_tx
== '0') && (*lan_rx
== '0') &&
921 (*lan1_tx
== '0') && (*lan1_rx
== '0') &&
922 (*lan2_tx
== '0') && (*lan2_rx
== '0') &&
923 (*lan3_tx
== '0') && (*lan3_rx
== '0') &&
924 (*wan_tx
== '0') && (*wan_rx
== '0')) {
929 if ((fp
= fopen("/etc/zebra.conf", "w")) != NULL
) {
934 if ((fp
= fopen("/etc/ripd.conf", "w")) != NULL
) {
935 char *lan_ifname
= nvram_safe_get("lan_ifname");
936 char *lan1_ifname
= nvram_safe_get("lan1_ifname");
937 char *lan2_ifname
= nvram_safe_get("lan2_ifname");
938 char *lan3_ifname
= nvram_safe_get("lan3_ifname");
939 char *wan_ifname
= nvram_safe_get("wan_ifname");
941 fprintf(fp
, "router rip\n");
942 if(strcmp(lan_ifname
,"")!=0)
943 fprintf(fp
, "network %s\n", lan_ifname
);
944 if(strcmp(lan1_ifname
,"")!=0)
945 fprintf(fp
, "network %s\n", lan1_ifname
);
946 if(strcmp(lan2_ifname
,"")!=0)
947 fprintf(fp
, "network %s\n", lan2_ifname
);
948 if(strcmp(lan3_ifname
,"")!=0)
949 fprintf(fp
, "network %s\n", lan3_ifname
);
950 fprintf(fp
, "network %s\n", wan_ifname
);
951 fprintf(fp
, "redistribute connected\n");
952 //fprintf(fp, "redistribute static\n");
954 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
955 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
957 if(strcmp(lan_ifname
,"")!=0) {
958 fprintf(fp
, "interface %s\n", lan_ifname
);
959 if (*lan_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", lan_tx
);
960 if (*lan_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", lan_rx
);
962 if(strcmp(lan1_ifname
,"")!=0) {
963 fprintf(fp
, "interface %s\n", lan1_ifname
);
964 if (*lan1_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", lan1_tx
);
965 if (*lan1_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", lan1_rx
);
967 if(strcmp(lan2_ifname
,"")!=0) {
968 fprintf(fp
, "interface %s\n", lan2_ifname
);
969 if (*lan2_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", lan2_tx
);
970 if (*lan2_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", lan2_rx
);
972 if(strcmp(lan3_ifname
,"")!=0) {
973 fprintf(fp
, "interface %s\n", lan3_ifname
);
974 if (*lan3_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", lan3_tx
);
975 if (*lan3_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", lan3_rx
);
977 fprintf(fp
, "interface %s\n", wan_ifname
);
978 if (*wan_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", wan_tx
);
979 if (*wan_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", wan_rx
);
981 fprintf(fp
, "router rip\n");
982 if(strcmp(lan_ifname
,"")!=0) {
983 if (*lan_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", lan_ifname
);
984 if (*lan_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", lan_ifname
);
986 if(strcmp(lan1_ifname
,"")!=0) {
987 if (*lan1_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", lan1_ifname
);
988 if (*lan1_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", lan1_ifname
);
990 if(strcmp(lan2_ifname
,"")!=0) {
991 if (*lan2_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", lan2_ifname
);
992 if (*lan2_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", lan2_ifname
);
994 if(strcmp(lan3_ifname
,"")!=0) {
995 if (*lan3_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", lan3_ifname
);
996 if (*lan3_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", lan3_ifname
);
998 if (*wan_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", wan_ifname
);
999 if (*wan_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", wan_ifname
);
1000 fprintf(fp
, "access-list private deny any\n");
1002 //fprintf(fp, "debug rip events\n");
1003 //fprintf(fp, "log file /etc/ripd.log\n");
1007 xstart("zebra", "-d");
1008 xstart("ripd", "-d");
1012 void stop_zebra(void)
1014 #ifdef TCONFIG_ZEBRA
1015 if (getpid() != 1) {
1016 stop_service("zebra");
1020 killall("zebra", SIGTERM
);
1021 killall("ripd", SIGTERM
);
1023 unlink("/etc/zebra.conf");
1024 unlink("/etc/ripd.conf");
1028 // -----------------------------------------------------------------------------
1030 void start_syslog(void)
1040 char *rot_siz
= "50";
1041 char *rot_keep
= "1";
1042 char *log_file_path
;
1044 argv
[0] = "syslogd";
1047 if (nvram_match("log_remote", "1")) {
1048 nv
= nvram_safe_get("log_remoteip");
1050 snprintf(rem
, sizeof(rem
), "%s:%s", nv
, nvram_safe_get("log_remoteport"));
1051 argv
[argc
++] = "-R";
1056 if (nvram_match("log_file", "1")) {
1057 argv
[argc
++] = "-L";
1059 if (strcmp(nvram_safe_get("log_file_size"), "") != 0) {
1060 rot_siz
= nvram_safe_get("log_file_size");
1062 if (nvram_get_int("log_file_size") > 0) {
1063 rot_keep
= nvram_safe_get("log_file_keep");
1066 // log to custom path - shibby
1067 if (nvram_match("log_file_custom", "1")) {
1068 log_file_path
= nvram_safe_get("log_file_path");
1069 argv
[argc
++] = roz_siz
;
1070 argv
[argc
++] = "-O";
1071 argv
[argc
++] = log_file_path
;
1072 if (strcmp(nvram_safe_get("log_file_path"), "/var/log/messages") != 0) {
1073 remove("/var/log/messages");
1074 symlink(log_file_path
, "/var/log/messages");
1079 /* Read options: rotate_size(kb) num_backups logfilename.
1080 * Ignore these settings and use defaults if the logfile cannot be written to.
1082 if (f_read_string("/etc/syslogd.cfg", cfg
, sizeof(cfg
)) > 0) {
1083 if ((nv
= strchr(cfg
, '\n')))
1086 if ((nv
= strtok(cfg
, " \t"))) {
1091 if ((nv
= strtok(NULL
, " \t")))
1094 if ((nv
= strtok(NULL
, " \t")) && *nv
== '/') {
1095 if (f_write(nv
, cfg
, 0, FW_APPEND
, 0) >= 0) {
1096 argv
[argc
++] = "-O";
1106 if (nvram_match("log_file_custom", "0")) {
1107 argv
[argc
++] = "-s";
1108 argv
[argc
++] = rot_siz
;
1109 remove("/var/log/messages");
1112 if (isdigit(*b_opt
)) {
1113 argv
[argc
++] = "-b";
1114 argv
[argc
++] = b_opt
;
1116 if (nvram_get_int("log_file_size") > 0) {
1117 argv
[argc
++] = "-b";
1118 argv
[argc
++] = rot_keep
;
1124 _eval(argv
, NULL
, 0, NULL
);
1128 _eval(argv
, NULL
, 0, NULL
);
1130 // used to be available in syslogd -m
1131 n
= nvram_get_int("log_mark");
1135 sprintf(rem
, "*/%d * * * *", n
);
1136 else if (n
< 60 * 24)
1137 sprintf(rem
, "0 */%d * * *", n
/ 60);
1139 sprintf(rem
, "0 0 */%d * *", n
/ (60 * 24));
1140 sprintf(s
, "%s logger -p syslog.info -- -- MARK --", rem
);
1141 eval("cru", "a", "syslogdmark", s
);
1144 eval("cru", "d", "syslogdmark");
1149 void stop_syslog(void)
1151 killall("klogd", SIGTERM
);
1152 killall("syslogd", SIGTERM
);
1155 // -----------------------------------------------------------------------------
1157 static pid_t pid_igmp
= -1;
1159 void start_igmp_proxy(void)
1164 if (nvram_match("multicast_pass", "1")) {
1165 if (get_wan_proto() == WP_DISABLED
)
1168 if (f_exists("/etc/igmp.alt")) {
1169 eval("igmpproxy", "/etc/igmp.alt");
1171 else if ((fp
= fopen("/etc/igmp.conf", "w")) != NULL
) {
1174 "phyint %s upstream\n"
1176 // "phyint %s downstream ratelimit 0\n",
1178 nvram_get("multicast_altnet") ? : "0.0.0.0/0");
1179 // nvram_safe_get("lan_ifname"));
1181 char lanN_ifname
[] = "lanXX_ifname";
1182 char multicast_lanN
[] = "multicast_lanXX";
1185 for(br
=0 ; br
<4 ; br
++) {
1186 char bridge
[2] = "0";
1192 sprintf(lanN_ifname
, "lan%s_ifname", bridge
);
1193 sprintf(multicast_lanN
, "multicast_lan%s", bridge
);
1195 if((strcmp(nvram_safe_get(multicast_lanN
),"1")==0) && (strcmp(nvram_safe_get(lanN_ifname
),"")!=0)) {
1197 "phyint %s downstream ratelimit 0\n",
1198 nvram_safe_get(lanN_ifname
));
1202 eval("igmpproxy", "/etc/igmp.conf");
1207 if (!nvram_contains_word("debug_norestart", "igmprt")) {
1213 void stop_igmp_proxy(void)
1216 killall_tk("igmpproxy");
1219 #ifdef TCONFIG_NOCAT
1221 static pid_t pid_splashd
= -1;
1222 void start_splashd(void)
1226 if (!nvram_contains_word("debug_norestart", "splashd")) {
1231 void stop_splashd(void)
1239 // -----------------------------------------------------------------------------
1243 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE
|FW_NEWLINE
, 0644);
1246 void start_ntpc(void)
1252 if (nvram_get_int("ntp_updates") >= 0) {
1253 xstart("ntpsync", "--init");
1257 void stop_ntpc(void)
1259 killall("ntpsync", SIGTERM
);
1262 // -----------------------------------------------------------------------------
1264 static void stop_rstats(void)
1274 while ((n
-- > 0) && ((pid
= pidof("rstats")) > 0)) {
1276 pidz
= pidof("gzip");
1277 if (pidz
< 1) pidz
= pidof("cp");
1278 ppidz
= ppid(ppid(pidz
));
1279 if ((m
> 0) && (pidz
> 0) && (pid
== ppidz
)) {
1280 syslog(LOG_DEBUG
, "rstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid
, pidz
, ppidz
);
1287 if ((w
== 1) && (n
> 0))
1288 syslog(LOG_DEBUG
, "rstats stopped.\n");
1291 static void start_rstats(int new)
1293 if (nvram_match("rstats_enable", "1")) {
1296 syslog(LOG_DEBUG
, "starting rstats (new datafile).\n");
1297 xstart("rstats", "--new");
1299 syslog(LOG_DEBUG
, "starting rstats.\n");
1305 static void stop_cstats(void)
1315 while ((n
-- > 0) && ((pid
= pidof("cstats")) > 0)) {
1317 pidz
= pidof("gzip");
1318 if (pidz
< 1) pidz
= pidof("cp");
1319 ppidz
= ppid(ppid(pidz
));
1320 if ((m
> 0) && (pidz
> 0) && (pid
== ppidz
)) {
1321 syslog(LOG_DEBUG
, "cstats(PID %d) shutting down, waiting for helper process to complete(PID %d, PPID %d).\n", pid
, pidz
, ppidz
);
1328 if ((w
== 1) && (n
> 0))
1329 syslog(LOG_DEBUG
, "cstats stopped.\n");
1332 static void start_cstats(int new)
1334 if (nvram_match("cstats_enable", "1")) {
1337 syslog(LOG_DEBUG
, "starting cstats (new datafile).\n");
1338 xstart("cstats", "--new");
1340 syslog(LOG_DEBUG
, "starting cstats.\n");
1346 // -----------------------------------------------------------------------------
1348 // !!TB - FTP Server
1351 static char *get_full_storage_path(char *val
)
1353 static char buf
[128];
1357 len
= sprintf(buf
, "%s", val
);
1359 len
= sprintf(buf
, "%s/%s", MOUNT_ROOT
, val
);
1361 if (len
> 1 && buf
[len
- 1] == '/')
1367 static char *nvram_storage_path(char *var
)
1369 char *val
= nvram_safe_get(var
);
1370 return get_full_storage_path(val
);
1373 char vsftpd_conf
[] = "/etc/vsftpd.conf";
1374 char vsftpd_users
[] = "/etc/vsftpd.users";
1375 char vsftpd_passwd
[] = "/etc/vsftpd.passwd";
1377 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
1379 static void start_ftpd(void)
1386 char *user
, *pass
, *rights
, *root_dir
;
1388 if (getpid() != 1) {
1389 start_service("ftpd");
1393 if (!nvram_get_int("ftp_enable")) return;
1395 mkdir_if_none(vsftpd_users
);
1396 mkdir_if_none("/var/run/vsftpd");
1398 if ((fp
= fopen(vsftpd_conf
, "w")) == NULL
)
1401 if (nvram_get_int("ftp_super"))
1404 sprintf(tmp
, "%s/%s", vsftpd_users
, "admin");
1405 if ((f
= fopen(tmp
, "w")))
1408 "dirlist_enable=yes\n"
1409 "write_enable=yes\n"
1410 "download_enable=yes\n");
1415 #ifdef TCONFIG_SAMBASRV
1416 if (nvram_match("smbd_cset", "utf8"))
1417 fprintf(fp
, "utf8=yes\n");
1420 if (nvram_invmatch("ftp_anonymous", "0"))
1423 "anon_allow_writable_root=yes\n"
1424 "anon_world_readable_only=no\n"
1425 "anon_umask=022\n");
1428 sprintf(tmp
, "%s/ftp", vsftpd_users
);
1429 if ((f
= fopen(tmp
, "w")))
1431 if (nvram_match("ftp_dirlist", "0"))
1432 fprintf(f
, "dirlist_enable=yes\n");
1433 if (nvram_match("ftp_anonymous", "1") ||
1434 nvram_match("ftp_anonymous", "3"))
1435 fprintf(f
, "write_enable=yes\n");
1436 if (nvram_match("ftp_anonymous", "1") ||
1437 nvram_match("ftp_anonymous", "2"))
1438 fprintf(f
, "download_enable=yes\n");
1441 if (nvram_match("ftp_anonymous", "1") ||
1442 nvram_match("ftp_anonymous", "3"))
1444 "anon_upload_enable=yes\n"
1445 "anon_mkdir_write_enable=yes\n"
1446 "anon_other_write_enable=yes\n");
1448 fprintf(fp
, "anonymous_enable=no\n");
1452 "dirmessage_enable=yes\n"
1453 "download_enable=no\n"
1454 "dirlist_enable=no\n"
1456 "syslog_enable=yes\n"
1457 "local_enable=yes\n"
1460 "chroot_local_user=yes\n"
1462 "log_ftp_protocol=%s\n"
1463 "user_config_dir=%s\n"
1471 "max_login_fails=1\n"
1472 "idle_session_timeout=%s\n"
1474 "anon_max_rate=%d\n"
1475 "local_max_rate=%d\n"
1477 nvram_get_int("log_ftp") ? "yes" : "no",
1478 vsftpd_users
, vsftpd_passwd
,
1480 ipv6_enabled() ? "_ipv6" : "",
1484 nvram_get("ftp_port") ? : "21",
1485 nvram_get_int("ftp_max"),
1486 nvram_get_int("ftp_ipmax"),
1487 nvram_get("ftp_staytimeout") ? : "300",
1488 nvram_get_int("ftp_anonrate") * 1024,
1489 nvram_get_int("ftp_rate") * 1024,
1490 nvram_safe_get("ftp_custom"));
1494 /* prepare passwd file and default users */
1495 if ((fp
= fopen(vsftpd_passwd
, "w")) == NULL
)
1498 if (((user
= nvram_get("http_username")) == NULL
) || (*user
== 0)) user
= "admin";
1499 if (((pass
= nvram_get("http_passwd")) == NULL
) || (*pass
== 0)) pass
= "admin";
1501 fprintf(fp
, /* anonymous, admin, nobody */
1502 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
1503 "%s:%s:0:0:root:/:/sbin/nologin\n"
1504 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
1505 nvram_storage_path("ftp_anonroot"), user
,
1506 nvram_get_int("ftp_super") ? crypt(pass
, "$1$") : "x",
1509 if ((buf
= strdup(nvram_safe_get("ftp_users"))) != NULL
)
1512 username<password<rights[<root_dir>]
1520 while ((q
= strsep(&p
, ">")) != NULL
) {
1521 i
= vstrsep(q
, "<", &user
, &pass
, &rights
, &root_dir
);
1522 if (i
< 3 || i
> 4) continue;
1523 if (!user
|| !pass
) continue;
1525 if (i
== 3 || !root_dir
|| !(*root_dir
))
1526 root_dir
= nvram_safe_get("ftp_pubroot");
1529 if (strncmp(rights
, "Private", 7) == 0)
1531 sprintf(tmp
, "%s/%s", nvram_storage_path("ftp_pvtroot"), user
);
1535 sprintf(tmp
, "%s", get_full_storage_path(root_dir
));
1537 fprintf(fp
, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1538 user
, crypt(pass
, "$1$"), user
, tmp
);
1541 sprintf(tmp
, "%s/%s", vsftpd_users
, user
);
1542 if ((f
= fopen(tmp
, "w")))
1545 if (nvram_invmatch("ftp_dirlist", "1"))
1546 strcat(tmp
, "dirlist_enable=yes\n");
1547 if (strstr(rights
, "Read") || !strcmp(rights
, "Private"))
1548 strcat(tmp
, "download_enable=yes\n");
1549 if (strstr(rights
, "Write") || !strncmp(rights
, "Private", 7))
1550 strcat(tmp
, "write_enable=yes\n");
1560 killall("vsftpd", SIGHUP
);
1562 /* start vsftpd if it's not already running */
1563 if (pidof("vsftpd") <= 0)
1567 static void stop_ftpd(void)
1569 if (getpid() != 1) {
1570 stop_service("ftpd");
1574 killall_tk("vsftpd");
1575 unlink(vsftpd_passwd
);
1576 unlink(vsftpd_conf
);
1577 eval("rm", "-rf", vsftpd_users
);
1579 #endif // TCONFIG_FTP
1581 // -----------------------------------------------------------------------------
1585 #ifdef TCONFIG_SAMBASRV
1586 static void kill_samba(int sig
)
1588 if (sig
== SIGTERM
) {
1593 killall("smbd", sig
);
1594 killall("nmbd", sig
);
1598 static void start_samba(void)
1607 if (getpid() != 1) {
1608 start_service("smbd");
1612 mode
= nvram_get_int("smbd_enable");
1613 if (!mode
|| !nvram_invmatch("lan_hostname", ""))
1616 if ((fp
= fopen("/etc/smb.conf", "w")) == NULL
)
1619 fprintf(fp
, "[global]\n"
1620 " interfaces = %s\n"
1621 " bind interfaces only = yes\n"
1623 " netbios name = %s\n"
1624 " server string = %s\n"
1625 " guest account = nobody\n"
1626 " security = user\n"
1629 " guest only = no\n"
1630 " browseable = yes\n"
1631 " syslog only = yes\n"
1632 " timestamp logs = no\n"
1634 " encrypt passwords = yes\n"
1635 " preserve case = yes\n"
1636 " short preserve case = yes\n",
1637 nvram_safe_get("lan_ifname"),
1638 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1639 nvram_safe_get("lan_hostname"),
1640 nvram_get("router_name") ? : "Tomato",
1641 mode
== 2 ? "" : "map to guest = Bad User",
1642 mode
== 2 ? "no" : "yes" // guest ok
1645 if (nvram_get_int("smbd_wins")) {
1646 nv
= nvram_safe_get("wan_wins");
1647 if ((*nv
== 0) || (strcmp(nv
, "0.0.0.0") == 0)) {
1648 fprintf(fp
, " wins support = yes\n");
1652 if (nvram_get_int("smbd_master")) {
1654 " domain master = yes\n"
1655 " local master = yes\n"
1656 " preferred master = yes\n"
1657 " os level = 65\n");
1660 nv
= nvram_safe_get("smbd_cpage");
1662 #ifndef TCONFIG_SAMBA3
1663 fprintf(fp
, " client code page = %s\n", nv
);
1665 sprintf(nlsmod
, "nls_cp%s", nv
);
1667 nv
= nvram_safe_get("smbd_nlsmod");
1668 if ((*nv
) && (strcmp(nv
, nlsmod
) != 0))
1672 nvram_set("smbd_nlsmod", nlsmod
);
1675 #ifndef TCONFIG_SAMBA3
1676 if (nvram_match("smbd_cset", "utf8"))
1677 fprintf(fp
, " coding system = utf8\n");
1678 else if (nvram_invmatch("smbd_cset", ""))
1679 fprintf(fp
, " character set = %s\n", nvram_safe_get("smbd_cset"));
1682 nv
= nvram_safe_get("smbd_custom");
1683 /* add socket options unless overriden by the user */
1684 if (strstr(nv
, "socket options") == NULL
) {
1685 fprintf(fp
, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");
1687 fprintf(fp
, "%s\n\n", nv
);
1689 /* configure shares */
1693 char *name
, *path
, *comment
, *writeable
, *hidden
;
1696 if ((buf
= strdup(nvram_safe_get("smbd_shares"))) != NULL
)
1698 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1701 while ((q
= strsep(&p
, ">")) != NULL
) {
1702 if (vstrsep(q
, "<", &name
, &path
, &comment
, &writeable
, &hidden
) != 5) continue;
1703 if (!path
|| !name
) continue;
1706 fprintf(fp
, "\n[%s]\n", name
);
1709 fprintf(fp
, " path = %s\n", path
);
1712 if (!strcmp(writeable
, "1"))
1713 fprintf(fp
, " writable = yes\n delete readonly = yes\n force user = root\n");
1714 if (!strcmp(hidden
, "1"))
1715 fprintf(fp
, " browseable = no\n");
1719 fprintf(fp
, " comment = %s\n", comment
);
1726 /* Share every mountpoint below MOUNT_ROOT */
1727 if (nvram_get_int("smbd_autoshare") && (dir
= opendir(MOUNT_ROOT
))) {
1728 while ((dp
= readdir(dir
))) {
1729 if (strcmp(dp
->d_name
, ".") && strcmp(dp
->d_name
, "..")) {
1731 /* Only if is a directory and is mounted */
1732 if (!dir_is_mountpoint(MOUNT_ROOT
, dp
->d_name
))
1735 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1736 fprintf(fp
, "\n[%s]\n path = %s/%s\n comment = %s\n",
1737 dp
->d_name
, MOUNT_ROOT
, dp
->d_name
, dp
->d_name
);
1738 if (nvram_match("smbd_autoshare", "3")) // Hidden
1739 fprintf(fp
, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1740 dp
->d_name
, MOUNT_ROOT
, dp
->d_name
);
1741 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1742 fprintf(fp
, " writable = yes\n delete readonly = yes\n force user = root\n");
1748 if (dir
) closedir(dir
);
1751 /* by default share MOUNT_ROOT as read-only */
1752 fprintf(fp
, "\n[share]\n"
1760 mkdir_if_none("/var/run/samba");
1761 mkdir_if_none("/etc/samba");
1763 /* write smbpasswd */
1764 #ifdef TCONFIG_SAMBA3
1765 eval("smbpasswd", "nobody", "\"\"");
1767 eval("smbpasswd", "-a", "nobody", "\"\"");
1771 if (((smbd_user
= nvram_get("smbd_user")) == NULL
) || (*smbd_user
== 0) || !strcmp(smbd_user
, "root"))
1773 #ifdef TCONFIG_SAMBA3
1774 eval("smbpasswd", smbd_user
, nvram_safe_get("smbd_passwd"));
1776 eval("smbpasswd", "-a", smbd_user
, nvram_safe_get("smbd_passwd"));
1781 int ret1
= 0, ret2
= 0;
1782 /* start samba if it's not already running */
1783 if (pidof("nmbd") <= 0)
1784 ret1
= xstart("nmbd", "-D");
1785 if (pidof("smbd") <= 0)
1786 ret2
= xstart("smbd", "-D");
1788 if (ret1
|| ret2
) kill_samba(SIGTERM
);
1791 static void stop_samba(void)
1793 if (getpid() != 1) {
1794 stop_service("smbd");
1798 kill_samba(SIGTERM
);
1800 unlink("/var/log/smb");
1801 unlink("/var/log/nmb");
1802 eval("rm", "-rf", "/var/run/samba");
1804 #endif // TCONFIG_SAMBASRV
1806 #ifdef TCONFIG_MEDIA_SERVER
1807 #define MEDIA_SERVER_APP "minidlna"
1809 static void start_media_server(void)
1812 int port
, pid
, https
;
1814 char *argv
[] = { MEDIA_SERVER_APP
, "-f", "/etc/"MEDIA_SERVER_APP
".conf", "-R", NULL
};
1815 static int once
= 1;
1817 if (getpid() != 1) {
1818 start_service("media");
1822 if (nvram_get_int("ms_sas") == 0)
1825 if (nvram_get_int("ms_enable") != 0) {
1826 if ((!once
) && (nvram_get_int("ms_rescan") == 0)) {
1830 nvram_unset("ms_rescan");
1832 if (f_exists("/etc/"MEDIA_SERVER_APP
".alt")) {
1833 argv
[2] = "/etc/"MEDIA_SERVER_APP
".alt";
1836 if ((f
= fopen(argv
[2], "w")) != NULL
) {
1837 port
= nvram_get_int("ms_port");
1838 https
= nvram_get_int("https_enable");
1839 dbdir
= nvram_safe_get("ms_dbdir");
1840 if (!(*dbdir
)) dbdir
= NULL
;
1841 mkdir_if_none(dbdir
? : "/var/run/"MEDIA_SERVER_APP
);
1844 "network_interface=%s\n"
1846 "friendly_name=%s\n"
1850 "presentation_url=http%s://%s:%s/nas-media.asp\n"
1852 "notify_interval=600\n"
1853 "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"
1855 nvram_safe_get("lan_ifname"),
1856 (port
< 0) || (port
>= 0xffff) ? 0 : port
,
1857 nvram_get("router_name") ? : "Tomato",
1858 dbdir
? : "/var/run/"MEDIA_SERVER_APP
,
1859 nvram_get_int("ms_tivo") ? "yes" : "no",
1860 nvram_get_int("ms_stdlna") ? "yes" : "no",
1861 https
? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https
? "https_lanport" : "http_lanport")
1864 // media directories
1866 char *path
, *restrict
;
1868 if ((buf
= strdup(nvram_safe_get("ms_dirs"))) != NULL
) {
1869 /* path<restrict[A|V|P|] */
1872 while ((q
= strsep(&p
, ">")) != NULL
) {
1873 if (vstrsep(q
, "<", &path
, &restrict
) < 1 || !path
|| !(*path
))
1875 fprintf(f
, "media_dir=%s%s%s\n",
1876 restrict
? : "", (restrict
&& *restrict
) ? "," : "", path
);
1885 /* start media server if it's not already running */
1886 if (pidof(MEDIA_SERVER_APP
) <= 0) {
1887 if ((_eval(argv
, NULL
, 0, &pid
) == 0) && (once
)) {
1888 /* If we started the media server successfully, wait 1 sec
1889 * to let it die if it can't open the database file.
1890 * If it's still alive after that, assume it's running and
1891 * disable forced once-after-reboot rescan.
1894 if (pidof(MEDIA_SERVER_APP
) > 0)
1901 static void stop_media_server(void)
1903 if (getpid() != 1) {
1904 stop_service("media");
1908 killall_tk(MEDIA_SERVER_APP
);
1910 #endif // TCONFIG_MEDIA_SERVER
1913 static void start_nas_services(void)
1915 if (getpid() != 1) {
1916 start_service("usbapps");
1920 #ifdef TCONFIG_SAMBASRV
1926 #ifdef TCONFIG_MEDIA_SERVER
1927 start_media_server();
1935 static void stop_nas_services(void)
1937 if (getpid() != 1) {
1938 stop_service("usbapps");
1942 #ifdef TCONFIG_MEDIA_SERVER
1943 stop_media_server();
1948 #ifdef TCONFIG_SAMBASRV
1957 void restart_nas_services(int stop
, int start
)
1959 int fd
= file_lock("usb");
1960 /* restart all NAS applications */
1962 stop_nas_services();
1964 start_nas_services();
1967 #endif // TCONFIG_USB
1969 // -----------------------------------------------------------------------------
1971 /* -1 = Don't check for this program, it is not expected to be running.
1972 * Other = This program has been started and should be kept running. If no
1973 * process with the name is running, call func to restart it.
1974 * Note: At startup, dnsmasq forks a short-lived child which forks a
1975 * long-lived (grand)child. The parents terminate.
1976 * Many daemons use this technique.
1978 static void _check(pid_t pid
, const char *name
, void (*func
)(void))
1980 if (pid
== -1) return;
1982 if (pidof(name
) > 0) return;
1984 syslog(LOG_DEBUG
, "%s terminated unexpectedly, restarting.\n", name
);
1987 // Force recheck in 500 msec
1988 setitimer(ITIMER_REAL
, &pop_tv
, NULL
);
1991 void check_services(void)
1993 TRACE_PT("keep alive\n");
1995 // Periodically reap any zombies
1996 setitimer(ITIMER_REAL
, &zombie_tv
, NULL
);
1999 _check(pid_hotplug2
, "hotplug2", start_hotplug2
);
2001 _check(pid_dnsmasq
, "dnsmasq", start_dnsmasq
);
2002 _check(pid_crond
, "crond", start_cron
);
2003 _check(pid_igmp
, "igmpproxy", start_igmp_proxy
);
2005 _check(pid_radvd
, "radvd", start_radvd
);
2008 //#ifdef TCONFIG_NOCAT
2009 // if (nvram_get_int("NC_enable"))
2010 // _check(&pid_splashd, "splashd", start_splashd);
2015 // -----------------------------------------------------------------------------
2017 void start_services(void)
2019 static int once
= 1;
2024 if (nvram_get_int("telnetd_eas")) start_telnetd();
2025 if (nvram_get_int("sshd_eas")) start_sshd();
2043 /* note: starting radvd here might be too early in case of
2044 * DHCPv6 or 6to4 because we won't have received a prefix and
2045 * so it will disable advertisements. To restart them, we have
2046 * to send radvd a SIGHUP, or restart it.
2050 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
2065 void stop_services(void)
2080 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2100 // -----------------------------------------------------------------------------
2102 /* nvram "action_service" is: "service-action[-modifier]"
2103 * action is something like "stop" or "start" or "restart"
2104 * optional modifier is "c" for the "service" command-line command
2106 void exec_service(void)
2108 const int A_START
= 1;
2109 const int A_STOP
= 2;
2110 const int A_RESTART
= 1|2;
2119 strlcpy(buffer
, nvram_safe_get("action_service"), sizeof(buffer
));
2123 act
= strsep(&next
, ",");
2124 service
= strsep(&act
, "-");
2130 strsep(&modifier
, "-");
2132 TRACE_PT("service=%s action=%s modifier=%s\n", service
, act
, modifier
? : "");
2134 if (strcmp(act
, "start") == 0) action
= A_START
;
2135 else if (strcmp(act
, "stop") == 0) action
= A_STOP
;
2136 else if (strcmp(act
, "restart") == 0) action
= A_RESTART
;
2138 user
= (modifier
!= NULL
&& *modifier
== 'c');
2140 if (strcmp(service
, "dhcpc") == 0) {
2141 if (action
& A_STOP
) stop_dhcpc();
2142 if (action
& A_START
) start_dhcpc();
2146 if ((strcmp(service
, "dhcpd") == 0) || (strcmp(service
, "dns") == 0) || (strcmp(service
, "dnsmasq") == 0)) {
2147 if (action
& A_STOP
) stop_dnsmasq();
2148 if (action
& A_START
) {
2155 if (strcmp(service
, "firewall") == 0) {
2156 if (action
& A_STOP
) {
2160 if (action
& A_START
) {
2167 if (strcmp(service
, "restrict") == 0) {
2168 if (action
& A_STOP
) {
2171 if (action
& A_START
) {
2172 i
= nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
2176 // if radio was disabled by access restriction, but no rule is handling it now, enable it
2178 if (nvram_get_int("rrules_radio") < 0) {
2179 eval("radio", "on");
2186 if (strcmp(service
, "arpbind") == 0) {
2187 if (action
& A_STOP
) stop_arpbind();
2188 if (action
& A_START
) start_arpbind();
2192 if (strcmp(service
, "qos") == 0) {
2193 if (action
& A_STOP
) {
2196 stop_firewall(); start_firewall(); // always restarted
2197 if (action
& A_START
) {
2199 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
2204 if (strcmp(service
, "qoslimit") == 0) {
2205 if (action
& A_STOP
) {
2206 new_qoslimit_stop();
2208 stop_firewall(); start_firewall(); // always restarted
2209 if (action
& A_START
) {
2210 new_qoslimit_start();
2215 if (strcmp(service
, "upnp") == 0) {
2216 if (action
& A_STOP
) {
2219 stop_firewall(); start_firewall(); // always restarted
2220 if (action
& A_START
) {
2226 if (strcmp(service
, "telnetd") == 0) {
2227 if (action
& A_STOP
) stop_telnetd();
2228 if (action
& A_START
) start_telnetd();
2232 if (strcmp(service
, "sshd") == 0) {
2233 if (action
& A_STOP
) stop_sshd();
2234 if (action
& A_START
) start_sshd();
2238 if (strcmp(service
, "httpd") == 0) {
2239 if (action
& A_STOP
) stop_httpd();
2240 if (action
& A_START
) start_httpd();
2245 if (strcmp(service
, "ipv6") == 0) {
2246 if (action
& A_STOP
) {
2250 if (action
& A_START
) {
2257 if (strcmp(service
, "radvd") == 0) {
2258 if (action
& A_STOP
) {
2261 if (action
& A_START
) {
2267 if (strncmp(service
, "dhcp6", 5) == 0) {
2268 if (action
& A_STOP
) {
2271 if (action
& A_START
) {
2278 if (strcmp(service
, "admin") == 0) {
2279 if (action
& A_STOP
) {
2284 stop_firewall(); start_firewall(); // always restarted
2285 if (action
& A_START
) {
2288 if (nvram_match("telnetd_eas", "1")) start_telnetd();
2289 if (nvram_match("sshd_eas", "1")) start_sshd();
2294 if (strcmp(service
, "ddns") == 0) {
2295 if (action
& A_STOP
) stop_ddns();
2296 if (action
& A_START
) start_ddns();
2300 if (strcmp(service
, "ntpc") == 0) {
2301 if (action
& A_STOP
) stop_ntpc();
2302 if (action
& A_START
) start_ntpc();
2306 if (strcmp(service
, "logging") == 0) {
2307 if (action
& A_STOP
) {
2310 if (action
& A_START
) {
2314 // always restarted except from "service" command
2315 stop_cron(); start_cron();
2316 stop_firewall(); start_firewall();
2321 if (strcmp(service
, "crond") == 0) {
2322 if (action
& A_STOP
) {
2325 if (action
& A_START
) {
2332 if (strncmp(service
, "hotplug", 7) == 0) {
2333 if (action
& A_STOP
) {
2336 if (action
& A_START
) {
2343 if (strcmp(service
, "upgrade") == 0) {
2344 if (action
& A_START
) {
2349 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
2357 killall("rstats", SIGTERM
);
2358 killall("cstats", SIGTERM
);
2359 killall("buttons", SIGTERM
);
2361 remove_storage_main(1); // !!TB - USB Support
2362 stop_usb(); // !!TB - USB Support
2368 if (strcmp(service
, "cifs") == 0) {
2369 if (action
& A_STOP
) stop_cifs();
2370 if (action
& A_START
) start_cifs();
2375 #ifdef TCONFIG_JFFS2
2376 if (strncmp(service
, "jffs", 4) == 0) {
2377 if (action
& A_STOP
) stop_jffs2();
2378 if (action
& A_START
) start_jffs2();
2383 if (strcmp(service
, "zebra") == 0) {
2384 if (action
& A_STOP
) stop_zebra();
2385 if (action
& A_START
) start_zebra();
2390 if (strcmp(service
, "mmc") == 0) {
2391 if (action
& A_STOP
) stop_mmc();
2392 if (action
& A_START
) start_mmc();
2397 if (strcmp(service
, "routing") == 0) {
2398 if (action
& A_STOP
) {
2400 do_static_routes(0); // remove old '_saved'
2401 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
2402 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2403 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), "0");
2404 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2405 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), "0");
2406 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2407 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), "0");
2411 if (action
& A_START
) {
2412 do_static_routes(1); // add new
2414 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
2415 if(strcmp(nvram_safe_get("lan1_ifname"),"")!=0)
2416 eval("brctl", "stp", nvram_safe_get("lan1_ifname"), nvram_safe_get("lan1_stp"));
2417 if(strcmp(nvram_safe_get("lan2_ifname"),"")!=0)
2418 eval("brctl", "stp", nvram_safe_get("lan2_ifname"), nvram_safe_get("lan2_stp"));
2419 if(strcmp(nvram_safe_get("lan3_ifname"),"")!=0)
2420 eval("brctl", "stp", nvram_safe_get("lan3_ifname"), nvram_safe_get("lan3_stp"));
2425 if (strcmp(service
, "ctnf") == 0) {
2426 if (action
& A_START
) {
2434 if (strcmp(service
, "wan") == 0) {
2435 if (action
& A_STOP
) {
2439 if (action
& A_START
) {
2440 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
2448 if (strcmp(service
, "net") == 0) {
2449 if (action
& A_STOP
) {
2451 stop_nas_services();
2464 if (action
& A_START
) {
2477 start_nas_services();
2483 if (strcmp(service
, "nas") == 0) {
2484 if (action
& A_STOP
) {
2487 if (action
& A_START
) {
2494 if (strcmp(service
, "rstats") == 0) {
2495 if (action
& A_STOP
) stop_rstats();
2496 if (action
& A_START
) start_rstats(0);
2500 if (strcmp(service
, "rstatsnew") == 0) {
2501 if (action
& A_STOP
) stop_rstats();
2502 if (action
& A_START
) start_rstats(1);
2506 if (strcmp(service
, "cstats") == 0) {
2507 if (action
& A_STOP
) stop_cstats();
2508 if (action
& A_START
) start_cstats(0);
2512 if (strcmp(service
, "cstatsnew") == 0) {
2513 if (action
& A_STOP
) stop_cstats();
2514 if (action
& A_START
) start_cstats(1);
2518 if (strcmp(service
, "sched") == 0) {
2519 if (action
& A_STOP
) stop_sched();
2520 if (action
& A_START
) start_sched();
2525 if (strcmp(service
, "bittorrent") == 0) {
2526 if (action
& A_STOP
) {
2529 stop_firewall(); start_firewall(); // always restarted
2530 if (action
& A_START
) {
2538 if (strcmp(service
, "nfs") == 0) {
2539 if (action
& A_STOP
) stop_nfs();
2540 if (action
& A_START
) start_nfs();
2546 if (strcmp(service
, "snmp") == 0) {
2547 if (action
& A_STOP
) stop_snmp();
2548 if (action
& A_START
) start_snmp();
2554 if (strcmp(service
, "ups") == 0) {
2555 if (action
& A_STOP
) stop_ups();
2556 if (action
& A_START
) start_ups();
2562 // !!TB - USB Support
2563 if (strcmp(service
, "usb") == 0) {
2564 if (action
& A_STOP
) stop_usb();
2565 if (action
& A_START
) {
2567 // restart Samba and ftp since they may be killed by stop_usb()
2568 restart_nas_services(0, 1);
2569 // remount all partitions by simulating hotplug event
2570 add_remove_usbhost("-1", 1);
2575 if (strcmp(service
, "usbapps") == 0) {
2576 if (action
& A_STOP
) stop_nas_services();
2577 if (action
& A_START
) start_nas_services();
2583 // !!TB - FTP Server
2584 if (strcmp(service
, "ftpd") == 0) {
2585 if (action
& A_STOP
) stop_ftpd();
2589 if (action
& A_START
) start_ftpd();
2594 #ifdef TCONFIG_MEDIA_SERVER
2595 if (strcmp(service
, "media") == 0 || strcmp(service
, "dlna") == 0) {
2596 if (action
& A_STOP
) stop_media_server();
2597 if (action
& A_START
) start_media_server();
2602 #ifdef TCONFIG_SAMBASRV
2604 if (strcmp(service
, "samba") == 0 || strcmp(service
, "smbd") == 0) {
2605 if (action
& A_STOP
) stop_samba();
2606 if (action
& A_START
) {
2616 #ifdef TCONFIG_OPENVPN
2617 if (strncmp(service
, "vpnclient", 9) == 0) {
2618 if (action
& A_STOP
) stop_vpnclient(atoi(&service
[9]));
2619 if (action
& A_START
) start_vpnclient(atoi(&service
[9]));
2623 if (strncmp(service
, "vpnserver", 9) == 0) {
2624 if (action
& A_STOP
) stop_vpnserver(atoi(&service
[9]));
2625 if (action
& A_START
) start_vpnserver(atoi(&service
[9]));
2630 #ifdef TCONFIG_NOCAT
2631 if (strcmp(service
, "splashd") == 0) {
2632 if (action
& A_STOP
) stop_splashd();
2633 if (action
& A_START
) start_splashd();
2641 // some functions check action_service and must be cleared at end -- zzz
2642 nvram_set("action_service", "");
2644 // Force recheck in 500 msec
2645 setitimer(ITIMER_REAL
, &pop_tv
, NULL
);
2648 static void do_service(const char *name
, const char *action
, int user
)
2654 while (!nvram_match("action_service", "")) {
2659 else if (--n
< 0) break;
2663 snprintf(s
, sizeof(s
), "%s-%s%s", name
, action
, (user
? "-c" : ""));
2664 nvram_set("action_service", s
);
2666 if (nvram_match("debug_rc_svc", "1")) {
2667 nvram_unset("debug_rc_svc");
2674 while (nvram_match("action_service", s
)) {
2686 int service_main(int argc
, char *argv
[])
2688 if (argc
!= 3) usage_exit(argv
[0], "<service> <action>");
2689 do_service(argv
[1], argv
[2], 1);
2690 printf("\nDone.\n");
2694 void start_service(const char *name
)
2696 do_service(name
, "start", 0);
2699 void stop_service(const char *name
)
2701 do_service(name
, "stop", 0);
2705 void restart_service(const char *name)
2707 do_service(name, "restart", 0);