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 #define IFUP (IFF_UP | IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST)
49 #define sin_addr(s) (((struct sockaddr_in *)(s))->sin_addr)
51 // Pop an alarm to recheck pids in 500 msec.
52 static const struct itimerval pop_tv
= { {0,0}, {0, 500 * 1000} };
54 // Pop an alarm to reap zombies.
55 static const struct itimerval zombie_tv
= { {0,0}, {307, 0} };
57 // -----------------------------------------------------------------------------
59 static const char dmhosts
[] = "/etc/hosts.dnsmasq";
60 static const char dmresolv
[] = "/etc/resolv.dnsmasq";
62 static pid_t pid_dnsmasq
= -1;
64 static int is_wet(int idx
, int unit
, int subunit
, void *param
)
66 return nvram_match(wl_nvname("mode", unit
, subunit
), "wet");
75 const char *router_ip
;
76 const char *lan_ifname
;
80 char *mac
, *ip
, *name
;
94 start_service("dnsmasq");
100 if (foreach_wif(1, NULL
, is_wet
)) return;
102 if ((f
= fopen("/etc/dnsmasq.conf", "w")) == NULL
) return;
104 lan_ifname
= nvram_safe_get("lan_ifname");
105 router_ip
= nvram_safe_get("lan_ipaddr");
106 strlcpy(lan
, router_ip
, sizeof(lan
));
107 if ((p
= strrchr(lan
, '.')) != NULL
) *(p
+ 1) = 0;
110 "pid-file=/var/run/dnsmasq.pid\n"
113 if (((nv
= nvram_get("wan_domain")) != NULL
) || ((nv
= nvram_get("wan_get_domain")) != NULL
)) {
114 if (*nv
) fprintf(f
, "domain=%s\n", nv
);
118 const dns_list_t
*dns
= get_dns(); // this always points to a static buffer
120 if (((nv
= nvram_get("dns_minport")) != NULL
) && (*nv
)) n
= atoi(nv
);
123 "resolv-file=%s\n" // the real stuff is here
124 "addn-hosts=%s\n" // "
125 "expand-hosts\n" // expand hostnames in hosts file
126 "min-port=%u\n", // min port used for random src port
127 dmresolv
, dmhosts
, n
);
128 do_dns
= nvram_match("dhcpd_dmdns", "1");
130 // DNS rebinding protection, will discard upstream RFC1918 responses
131 if (nvram_get_int("dns_norebind")) {
134 "rebind-localhost-ok\n");
135 // allow RFC1918 responses for server domain
136 switch (get_wan_proto()) {
138 nv
= nvram_get("pptp_server_ip");
141 nv
= nvram_get("l2tp_server_ip");
147 if (nv
&& *nv
) fprintf(f
, "rebind-domain-ok=%s\n", nv
);
150 for (n
= 0 ; n
< dns
->count
; ++n
) {
151 if (dns
->dns
[n
].port
!= 53) {
152 fprintf(f
, "server=%s#%u\n", inet_ntoa(dns
->dns
[n
].addr
), dns
->dns
[n
].port
);
158 do_dhcpd
= nvram_match("lan_proto", "dhcp");
160 dhcp_lease
= nvram_get_int("dhcp_lease");
161 if (dhcp_lease
<= 0) dhcp_lease
= 1440;
163 if ((e
= nvram_get("dhcpd_slt")) != NULL
) n
= atoi(e
); else n
= 0;
164 if (n
< 0) strcpy(sdhcp_lease
, "infinite");
165 else sprintf(sdhcp_lease
, "%dm", (n
> 0) ? n
: dhcp_lease
);
168 // if not using dnsmasq for dns
170 if ((dns
->count
== 0) && (nvram_get_int("dhcpd_llndns"))) {
171 // no DNS might be temporary. use a low lease time to force clients to update.
173 strcpy(sdhcp_lease
, "2m");
177 // pass the dns directly
179 for (n
= 0 ; n
< dns
->count
; ++n
) {
180 if (dns
->dns
[n
].port
== 53) { // check: option 6 doesn't seem to support other ports
181 sprintf(buf
+ strlen(buf
), ",%s", inet_ntoa(dns
->dns
[n
].addr
));
184 fprintf(f
, "dhcp-option=6%s\n", buf
);
188 if ((p
= nvram_get("dhcpd_startip")) && (*p
) && (e
= nvram_get("dhcpd_endip")) && (*e
)) {
189 fprintf(f
, "dhcp-range=%s,%s,%s,%dm\n", p
, e
, nvram_safe_get("lan_netmask"), dhcp_lease
);
193 dhcp_start
= nvram_get_int("dhcp_start");
194 dhcp_count
= nvram_get_int("dhcp_num");
195 fprintf(f
, "dhcp-range=%s%d,%s%d,%s,%dm\n",
196 lan
, dhcp_start
, lan
, dhcp_start
+ dhcp_count
- 1, nvram_safe_get("lan_netmask"), dhcp_lease
);
200 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED
)) {
201 p
= nvram_safe_get("lan_gateway");
202 if ((*p
) && (strcmp(p
, "0.0.0.0") != 0)) nv
= p
;
205 n
= nvram_get_int("dhcpd_lmax");
207 "dhcp-option=3,%s\n" // gateway
208 "dhcp-lease-max=%d\n",
212 if (nvram_get_int("dhcpd_auth") >= 0) {
213 fprintf(f
, "dhcp-authoritative\n");
216 if (((nv
= nvram_get("wan_wins")) != NULL
) && (*nv
) && (strcmp(nv
, "0.0.0.0") != 0)) {
217 fprintf(f
, "dhcp-option=44,%s\n", nv
);
219 #ifdef TCONFIG_SAMBASRV
220 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
221 if ((nv
== NULL
) || (*nv
== 0) || (strcmp(nv
, "0.0.0.0") == 0)) {
222 // Samba will serve as a WINS server
223 fprintf(f
, "dhcp-option=44,0.0.0.0\n");
229 fprintf(f
, "no-dhcp-interface=%s\n", lan_ifname
);
232 // write static lease entries & create hosts file
234 if ((hf
= fopen(dmhosts
, "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
);
243 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
244 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
245 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 106 w/ delim
246 p
= nvram_safe_get("dhcpd_static");
247 while ((e
= strchr(p
, '>')) != NULL
) {
258 if ((e
= strchr(buf
, '<')) == NULL
) continue;
263 if ((e
= strchr(ip
, '<')) == NULL
) continue;
265 if (strchr(ip
, '.') == NULL
) {
267 if ((ipn
<= 0) || (ipn
> 255)) continue;
268 sprintf(ipbuf
, "%s%d", lan
, ipn
);
272 if (inet_addr(ip
) == INADDR_NONE
) continue;
277 if ((hf
) && (*name
!= 0)) {
278 fprintf(hf
, "%s %s\n", ip
, name
);
281 if ((do_dhcpd
) && (*mac
!= 0) && (strcmp(mac
, "00:00:00:00:00:00") != 0)) {
282 fprintf(f
, "dhcp-host=%s,%s,%s\n", mac
, ip
, sdhcp_lease
);
290 #ifdef TCONFIG_OPENVPN
291 write_vpn_dnsmasq_config(f
);
294 fprintf(f
, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
296 fappend(f
, "/etc/dnsmasq.custom");
303 unlink("/etc/resolv.conf");
304 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
307 TRACE_PT("run dnsmasq\n");
311 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
318 void stop_dnsmasq(void)
323 stop_service("dnsmasq");
329 unlink("/etc/resolv.conf");
330 symlink(dmresolv
, "/etc/resolv.conf");
332 killall_tk("dnsmasq");
337 void clear_resolv(void)
339 f_write(dmresolv
, NULL
, 0, 0, 0); // blank
342 void dns_to_resolv(void)
345 const dns_list_t
*dns
;
349 m
= umask(022); // 077 from pppoecd
350 if ((f
= fopen(dmresolv
, "w")) != NULL
) {
351 // Check for VPN DNS entries
352 if (!write_vpn_resolv(f
)) {
353 dns
= get_dns(); // static buffer
354 if (dns
->count
== 0) {
355 // Put a pseudo DNS IP to trigger Connect On Demand
356 if (nvram_match("ppp_demand", "1")) {
357 switch (get_wan_proto()) {
361 fprintf(f
, "nameserver 1.1.1.1\n");
367 for (i
= 0; i
< dns
->count
; i
++) {
368 if (dns
->dns
[i
].port
== 53) { // resolv.conf doesn't allow for an alternate port
369 fprintf(f
, "nameserver %s\n", inet_ntoa(dns
->dns
[i
].addr
));
379 // -----------------------------------------------------------------------------
381 void start_httpd(void)
384 if (!nvram_match("http_enable", "0")) {
387 if (!nvram_match("https_enable", "0")) {
388 xstart("httpd", "-s");
393 void stop_httpd(void)
398 // -----------------------------------------------------------------------------
400 void start_upnp(void)
402 if (get_wan_proto() == WP_DISABLED
) return;
408 if (((enable
= nvram_get_int("upnp_enable")) & 3) != 0) {
409 mkdir("/etc/upnp", 0777);
410 if (f_exists("/etc/upnp/config.alt")) {
411 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
414 if ((f
= fopen("/etc/upnp/config", "w")) != NULL
) {
415 upnp_port
= nvram_get_int("upnp_port");
416 if ((upnp_port
< 0) || (upnp_port
>= 0xFFFF)) upnp_port
= 0;
418 char *lanip
= nvram_safe_get("lan_ipaddr");
419 char *lanmask
= nvram_safe_get("lan_netmask");
423 "listening_ip=%s/%s\n"
428 "upnp_forward_chain=upnp\n"
429 "upnp_nat_chain=upnp\n"
430 "notify_interval=%d\n"
431 "system_uptime=yes\n"
434 nvram_safe_get("wan_iface"),
437 (enable
& 1) ? "yes" : "no", // upnp enable
438 (enable
& 2) ? "yes" : "no", // natpmp enable
439 nvram_get_int("upnp_secure") ? "yes" : "no", // secure_mode (only forward to self)
440 nvram_get_int("upnp_ssdp_interval")
443 if (nvram_get_int("upnp_clean")) {
444 int interval
= nvram_get_int("upnp_clean_interval");
445 if (interval
< 60) interval
= 60;
447 "clean_ruleset_interval=%d\n"
448 "clean_ruleset_threshold=%d\n",
450 nvram_get_int("upnp_clean_threshold")
454 fprintf(f
,"clean_ruleset_interval=0\n");
456 if (nvram_match("upnp_mnp", "1")) {
457 int https
= nvram_get_int("https_enable");
458 fprintf(f
, "presentation_url=http%s://%s:%s/forward-upnp.asp\n",
459 https
? "s" : "", lanip
,
460 nvram_safe_get(https
? "https_lanport" : "http_lanport"));
463 // Empty parameters are not included into XML service description
464 fprintf(f
, "presentation_url=\n");
468 f_read_string("/proc/sys/kernel/random/uuid", uuid
, sizeof(uuid
));
469 fprintf(f
, "uuid=%s\n", uuid
);
472 if ((ports
[0] = nvram_get_int("upnp_min_port_int")) > 0 &&
473 (ports
[1] = nvram_get_int("upnp_max_port_int")) > 0 &&
474 (ports
[2] = nvram_get_int("upnp_min_port_ext")) > 0 &&
475 (ports
[3] = nvram_get_int("upnp_max_port_ext")) > 0) {
477 "allow %d-%d %s/%s %d-%d\n",
484 // by default allow only redirection of ports above 1024
485 fprintf(f
, "allow 1024-65535 %s/%s 1024-65535\n", lanip
, lanmask
);
488 fappend(f
, "/jffs/upnpconfig.custom");
489 fappend(f
, "/etc/upnp/config.custom");
490 fprintf(f
, "\ndeny 0-65535 0.0.0.0/0 0-65535\n");
493 xstart("miniupnpd", "-f", "/etc/upnp/config");
501 killall_tk("miniupnpd");
504 // -----------------------------------------------------------------------------
506 static pid_t pid_crond
= -1;
508 void start_cron(void)
512 eval("crond", nvram_contains_word("log_events", "crond") ? NULL
: "-l", "9");
513 if (!nvram_contains_word("debug_norestart", "crond")) {
524 // -----------------------------------------------------------------------------
527 static pid_t pid_hotplug2
= -1;
529 void start_hotplug2()
533 f_write_string("/proc/sys/kernel/hotplug", "", FW_NEWLINE
, 0);
534 xstart("hotplug2", "--persistent", "--no-coldplug");
535 // FIXME: Don't remember exactly why I put "sleep" here -
536 // but it was not for a race with check_services()... - TB
539 if (!nvram_contains_word("debug_norestart", "hotplug2")) {
544 void stop_hotplug2(void)
547 killall_tk("hotplug2");
551 // -----------------------------------------------------------------------------
553 // Written by Sparq in 2002/07/16
554 void start_zebra(void)
559 char *lan_tx
= nvram_safe_get("dr_lan_tx");
560 char *lan_rx
= nvram_safe_get("dr_lan_rx");
561 char *wan_tx
= nvram_safe_get("dr_wan_tx");
562 char *wan_rx
= nvram_safe_get("dr_wan_rx");
564 if ((*lan_tx
== '0') && (*lan_rx
== '0') && (*wan_tx
== '0') && (*wan_rx
== '0')) {
569 if ((fp
= fopen("/etc/zebra.conf", "w")) != NULL
) {
574 if ((fp
= fopen("/etc/ripd.conf", "w")) != NULL
) {
575 char *lan_ifname
= nvram_safe_get("lan_ifname");
576 char *wan_ifname
= nvram_safe_get("wan_ifname");
578 fprintf(fp
, "router rip\n");
579 fprintf(fp
, "network %s\n", lan_ifname
);
580 fprintf(fp
, "network %s\n", wan_ifname
);
581 fprintf(fp
, "redistribute connected\n");
582 //fprintf(fp, "redistribute static\n");
584 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
585 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
587 fprintf(fp
, "interface %s\n", lan_ifname
);
588 if (*lan_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", lan_tx
);
589 if (*lan_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", lan_rx
);
591 fprintf(fp
, "interface %s\n", wan_ifname
);
592 if (*wan_tx
!= '0') fprintf(fp
, "ip rip send version %s\n", wan_tx
);
593 if (*wan_rx
!= '0') fprintf(fp
, "ip rip receive version %s\n", wan_rx
);
595 fprintf(fp
, "router rip\n");
596 if (*lan_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", lan_ifname
);
597 if (*lan_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", lan_ifname
);
598 if (*wan_tx
== '0') fprintf(fp
, "distribute-list private out %s\n", wan_ifname
);
599 if (*wan_rx
== '0') fprintf(fp
, "distribute-list private in %s\n", wan_ifname
);
600 fprintf(fp
, "access-list private deny any\n");
602 //fprintf(fp, "debug rip events\n");
603 //fprintf(fp, "log file /etc/ripd.log\n");
607 xstart("zebra", "-d");
608 xstart("ripd", "-d");
612 void stop_zebra(void)
615 killall("zebra", SIGTERM
);
616 killall("ripd", SIGTERM
);
618 unlink("/etc/zebra.conf");
619 unlink("/etc/ripd.conf");
623 // -----------------------------------------------------------------------------
625 void start_syslog(void)
635 char *rot_siz
= "50";
640 if (nvram_match("log_remote", "1")) {
641 nv
= nvram_safe_get("log_remoteip");
643 snprintf(rem
, sizeof(rem
), "%s:%s", nv
, nvram_safe_get("log_remoteport"));
649 if (nvram_match("log_file", "1")) {
652 /* Read options: rotate_size(kb) num_backups logfilename.
653 * Ignore these settings and use defaults if the logfile cannot be written to.
655 if (f_read_string("/etc/syslogd.cfg", cfg
, sizeof(cfg
)) > 0) {
656 if ((nv
= strchr(cfg
, '\n')))
659 if ((nv
= strtok(cfg
, " \t"))) {
664 if ((nv
= strtok(NULL
, " \t")))
667 if ((nv
= strtok(NULL
, " \t")) && *nv
== '/') {
668 if (f_write(nv
, cfg
, 0, FW_APPEND
, 0) >= 0) {
680 argv
[argc
++] = rot_siz
;
682 if (isdigit(*b_opt
)) {
684 argv
[argc
++] = b_opt
;
690 _eval(argv
, NULL
, 0, NULL
);
694 _eval(argv
, NULL
, 0, NULL
);
696 // used to be available in syslogd -m
697 n
= nvram_get_int("log_mark");
701 sprintf(rem
, "*/%d * * * *", n
);
702 else if (n
< 60 * 24)
703 sprintf(rem
, "0 */%d * * *", n
/ 60);
705 sprintf(rem
, "0 0 */%d * *", n
/ (60 * 24));
706 sprintf(s
, "cru a syslogdmark \"%s logger -p syslog.info -- -- MARK --\"", rem
);
710 system("cru d syslogdmark");
715 void stop_syslog(void)
717 killall("klogd", SIGTERM
);
718 killall("syslogd", SIGTERM
);
721 // -----------------------------------------------------------------------------
723 static pid_t pid_igmp
= -1;
725 void start_igmp_proxy(void)
731 if (nvram_match("multicast_pass", "1")) {
732 switch (get_wan_proto()) {
745 if (f_exists("/etc/igmp.alt")) {
746 eval("igmpproxy", "/etc/igmp.alt");
748 else if ((fp
= fopen("/etc/igmp.conf", "w")) != NULL
) {
751 "phyint %s upstream\n"
753 "phyint %s downstream ratelimit 0\n",
755 nvram_get("multicast_altnet") ? : "0.0.0.0/0",
756 nvram_safe_get("lan_ifname"));
758 eval("igmpproxy", "/etc/igmp.conf");
763 if (!nvram_contains_word("debug_norestart", "igmprt")) {
769 void stop_igmp_proxy(void)
772 killall_tk("igmpproxy");
776 // -----------------------------------------------------------------------------
780 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE
|FW_NEWLINE
, 0644);
783 void start_ntpc(void)
789 if (nvram_get_int("ntp_updates") >= 0) {
790 xstart("ntpsync", "--init");
796 killall("ntpsync", SIGTERM
);
799 // -----------------------------------------------------------------------------
801 static void stop_rstats(void)
807 while ((n
-- > 0) && ((pid
= pidof("rstats")) > 0)) {
808 if (kill(pid
, SIGTERM
) != 0) break;
813 static void start_rstats(int new)
815 if (nvram_match("rstats_enable", "1")) {
817 if (new) xstart("rstats", "--new");
818 else xstart("rstats");
822 // -----------------------------------------------------------------------------
827 static char *get_full_storage_path(char *val
)
829 static char buf
[128];
833 len
= sprintf(buf
, "%s", val
);
835 len
= sprintf(buf
, "%s/%s", MOUNT_ROOT
, val
);
837 if (len
> 1 && buf
[len
- 1] == '/')
843 static char *nvram_storage_path(char *var
)
845 char *val
= nvram_safe_get(var
);
846 return get_full_storage_path(val
);
849 char vsftpd_conf
[] = "/etc/vsftpd.conf";
850 char vsftpd_users
[] = "/etc/vsftpd.users";
851 char vsftpd_passwd
[] = "/etc/vsftpd.passwd";
853 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
855 static void start_ftpd(void)
861 char *user
, *pass
, *rights
;
864 start_service("ftpd");
868 if (!nvram_get_int("ftp_enable")) return;
870 mkdir_if_none(vsftpd_users
);
871 mkdir_if_none("/var/run/vsftpd");
873 if ((fp
= fopen(vsftpd_conf
, "w")) == NULL
)
876 if (nvram_get_int("ftp_super"))
879 sprintf(tmp
, "%s/%s", vsftpd_users
, "admin");
880 if ((f
= fopen(tmp
, "w")))
883 "dirlist_enable=yes\n"
885 "download_enable=yes\n");
890 #ifdef TCONFIG_SAMBASRV
891 if (nvram_match("smbd_cset", "utf8"))
892 fprintf(fp
, "utf8=yes\n");
895 if (nvram_invmatch("ftp_anonymous", "0"))
898 "anon_allow_writable_root=yes\n"
899 "anon_world_readable_only=no\n"
903 sprintf(tmp
, "%s/ftp", vsftpd_users
);
904 if ((f
= fopen(tmp
, "w")))
906 if (nvram_match("ftp_dirlist", "0"))
907 fprintf(f
, "dirlist_enable=yes\n");
908 if (nvram_match("ftp_anonymous", "1") ||
909 nvram_match("ftp_anonymous", "3"))
910 fprintf(f
, "write_enable=yes\n");
911 if (nvram_match("ftp_anonymous", "1") ||
912 nvram_match("ftp_anonymous", "2"))
913 fprintf(f
, "download_enable=yes\n");
916 if (nvram_match("ftp_anonymous", "1") ||
917 nvram_match("ftp_anonymous", "3"))
919 "anon_upload_enable=yes\n"
920 "anon_mkdir_write_enable=yes\n"
921 "anon_other_write_enable=yes\n");
923 fprintf(fp
, "anonymous_enable=no\n");
927 "dirmessage_enable=yes\n"
928 "download_enable=no\n"
929 "dirlist_enable=no\n"
931 "syslog_enable=yes\n"
935 "chroot_local_user=yes\n"
937 "log_ftp_protocol=%s\n"
938 "user_config_dir=%s\n"
946 "idle_session_timeout=%s\n"
949 "local_max_rate=%d\n"
951 nvram_get_int("log_ftp") ? "yes" : "no",
952 vsftpd_users
, vsftpd_passwd
,
953 nvram_get("ftp_port") ? : "21",
954 nvram_get_int("ftp_max"),
955 nvram_get_int("ftp_ipmax"),
956 nvram_get("ftp_staytimeout") ? : "300",
957 nvram_get_int("ftp_anonrate") * 1024,
958 nvram_get_int("ftp_rate") * 1024,
959 nvram_safe_get("ftp_custom"));
963 /* prepare passwd file and default users */
964 if ((fp
= fopen(vsftpd_passwd
, "w")) == NULL
)
967 if (((user
= nvram_get("http_username")) == NULL
) || (*user
== 0)) user
= "admin";
968 if (((pass
= nvram_get("http_passwd")) == NULL
) || (*pass
== 0)) pass
= "admin";
970 fprintf(fp
, /* anonymous, admin, nobody */
971 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
972 "%s:%s:0:0:root:/:/sbin/nologin\n"
973 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
974 nvram_storage_path("ftp_anonroot"), user
,
975 nvram_get_int("ftp_super") ? crypt(pass
, "$1$") : "x",
978 if ((buf
= strdup(nvram_safe_get("ftp_users"))) != NULL
)
981 username<password<rights
989 while ((q
= strsep(&p
, ">")) != NULL
) {
990 if (vstrsep(q
, "<", &user
, &pass
, &rights
) != 3) continue;
991 if (!user
|| !pass
) continue;
994 if (strncmp(rights
, "Private", 7) == 0)
996 sprintf(tmp
, "%s/%s", nvram_storage_path("ftp_pvtroot"), user
);
1000 sprintf(tmp
, "%s", nvram_storage_path("ftp_pubroot"));
1002 fprintf(fp
, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
1003 user
, crypt(pass
, "$1$"), user
, tmp
);
1006 sprintf(tmp
, "%s/%s", vsftpd_users
, user
);
1007 if ((f
= fopen(tmp
, "w")))
1010 if (nvram_invmatch("ftp_dirlist", "1"))
1011 strcat(tmp
, "dirlist_enable=yes\n");
1012 if (strstr(rights
, "Read") || !strcmp(rights
, "Private"))
1013 strcat(tmp
, "download_enable=yes\n");
1014 if (strstr(rights
, "Write") || !strncmp(rights
, "Private", 7))
1015 strcat(tmp
, "write_enable=yes\n");
1025 killall("vsftpd", SIGHUP
);
1027 /* start vsftpd if it's not already running */
1028 if (pidof("vsftpd") <= 0)
1032 static void stop_ftpd(void)
1034 if (getpid() != 1) {
1035 stop_service("ftpd");
1039 killall_tk("vsftpd");
1040 unlink(vsftpd_passwd
);
1041 unlink(vsftpd_conf
);
1042 eval("rm", "-rf", vsftpd_users
);
1044 #endif // TCONFIG_FTP
1046 // -----------------------------------------------------------------------------
1050 #ifdef TCONFIG_SAMBASRV
1051 static void kill_samba(int sig
)
1053 if (sig
== SIGTERM
) {
1058 killall("smbd", sig
);
1059 killall("nmbd", sig
);
1063 static void start_samba(void)
1072 if (getpid() != 1) {
1073 start_service("smbd");
1077 mode
= nvram_get_int("smbd_enable");
1078 if (!mode
|| !nvram_invmatch("lan_hostname", ""))
1081 if ((fp
= fopen("/etc/smb.conf", "w")) == NULL
)
1084 fprintf(fp
, "[global]\n"
1085 " interfaces = %s\n"
1086 " bind interfaces only = yes\n"
1088 " netbios name = %s\n"
1089 " server string = %s\n"
1090 " guest account = nobody\n"
1091 " security = user\n"
1094 " guest only = no\n"
1095 " browseable = yes\n"
1096 " syslog only = yes\n"
1097 " timestamp logs = no\n"
1099 " encrypt passwords = yes\n"
1100 #if defined(LINUX26) && defined(TCONFIG_SAMBA3)
1101 " use sendfile = yes\n"
1103 " preserve case = yes\n"
1104 " short preserve case = yes\n",
1105 nvram_safe_get("lan_ifname"),
1106 nvram_get("smbd_wgroup") ? : "WORKGROUP",
1107 nvram_safe_get("lan_hostname"),
1108 nvram_get("router_name") ? : "Tomato",
1109 mode
== 2 ? "" : "map to guest = Bad User",
1110 mode
== 2 ? "no" : "yes" // guest ok
1113 if (nvram_get_int("smbd_wins")) {
1114 nv
= nvram_safe_get("wan_wins");
1115 if ((*nv
== 0) || (strcmp(nv
, "0.0.0.0") == 0)) {
1116 fprintf(fp
, " wins support = yes\n");
1120 if (nvram_get_int("smbd_master")) {
1122 " domain master = yes\n"
1123 " local master = yes\n"
1124 " preferred master = yes\n"
1125 " os level = 65\n");
1128 nv
= nvram_safe_get("smbd_cpage");
1130 #ifndef TCONFIG_SAMBA3
1131 fprintf(fp
, " client code page = %s\n", nv
);
1133 sprintf(nlsmod
, "nls_cp%s", nv
);
1135 nv
= nvram_safe_get("smbd_nlsmod");
1136 if ((*nv
) && (strcmp(nv
, nlsmod
) != 0))
1140 nvram_set("smbd_nlsmod", nlsmod
);
1143 #ifndef TCONFIG_SAMBA3
1144 if (nvram_match("smbd_cset", "utf8"))
1145 fprintf(fp
, " coding system = utf8\n");
1146 else if (nvram_invmatch("smbd_cset", ""))
1147 fprintf(fp
, " character set = %s\n", nvram_safe_get("smbd_cset"));
1150 nv
= nvram_safe_get("smbd_custom");
1151 /* add socket options unless overriden by the user */
1152 if (strstr(nv
, "socket options") == NULL
) {
1153 fprintf(fp
, " socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=16384 SO_SNDBUF=16384\n");
1155 fprintf(fp
, "%s\n\n", nv
);
1157 /* configure shares */
1161 char *name
, *path
, *comment
, *writeable
, *hidden
;
1164 if ((buf
= strdup(nvram_safe_get("smbd_shares"))) != NULL
)
1166 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1169 while ((q
= strsep(&p
, ">")) != NULL
) {
1170 if (vstrsep(q
, "<", &name
, &path
, &comment
, &writeable
, &hidden
) != 5) continue;
1171 if (!path
|| !name
) continue;
1174 fprintf(fp
, "\n[%s]\n", name
);
1177 fprintf(fp
, " path = %s\n", path
);
1180 if (!strcmp(writeable
, "1"))
1181 fprintf(fp
, " writable = yes\n delete readonly = yes\n force user = root\n");
1182 if (!strcmp(hidden
, "1"))
1183 fprintf(fp
, " browseable = no\n");
1187 fprintf(fp
, " comment = %s\n", comment
);
1194 /* Share every mountpoint below MOUNT_ROOT */
1195 if (nvram_get_int("smbd_autoshare") && (dir
= opendir(MOUNT_ROOT
))) {
1196 while ((dp
= readdir(dir
))) {
1197 if (strcmp(dp
->d_name
, ".") && strcmp(dp
->d_name
, "..")) {
1203 /* Only if is a directory and is mounted */
1204 sprintf(path
, "%s/%s", MOUNT_ROOT
, dp
->d_name
);
1205 sb
.st_mode
= S_IFDIR
; /* failsafe */
1207 if (!S_ISDIR(sb
.st_mode
))
1210 /* If this dir & its parent dir are on the same device, it is not a mountpoint */
1213 thisdev
= sb
.st_dev
;
1215 ++sb
.st_dev
; /* failsafe */
1217 if (thisdev
== sb
.st_dev
)
1220 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1221 fprintf(fp
, "\n[%s]\n path = %s/%s\n comment = %s\n",
1222 dp
->d_name
, MOUNT_ROOT
, dp
->d_name
, dp
->d_name
);
1223 if (nvram_match("smbd_autoshare", "3")) // Hidden
1224 fprintf(fp
, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1225 dp
->d_name
, MOUNT_ROOT
, dp
->d_name
);
1226 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1227 fprintf(fp
, " writable = yes\n delete readonly = yes\n force user = root\n");
1233 if (dir
) closedir(dir
);
1236 /* by default share MOUNT_ROOT as read-only */
1237 fprintf(fp
, "\n[share]\n"
1245 mkdir_if_none("/var/run/samba");
1246 mkdir_if_none("/etc/samba");
1248 /* write smbpasswd */
1249 #ifdef TCONFIG_SAMBA3
1250 eval("smbpasswd", "nobody", "\"\"");
1252 eval("smbpasswd", "-a", "nobody", "\"\"");
1256 if (((smbd_user
= nvram_get("smbd_user")) == NULL
) || (*smbd_user
== 0) || !strcmp(smbd_user
, "root"))
1258 #ifdef TCONFIG_SAMBA3
1259 eval("smbpasswd", smbd_user
, nvram_safe_get("smbd_passwd"));
1261 eval("smbpasswd", "-a", smbd_user
, nvram_safe_get("smbd_passwd"));
1266 int ret1
= 0, ret2
= 0;
1267 /* start samba if it's not already running */
1268 if (pidof("nmbd") <= 0)
1269 ret1
= xstart("nmbd", "-D");
1270 if (pidof("smbd") <= 0)
1271 ret2
= xstart("smbd", "-D");
1273 if (ret1
|| ret2
) kill_samba(SIGTERM
);
1276 static void stop_samba(void)
1278 if (getpid() != 1) {
1279 stop_service("smbd");
1283 kill_samba(SIGTERM
);
1285 unlink("/var/log/smb");
1286 unlink("/var/log/nmb");
1287 eval("rm", "-rf", "/var/run/samba");
1289 #endif // TCONFIG_SAMBASRV
1291 #ifdef TCONFIG_MEDIA_SERVER
1292 #define MEDIA_SERVER_APP "minidlna"
1294 static void start_media_server(void)
1297 int port
, pid
, https
;
1299 char *argv
[] = { MEDIA_SERVER_APP
, "-f", "/etc/"MEDIA_SERVER_APP
".conf", "-R", NULL
};
1300 static int once
= 1;
1302 if (getpid() != 1) {
1303 start_service("media");
1307 if (nvram_get_int("ms_sas") == 0)
1310 if (nvram_get_int("ms_enable") != 0) {
1311 if ((!once
) && (nvram_get_int("ms_rescan") == 0)) {
1315 nvram_unset("ms_rescan");
1317 if (f_exists("/etc/"MEDIA_SERVER_APP
".alt")) {
1318 argv
[2] = "/etc/"MEDIA_SERVER_APP
".alt";
1321 if ((f
= fopen(argv
[2], "w")) != NULL
) {
1322 port
= nvram_get_int("ms_port");
1323 https
= nvram_get_int("https_enable");
1324 dbdir
= nvram_safe_get("ms_dbdir");
1325 if (!(*dbdir
)) dbdir
= NULL
;
1326 mkdir_if_none(dbdir
? : "/var/run/"MEDIA_SERVER_APP
);
1329 "network_interface=%s\n"
1331 "friendly_name=%s\n"
1335 "presentation_url=http%s://%s:%s/nas-media.asp\n"
1337 "notify_interval=600\n"
1338 "album_art_names=Cover.jpg/cover.jpg/Thumb.jpg/thumb.jpg\n"
1340 nvram_safe_get("lan_ifname"),
1341 (port
< 0) || (port
>= 0xffff) ? 0 : port
,
1342 nvram_get("router_name") ? : "Tomato",
1343 dbdir
? : "/var/run/"MEDIA_SERVER_APP
,
1344 nvram_get_int("ms_tivo") ? "yes" : "no",
1345 nvram_get_int("ms_stdlna") ? "yes" : "no",
1346 https
? "s" : "", nvram_safe_get("lan_ipaddr"), nvram_safe_get(https
? "https_lanport" : "http_lanport")
1349 // media directories
1351 char *path
, *restrict
;
1353 if ((buf
= strdup(nvram_safe_get("ms_dirs"))) != NULL
) {
1354 /* path<restrict[A|V|P|] */
1357 while ((q
= strsep(&p
, ">")) != NULL
) {
1358 if (vstrsep(q
, "<", &path
, &restrict
) < 1 || !path
|| !(*path
))
1360 fprintf(f
, "media_dir=%s%s%s\n",
1361 restrict
? : "", (restrict
&& *restrict
) ? "," : "", path
);
1370 /* start media server if it's not already running */
1371 if (pidof(MEDIA_SERVER_APP
) <= 0) {
1372 if ((_eval(argv
, NULL
, 0, &pid
) == 0) && (once
)) {
1373 /* If we started the media server successfully, wait 1 sec
1374 * to let it die if it can't open the database file.
1375 * If it's still alive after that, assume it's running and
1376 * disable forced once-after-reboot rescan.
1379 if (pidof(MEDIA_SERVER_APP
) > 0)
1386 static void stop_media_server(void)
1388 if (getpid() != 1) {
1389 stop_service("media");
1393 killall_tk(MEDIA_SERVER_APP
);
1395 #endif // TCONFIG_MEDIA_SERVER
1398 static void start_nas_services(void)
1400 if (getpid() != 1) {
1401 start_service("usbapps");
1405 #ifdef TCONFIG_SAMBASRV
1411 #ifdef TCONFIG_MEDIA_SERVER
1412 start_media_server();
1416 static void stop_nas_services(void)
1418 if (getpid() != 1) {
1419 stop_service("usbapps");
1423 #ifdef TCONFIG_MEDIA_SERVER
1424 stop_media_server();
1429 #ifdef TCONFIG_SAMBASRV
1434 void restart_nas_services(int stop
, int start
)
1436 int fd
= file_lock("usb");
1437 /* restart all NAS applications */
1439 stop_nas_services();
1441 start_nas_services();
1444 #endif // TCONFIG_USB
1446 // -----------------------------------------------------------------------------
1448 /* -1 = Don't check for this program, it is not expected to be running.
1449 * Other = This program has been started and should be kept running. If no
1450 * process with the name is running, call func to restart it.
1451 * Note: At startup, dnsmasq forks a short-lived child which forks a
1452 * long-lived (grand)child. The parents terminate.
1453 * Many daemons use this technique.
1455 static void _check(pid_t pid
, const char *name
, void (*func
)(void))
1457 if (pid
== -1) return;
1459 if (pidof(name
) > 0) return;
1461 syslog(LOG_DEBUG
, "%s terminated unexpectedly, restarting.\n", name
);
1464 // Force recheck in 500 msec
1465 setitimer(ITIMER_REAL
, &pop_tv
, NULL
);
1468 void check_services(void)
1470 TRACE_PT("keep alive\n");
1472 // Periodically reap any zombies
1473 setitimer(ITIMER_REAL
, &zombie_tv
, NULL
);
1476 _check(pid_hotplug2
, "hotplug2", start_hotplug2
);
1478 _check(pid_dnsmasq
, "dnsmasq", start_dnsmasq
);
1479 _check(pid_crond
, "crond", start_cron
);
1480 _check(pid_igmp
, "igmpproxy", start_igmp_proxy
);
1483 // -----------------------------------------------------------------------------
1485 void start_services(void)
1487 static int once
= 1;
1492 if (nvram_get_int("telnetd_eas")) start_telnetd();
1493 if (nvram_get_int("sshd_eas")) start_sshd();
1506 restart_nas_services(1, 1); // !!TB - Samba, FTP and Media Server
1509 void stop_services(void)
1513 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
1526 // -----------------------------------------------------------------------------
1528 /* nvram "action_service" is: "service-action[-modifier]"
1529 * action is something like "stop" or "start" or "restart"
1530 * optional modifier is "c" for the "service" command-line command
1532 void exec_service(void)
1534 const int A_START
= 1;
1535 const int A_STOP
= 2;
1536 const int A_RESTART
= 1|2;
1545 strlcpy(buffer
, nvram_safe_get("action_service"), sizeof(buffer
));
1549 act
= strsep(&next
, ",");
1550 service
= strsep(&act
, "-");
1556 strsep(&modifier
, "-");
1558 TRACE_PT("service=%s action=%s modifier=%s\n", service
, act
, modifier
? : "");
1560 if (strcmp(act
, "start") == 0) action
= A_START
;
1561 else if (strcmp(act
, "stop") == 0) action
= A_STOP
;
1562 else if (strcmp(act
, "restart") == 0) action
= A_RESTART
;
1564 user
= (modifier
!= NULL
&& *modifier
== 'c');
1566 if (strcmp(service
, "dhcpc") == 0) {
1567 if (action
& A_STOP
) stop_dhcpc();
1568 if (action
& A_START
) start_dhcpc();
1572 if ((strcmp(service
, "dhcpd") == 0) || (strcmp(service
, "dns") == 0) || (strcmp(service
, "dnsmasq") == 0)) {
1573 if (action
& A_STOP
) stop_dnsmasq();
1574 if (action
& A_START
) {
1581 if (strcmp(service
, "firewall") == 0) {
1582 if (action
& A_STOP
) {
1586 if (action
& A_START
) {
1593 if (strcmp(service
, "restrict") == 0) {
1594 if (action
& A_STOP
) {
1597 if (action
& A_START
) {
1598 i
= nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
1602 // if radio was disabled by access restriction, but no rule is handling it now, enable it
1604 if (nvram_get_int("rrules_radio") < 0) {
1605 eval("radio", "on");
1612 if (strcmp(service
, "qos") == 0) {
1613 if (action
& A_STOP
) {
1616 stop_firewall(); start_firewall(); // always restarted
1617 if (action
& A_START
) {
1619 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
1625 if (strcmp(service
, "qoslimit") == 0) {
1626 if (action
& A_STOP
) {
1627 new_qoslimit_stop();
1629 stop_firewall(); start_firewall(); // always restarted
1630 if (action
& A_START
) {
1631 new_qoslimit_start();
1636 if (strcmp(service
, "arpbind") == 0) {
1637 if (action
& A_STOP
) new_arpbind_stop();
1638 if (action
& A_START
) new_arpbind_start();
1643 if (strcmp(service
, "upnp") == 0) {
1644 if (action
& A_STOP
) {
1647 stop_firewall(); start_firewall(); // always restarted
1648 if (action
& A_START
) {
1654 if (strcmp(service
, "telnetd") == 0) {
1655 if (action
& A_STOP
) stop_telnetd();
1656 if (action
& A_START
) start_telnetd();
1660 if (strcmp(service
, "sshd") == 0) {
1661 if (action
& A_STOP
) stop_sshd();
1662 if (action
& A_START
) start_sshd();
1666 if (strcmp(service
, "httpd") == 0) {
1667 if (action
& A_STOP
) stop_httpd();
1668 if (action
& A_START
) start_httpd();
1672 if (strcmp(service
, "admin") == 0) {
1673 if (action
& A_STOP
) {
1678 stop_firewall(); start_firewall(); // always restarted
1679 if (action
& A_START
) {
1682 if (nvram_match("telnetd_eas", "1")) start_telnetd();
1683 if (nvram_match("sshd_eas", "1")) start_sshd();
1688 if (strcmp(service
, "ddns") == 0) {
1689 if (action
& A_STOP
) stop_ddns();
1690 if (action
& A_START
) start_ddns();
1694 if (strcmp(service
, "ntpc") == 0) {
1695 if (action
& A_STOP
) stop_ntpc();
1696 if (action
& A_START
) start_ntpc();
1700 if (strcmp(service
, "logging") == 0) {
1701 if (action
& A_STOP
) {
1705 // always restarted except from "service" command
1706 stop_cron(); start_cron();
1707 stop_firewall(); start_firewall();
1709 if (action
& A_START
) {
1715 if (strcmp(service
, "crond") == 0) {
1716 if (action
& A_STOP
) {
1719 if (action
& A_START
) {
1726 if (strncmp(service
, "hotplug", 7) == 0) {
1727 if (action
& A_STOP
) {
1730 if (action
& A_START
) {
1737 if (strcmp(service
, "upgrade") == 0) {
1738 if (action
& A_START
) {
1743 restart_nas_services(1, 0); // stop Samba, FTP and Media Server
1751 killall("rstats", SIGTERM
);
1752 killall("buttons", SIGTERM
);
1754 remove_storage_main(1); // !!TB - USB Support
1755 stop_usb(); // !!TB - USB Support
1761 if (strcmp(service
, "cifs") == 0) {
1762 if (action
& A_STOP
) stop_cifs();
1763 if (action
& A_START
) start_cifs();
1768 #ifdef TCONFIG_JFFS2
1769 if (strncmp(service
, "jffs", 4) == 0) {
1770 if (action
& A_STOP
) stop_jffs2();
1771 if (action
& A_START
) start_jffs2();
1776 if (strcmp(service
, "routing") == 0) {
1777 if (action
& A_STOP
) {
1779 do_static_routes(0); // remove old '_saved'
1780 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
1784 if (action
& A_START
) {
1785 do_static_routes(1); // add new
1787 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
1792 if (strcmp(service
, "ctnf") == 0) {
1793 if (action
& A_START
) {
1801 if (strcmp(service
, "wan") == 0) {
1802 if (action
& A_STOP
) {
1803 if (get_wan_proto() == WP_PPPOE
) {
1806 stop_singe_pppoe(PPPOE0
);
1807 if (((action
& A_START
) == 0) && (nvram_match("ppp_demand", "1"))) {
1809 start_pppoe(PPPOE0
);
1818 if (action
& A_START
) {
1819 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
1821 if (get_wan_proto() == WP_PPPOE
) {
1822 stop_singe_pppoe(PPPOE0
);
1823 start_pppoe(PPPOE0
);
1824 if (nvram_invmatch("ppp_demand", "1")) {
1837 if (strcmp(service
, "net") == 0) {
1838 if (action
& A_STOP
) {
1845 if (action
& A_START
) {
1856 if (strcmp(service
, "nas") == 0) {
1857 if (action
& A_STOP
) {
1860 if (action
& A_START
) {
1867 if (strcmp(service
, "rstats") == 0) {
1868 if (action
& A_STOP
) stop_rstats();
1869 if (action
& A_START
) start_rstats(0);
1873 if (strcmp(service
, "rstatsnew") == 0) {
1874 if (action
& A_STOP
) stop_rstats();
1875 if (action
& A_START
) start_rstats(1);
1879 if (strcmp(service
, "sched") == 0) {
1880 if (action
& A_STOP
) stop_sched();
1881 if (action
& A_START
) start_sched();
1886 // !!TB - USB Support
1887 if (strcmp(service
, "usb") == 0) {
1888 if (action
& A_STOP
) stop_usb();
1889 if (action
& A_START
) {
1891 // restart Samba and ftp since they may be killed by stop_usb()
1892 restart_nas_services(0, 1);
1893 // remount all partitions by simulating hotplug event
1894 add_remove_usbhost("-1", 1);
1899 if (strcmp(service
, "usbapps") == 0) {
1900 if (action
& A_STOP
) stop_nas_services();
1901 if (action
& A_START
) start_nas_services();
1907 // !!TB - FTP Server
1908 if (strcmp(service
, "ftpd") == 0) {
1909 if (action
& A_STOP
) stop_ftpd();
1913 if (action
& A_START
) start_ftpd();
1918 #ifdef TCONFIG_MEDIA_SERVER
1919 if (strcmp(service
, "media") == 0 || strcmp(service
, "dlna") == 0) {
1920 if (action
& A_STOP
) stop_media_server();
1921 if (action
& A_START
) start_media_server();
1926 #ifdef TCONFIG_SAMBASRV
1928 if (strcmp(service
, "samba") == 0 || strcmp(service
, "smbd") == 0) {
1929 if (action
& A_STOP
) stop_samba();
1930 if (action
& A_START
) {
1940 #ifdef TCONFIG_OPENVPN
1941 if (strncmp(service
, "vpnclient", 9) == 0) {
1942 if (action
& A_STOP
) stop_vpnclient(atoi(&service
[9]));
1943 if (action
& A_START
) start_vpnclient(atoi(&service
[9]));
1947 if (strncmp(service
, "vpnserver", 9) == 0) {
1948 if (action
& A_STOP
) stop_vpnserver(atoi(&service
[9]));
1949 if (action
& A_START
) start_vpnserver(atoi(&service
[9]));
1957 // some functions check action_service and must be cleared at end -- zzz
1958 nvram_set("action_service", "");
1960 // Force recheck in 500 msec
1961 setitimer(ITIMER_REAL
, &pop_tv
, NULL
);
1964 static void do_service(const char *name
, const char *action
, int user
)
1970 while (!nvram_match("action_service", "")) {
1975 else if (--n
< 0) break;
1979 snprintf(s
, sizeof(s
), "%s-%s%s", name
, action
, (user
? "-c" : ""));
1980 nvram_set("action_service", s
);
1984 while (nvram_match("action_service", s
)) {
1996 int service_main(int argc
, char *argv
[])
1998 if (argc
!= 3) usage_exit(argv
[0], "<service> <action>");
1999 do_service(argv
[1], argv
[2], 1);
2000 printf("\nDone.\n");
2004 void start_service(const char *name
)
2006 do_service(name
, "start", 0);
2009 void stop_service(const char *name
)
2011 do_service(name
, "stop", 0);
2015 void restart_service(const char *name)
2017 do_service(name, "restart", 0);