Merge Tomato 1.26
[tomato.git] / release / src / router / rc / services.c
blob9a6ed42b73731149399ce2cfb022854389fd6d02
1 /*
3 Copyright 2003, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Copyright 2005, Broadcom Corporation
22 All Rights Reserved.
24 THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
25 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
26 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
27 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
32 Modified for Tomato Firmware
33 Portions, Copyright (C) 2006-2009 Jonathan Zarate
36 #include "rc.h"
38 #include <arpa/inet.h>
39 #include <time.h>
40 #include <sys/time.h>
41 #include <errno.h>
43 // !!TB
44 #include <sys/mount.h>
45 #include <mntent.h>
46 #include <dirent.h>
48 #define IFUP (IFF_UP | IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST)
49 #define sin_addr(s) (((struct sockaddr_in *)(s))->sin_addr)
51 // -----------------------------------------------------------------------------
53 static const char dmhosts[] = "/etc/hosts.dnsmasq";
54 static const char dmresolv[] = "/etc/resolv.dnsmasq";
55 static const char dmpid[] = "/var/run/dnsmasq.pid";
57 static pid_t pid_dnsmasq = -1;
60 void start_dnsmasq()
62 FILE *f;
63 const char *nv;
64 char buf[512];
65 char lan[24];
66 const char *router_ip;
67 const char *lan_ifname;
68 char sdhcp_lease[32];
69 char *e;
70 int n;
71 char *mac, *ip, *name;
72 char *p;
73 int ipn;
74 char ipbuf[32];
75 FILE *hf;
76 int dhcp_start;
77 int dhcp_count;
78 int dhcp_lease;
79 int do_dhcpd;
80 int do_dns;
82 TRACE_PT("begin\n");
84 if (getpid() != 1) {
85 start_service("dnsmasq");
86 return;
89 stop_dnsmasq();
91 if (nvram_match("wl_mode", "wet")) return;
92 if ((f = fopen("/etc/dnsmasq.conf", "w")) == NULL) return;
94 lan_ifname = nvram_safe_get("lan_ifname");
95 router_ip = nvram_safe_get("lan_ipaddr");
96 strlcpy(lan, router_ip, sizeof(lan));
97 if ((p = strrchr(lan, '.')) != NULL) *(p + 1) = 0;
99 fprintf(f,
100 "pid-file=%s\n"
101 "interface=%s\n",
102 dmpid, lan_ifname);
103 if (((nv = nvram_get("wan_domain")) != NULL) || ((nv = nvram_get("wan_get_domain")) != NULL)) {
104 if (*nv) fprintf(f, "domain=%s\n", nv);
107 // dns
108 const dns_list_t *dns = get_dns(); // this always points to a static buffer
110 if (((nv = nvram_get("dns_minport")) != NULL) && (*nv)) n = atoi(nv);
111 else n = 4096;
112 fprintf(f,
113 "resolv-file=%s\n" // the real stuff is here
114 "addn-hosts=%s\n" // "
115 "expand-hosts\n" // expand hostnames in hosts file
116 "min-port=%u\n", // min port used for random src port
117 dmresolv, dmhosts, n);
118 do_dns = nvram_match("dhcpd_dmdns", "1");
120 for (n = 0 ; n < dns->count; ++n) {
121 if (dns->dns[n].port != 53) {
122 fprintf(f, "server=%s#%u\n", inet_ntoa(dns->dns[n].addr), dns->dns[n].port);
127 // dhcp
128 do_dhcpd = nvram_match("lan_proto", "dhcp");
129 if (do_dhcpd) {
130 dhcp_lease = nvram_get_int("dhcp_lease");
131 if (dhcp_lease <= 0) dhcp_lease = 1440;
133 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
134 if (n < 0) strcpy(sdhcp_lease, "infinite");
135 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
137 if (!do_dns) {
138 // if not using dnsmasq for dns
140 if ((dns->count == 0) && (nvram_get_int("dhcpd_llndns"))) {
141 // no DNS might be temporary. use a low lease time to force clients to update.
142 dhcp_lease = 2;
143 strcpy(sdhcp_lease, "2m");
144 do_dns = 1;
146 else {
147 // pass the dns directly
148 buf[0] = 0;
149 for (n = 0 ; n < dns->count; ++n) {
150 if (dns->dns[n].port == 53) { // check: option 6 doesn't seem to support other ports
151 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n].addr));
154 fprintf(f, "dhcp-option=6%s\n", buf);
158 if ((p = nvram_get("dhcpd_startip")) && (*p) && (e = nvram_get("dhcpd_endip")) && (*e)) {
159 fprintf(f, "dhcp-range=%s,%s,%s,%dm\n", p, e, nvram_safe_get("lan_netmask"), dhcp_lease);
161 else {
162 // for compatibility
163 dhcp_start = nvram_get_int("dhcp_start");
164 dhcp_count = nvram_get_int("dhcp_num");
165 fprintf(f, "dhcp-range=%s%d,%s%d,%s,%dm\n",
166 lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get("lan_netmask"), dhcp_lease);
169 nv = router_ip;
170 if ((nvram_get_int("dhcpd_gwmode") == 1) && (get_wan_proto() == WP_DISABLED)) {
171 p = nvram_safe_get("lan_gateway");
172 if ((*p) && (strcmp(p, "0.0.0.0") != 0)) nv = p;
175 n = nvram_get_int("dhcpd_lmax");
176 fprintf(f,
177 "dhcp-option=3,%s\n" // gateway
178 "dhcp-lease-max=%d\n",
180 (n > 0) ? n : 255);
182 if (nvram_get_int("dhcpd_auth") >= 0) {
183 fprintf(f, "dhcp-authoritative\n");
186 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
187 fprintf(f, "dhcp-option=44,%s\n", nv);
189 #ifdef TCONFIG_SAMBASRV
190 else if (nvram_get_int("smbd_enable") && nvram_invmatch("lan_hostname", "") && nvram_get_int("smbd_wins")) {
191 if ((nv == NULL) || (*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
192 // Samba will serve as a WINS server
193 fprintf(f, "dhcp-option=44,0.0.0.0\n");
196 #endif
198 else {
199 fprintf(f, "no-dhcp-interface=%s\n", lan_ifname);
202 // write static lease entries & create hosts file
204 if ((hf = fopen(dmhosts, "w")) != NULL) {
205 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
206 fprintf(hf, "%s %s\n", router_ip, nv);
207 #ifdef TCONFIG_SAMBASRV
208 else if (((nv = nvram_get("lan_hostname")) != NULL) && (*nv))
209 fprintf(hf, "%s %s\n", router_ip, nv);
210 #endif
213 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
214 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
215 // 00:aa:bb:cc:dd:ee,00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 106 w/ delim
216 p = nvram_safe_get("dhcpd_static");
217 while ((e = strchr(p, '>')) != NULL) {
218 n = (e - p);
219 if (n > 105) {
220 p = e + 1;
221 continue;
224 strncpy(buf, p, n);
225 buf[n] = 0;
226 p = e + 1;
228 if ((e = strchr(buf, '<')) == NULL) continue;
229 *e = 0;
230 mac = buf;
232 ip = e + 1;
233 if ((e = strchr(ip, '<')) == NULL) continue;
234 *e = 0;
235 if (strchr(ip, '.') == NULL) {
236 ipn = atoi(ip);
237 if ((ipn <= 0) || (ipn > 255)) continue;
238 sprintf(ipbuf, "%s%d", lan, ipn);
239 ip = ipbuf;
241 else {
242 if (inet_addr(ip) == INADDR_NONE) continue;
245 name = e + 1;
247 if ((hf) && (*name != 0)) {
248 fprintf(hf, "%s %s\n", ip, name);
251 if ((do_dhcpd) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
252 fprintf(f, "dhcp-host=%s,%s,%s\n", mac, ip, sdhcp_lease);
256 if (hf) fclose(hf);
260 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
262 fappend(f, "/etc/dnsmasq.custom");
266 fclose(f);
268 if (do_dns) {
269 unlink("/etc/resolv.conf");
270 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
273 TRACE_PT("run dnsmasq\n");
275 eval("dnsmasq");
277 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
278 f_read_string(dmpid, buf, sizeof(buf));
279 pid_dnsmasq = atol(buf);
282 TRACE_PT("end\n");
285 void stop_dnsmasq(void)
287 TRACE_PT("begin\n");
289 if (getpid() != 1) {
290 stop_service("dnsmasq");
291 return;
294 pid_dnsmasq = -1;
296 unlink("/etc/resolv.conf");
297 symlink(dmresolv, "/etc/resolv.conf");
299 killall_tk("dnsmasq");
301 TRACE_PT("end\n");
304 void clear_resolv(void)
306 f_write(dmresolv, NULL, 0, 0, 0); // blank
309 void dns_to_resolv(void)
311 FILE *f;
312 const dns_list_t *dns;
313 int i;
314 mode_t m;
316 m = umask(022); // 077 from pppoecd
317 if ((f = fopen(dmresolv, "w")) != NULL) {
318 dns = get_dns(); // static buffer
319 if (dns->count == 0) {
320 // Put a pseudo DNS IP to trigger Connect On Demand
321 if ((nvram_match("ppp_demand", "1")) &&
322 (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "pptp") || nvram_match("wan_proto", "l2tp"))) {
323 fprintf(f, "nameserver 1.1.1.1\n");
326 else {
327 for (i = 0; i < dns->count; i++) {
328 if (dns->dns[i].port == 53) { // resolv.conf doesn't allow for an alternate port
329 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i].addr));
333 fclose(f);
335 umask(m);
338 // -----------------------------------------------------------------------------
340 void start_httpd(void)
342 chdir("/www");
343 if (!nvram_match("http_enable", "0")) {
344 xstart("httpd");
346 if (!nvram_match("https_enable", "0")) {
347 xstart("httpd", "-s");
349 chdir("/");
352 void stop_httpd(void)
354 killall_tk("httpd");
357 // -----------------------------------------------------------------------------
359 void start_upnp(void)
361 if (get_wan_proto() == WP_DISABLED) return;
363 int enable;
364 FILE *f;
365 int upnp_port;
367 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
368 mkdir("/etc/upnp", 0777);
369 if (f_exists("/etc/upnp/config.alt")) {
370 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
372 else {
373 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
374 upnp_port = nvram_get_int("upnp_port");
375 if ((upnp_port <= 0) || (upnp_port >= 0xFFFF)) upnp_port = 5000;
377 fprintf(f,
378 "ext_ifname=%s\n"
379 "listening_ip=%s\n"
380 "port=%d\n"
381 "enable_upnp=%s\n"
382 "enable_natpmp=%s\n"
383 "secure_mode=%s\n"
384 "upnp_forward_chain=upnp\n"
385 "upnp_nat_chain=upnp\n"
386 "system_uptime=yes\n"
387 "\n"
389 nvram_safe_get("wan_iface"),
390 nvram_safe_get("lan_ipaddr"),
391 upnp_port,
392 (enable & 1) ? "yes" : "no", // upnp enable
393 (enable & 2) ? "yes" : "no", // natpmp enable
394 nvram_get_int("upnp_secure") ? "yes" : "no" // secure_mode (only forward to self)
396 fappend(f, "/etc/upnp/config.custom");
397 fclose(f);
399 xstart("miniupnpd", "-f", "/etc/upnp/config");
405 void stop_upnp(void)
407 killall_tk("miniupnpd");
410 // -----------------------------------------------------------------------------
412 static pid_t pid_crond = -1;
414 void start_cron(void)
416 char *argv[] = { "crond", "-l", "9", NULL };
418 stop_cron();
420 if (nvram_contains_word("log_events", "crond")) argv[1] = NULL;
421 _eval(argv, NULL, 0, NULL);
422 if (!nvram_contains_word("debug_norestart", "crond")) {
423 pid_crond = -2;
428 void stop_cron(void)
430 pid_crond = -1;
431 killall_tk("crond");
434 // -----------------------------------------------------------------------------
436 // Written by Sparq in 2002/07/16
437 void start_zebra(void)
439 #ifdef TCONFIG_ZEBRA
440 FILE *fp;
442 char *lan_tx = nvram_safe_get("dr_lan_tx");
443 char *lan_rx = nvram_safe_get("dr_lan_rx");
444 char *wan_tx = nvram_safe_get("dr_wan_tx");
445 char *wan_rx = nvram_safe_get("dr_wan_rx");
447 if ((*lan_tx == '0') && (*lan_rx == '0') && (*wan_tx == '0') && (*wan_rx == '0')) {
448 return;
451 // empty
452 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
453 fclose(fp);
457 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
458 char *lan_ifname = nvram_safe_get("lan_ifname");
459 char *wan_ifname = nvram_safe_get("wan_ifname");
461 fprintf(fp, "router rip\n");
462 fprintf(fp, "network %s\n", lan_ifname);
463 fprintf(fp, "network %s\n", wan_ifname);
464 fprintf(fp, "redistribute connected\n");
465 //fprintf(fp, "redistribute static\n");
467 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
468 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
470 fprintf(fp, "interface %s\n", lan_ifname);
471 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
472 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
474 fprintf(fp, "interface %s\n", wan_ifname);
475 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
476 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
478 fprintf(fp, "router rip\n");
479 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
480 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
481 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
482 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
483 fprintf(fp, "access-list private deny any\n");
485 //fprintf(fp, "debug rip events\n");
486 //fprintf(fp, "log file /etc/ripd.log\n");
487 fclose(fp);
490 xstart("zebra", "-d", "-f", "/etc/zebra.conf");
491 xstart("ripd", "-d", "-f", "/etc/ripd.conf");
492 #endif
495 void stop_zebra(void)
497 #ifdef TCONFIG_ZEBRA
498 killall("zebra", SIGTERM);
499 killall("ripd", SIGTERM);
501 unlink("/etc/zebra.conf");
502 unlink("/etc/ripd.conf");
503 #endif
506 // -----------------------------------------------------------------------------
508 void start_syslog(void)
510 #if 1
511 char *argv[12];
512 int argc;
513 char *nv;
514 char rem[256];
515 int n;
516 char s[64];
518 argv[0] = "syslogd";
519 argc = 1;
521 if (nvram_match("log_remote", "1")) {
522 nv = nvram_safe_get("log_remoteip");
523 if (*nv) {
524 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
525 argv[argc++] = "-R";
526 argv[argc++] = rem;
530 if (nvram_match("log_file", "1")) {
531 argv[argc++] = "-L";
532 argv[argc++] = "-s";
533 argv[argc++] = "50";
536 if (argc > 1) {
537 argv[argc] = NULL;
538 _eval(argv, NULL, 0, NULL);
539 usleep(500000);
541 argv[0] = "klogd";
542 argv[1] = NULL;
543 _eval(argv, NULL, 0, NULL);
544 usleep(500000);
546 // used to be available in syslogd -m
547 n = nvram_get_int("log_mark");
548 if (n > 0) {
549 sprintf(s, "cru a syslogdmark \"%s %s * * * logger -p syslog.info -- -- MARK --\"",
550 (n < 60) ? "*/30" : "0", (n < 120) ? "*" : "*/2");
551 system(s);
553 else {
554 system("cru d syslogdmark");
558 #else
559 char *argv[12];
560 int argc;
561 char *nv;
562 char rem[256];
564 argv[0] = "syslogd";
565 argv[1] = "-m";
566 argv[2] = nvram_get("log_mark");
567 argc = 3;
569 if (nvram_match("log_remote", "1")) {
570 nv = nvram_safe_get("log_remoteip");
571 if (*nv) {
572 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
573 argv[argc++] = "-R";
574 argv[argc++] = rem;
578 if (nvram_match("log_file", "1")) {
579 argv[argc++] = "-L";
580 argv[argc++] = "-s";
581 argv[argc++] = "50";
584 if (argc > 3) {
585 argv[argc] = NULL;
586 _eval(argv, NULL, 0, NULL);
587 usleep(500000);
589 argv[0] = "klogd";
590 argv[1] = NULL;
591 _eval(argv, NULL, 0, NULL);
592 usleep(500000);
594 #endif
597 void stop_syslog(void)
599 killall("klogd", SIGTERM);
600 killall("syslogd", SIGTERM);
603 // -----------------------------------------------------------------------------
605 static pid_t pid_igmp = -1;
607 void start_igmp_proxy(void)
609 static char *igmpproxy_conf = "/etc/igmpproxy.conf";
610 FILE *fp;
611 char *p;
613 pid_igmp = -1;
614 if (nvram_match("multicast_pass", "1")) {
615 switch (get_wan_proto()) {
616 case WP_PPPOE:
617 case WP_PPTP:
618 case WP_L2TP:
619 p = "wan_iface";
620 break;
621 default:
622 p = "wan_ifname";
623 break;
626 if ((fp = fopen(igmpproxy_conf, "w")) != NULL) {
627 fprintf(fp,
628 "quickleave\n"
629 "phyint %s upstream\n"
630 "\taltnet %s\n"
631 "phyint %s downstream ratelimit 0\n",
632 nvram_safe_get(p),
633 nvram_get("multicast_altnet") ? : "0.0.0.0/0",
634 nvram_safe_get("lan_ifname") ? : "br0");
635 fclose(fp);
636 xstart("igmpproxy", igmpproxy_conf);
638 if (!nvram_contains_word("debug_norestart", "igmprt")) {
639 pid_igmp = -2;
645 void stop_igmp_proxy(void)
647 pid_igmp = -1;
648 killall("igmpproxy", SIGTERM);
652 // -----------------------------------------------------------------------------
654 void set_tz(void)
656 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
659 void start_ntpc(void)
661 set_tz();
663 stop_ntpc();
665 if (nvram_get_int("ntp_updates") >= 0) {
666 xstart("ntpsync", "--init");
670 void stop_ntpc(void)
672 killall("ntpsync", SIGTERM);
675 // -----------------------------------------------------------------------------
677 static void stop_rstats(void)
679 int n;
680 int pid;
682 n = 60;
683 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
684 if (kill(pid, SIGTERM) != 0) break;
685 sleep(1);
689 static void start_rstats(int new)
691 if (nvram_match("rstats_enable", "1")) {
692 stop_rstats();
693 if (new) xstart("rstats", "--new");
694 else xstart("rstats");
698 // -----------------------------------------------------------------------------
700 // !!TB - FTP Server
702 #ifdef TCONFIG_USB
704 * Return non-zero if we created the directory,
705 * and zero if it already existed.
707 int mkdir_if_none(char *dir)
709 DIR *dp;
710 if (!(dp=opendir(dir))) {
711 umask(0000);
712 mkdir(dir, 0777);
713 return 1;
715 closedir(dp);
716 return 0;
719 char *get_full_storage_path(char *val)
721 static char buf[128];
722 int len;
724 if (val[0] == '/')
725 len = sprintf(buf, "%s", val);
726 else
727 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
729 if (len > 1 && buf[len - 1] == '/')
730 buf[len - 1] = 0;
732 return buf;
735 char *nvram_storage_path(char *var)
737 char *val = nvram_safe_get(var);
738 return get_full_storage_path(val);
740 #endif // TCONFIG_USB
742 #ifdef TCONFIG_FTP
744 char vsftpd_conf[] = "/etc/vsftpd.conf";
745 char vsftpd_users[] = "/etc/vsftpd.users";
746 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
747 #endif
749 #ifdef TCONFIG_FTP
750 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
751 static void do_start_stop_ftpd(int stop, int start)
753 if (stop) killall("vsftpd", SIGTERM);
755 char tmp[256];
756 FILE *fp, *f;
758 if (!start || !nvram_get_int("ftp_enable")) return;
760 mkdir_if_none(vsftpd_users);
761 mkdir_if_none("/var/run/vsftpd");
763 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
764 return;
766 if (nvram_get_int("ftp_super"))
768 /* rights */
769 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
770 if ((f = fopen(tmp, "w")))
772 fprintf(f,
773 "dirlist_enable=yes\n"
774 "write_enable=yes\n"
775 "download_enable=yes\n");
776 fclose(f);
780 #ifdef TCONFIG_SAMBASRV
781 if (nvram_match("smbd_cset", "utf8"))
782 fprintf(fp, "utf8=yes\n");
783 #endif
785 if (nvram_invmatch("ftp_anonymous", "0"))
787 fprintf(fp,
788 "anon_allow_writable_root=yes\n"
789 "anon_world_readable_only=no\n"
790 "anon_umask=022\n");
792 /* rights */
793 sprintf(tmp, "%s/ftp", vsftpd_users);
794 if ((f = fopen(tmp, "w")))
796 if (nvram_match("ftp_dirlist", "0"))
797 fprintf(f, "dirlist_enable=yes\n");
798 if (nvram_match("ftp_anonymous", "1") ||
799 nvram_match("ftp_anonymous", "3"))
800 fprintf(f, "write_enable=yes\n");
801 if (nvram_match("ftp_anonymous", "1") ||
802 nvram_match("ftp_anonymous", "2"))
803 fprintf(f, "download_enable=yes\n");
804 fclose(f);
806 if (nvram_match("ftp_anonymous", "1") ||
807 nvram_match("ftp_anonymous", "3"))
808 fprintf(fp,
809 "anon_upload_enable=yes\n"
810 "anon_mkdir_write_enable=yes\n"
811 "anon_other_write_enable=yes\n");
812 } else {
813 fprintf(fp, "anonymous_enable=no\n");
816 fprintf(fp,
817 "dirmessage_enable=yes\n"
818 "download_enable=no\n"
819 "dirlist_enable=no\n"
820 "hide_ids=yes\n"
821 "syslog_enable=yes\n"
822 "local_enable=yes\n"
823 "local_umask=022\n"
824 "chmod_enable=no\n"
825 "chroot_local_user=yes\n"
826 "check_shell=no\n"
827 "log_ftp_protocol=%s\n"
828 "user_config_dir=%s\n"
829 "passwd_file=%s\n"
830 "listen=yes\n"
831 "listen_port=%s\n"
832 "background=yes\n"
833 "max_clients=%d\n"
834 "max_per_ip=%d\n"
835 "idle_session_timeout=%s\n"
836 "use_sendfile=no\n"
837 "anon_max_rate=%d\n"
838 "local_max_rate=%d\n"
839 "%s\n",
840 nvram_get_int("log_ftp") ? "yes" : "no",
841 vsftpd_users, vsftpd_passwd,
842 nvram_get("ftp_port") ? : "21",
843 nvram_get_int("ftp_max"),
844 nvram_get_int("ftp_ipmax"),
845 nvram_get("ftp_staytimeout") ? : "300",
846 nvram_get_int("ftp_anonrate") * 1024,
847 nvram_get_int("ftp_rate") * 1024,
848 nvram_safe_get("ftp_custom"));
850 fclose(fp);
852 /* prepare passwd file and default users */
853 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
854 return;
856 fprintf(fp, /* anonymous, admin, nobody */
857 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
858 "%s:%s:0:0:root:/:/sbin/nologin\n"
859 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
860 nvram_storage_path("ftp_anonroot"), "admin",
861 nvram_get_int("ftp_super") ? crypt(nvram_safe_get("http_passwd"), "$1$") : "x",
862 MOUNT_ROOT);
864 char *buf;
865 char *p, *q;
866 char *user, *pass, *rights;
868 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
871 username<password<rights
872 rights:
873 Read/Write
874 Read Only
875 View Only
876 Private
878 p = buf;
879 while ((q = strsep(&p, ">")) != NULL) {
880 if (vstrsep(q, "<", &user, &pass, &rights) != 3) continue;
881 if (!user || !pass) continue;
883 /* directory */
884 if (strncmp(rights, "Private", 7) == 0)
886 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
887 mkdir_if_none(tmp);
889 else
890 sprintf(tmp, "%s", nvram_storage_path("ftp_pubroot"));
892 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
893 user, crypt(pass, "$1$"), user, tmp);
895 /* rights */
896 sprintf(tmp, "%s/%s", vsftpd_users, user);
897 if ((f = fopen(tmp, "w")))
899 tmp[0] = 0;
900 if (nvram_invmatch("ftp_dirlist", "1"))
901 strcat(tmp, "dirlist_enable=yes\n");
902 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
903 strcat(tmp, "download_enable=yes\n");
904 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
905 strcat(tmp, "write_enable=yes\n");
907 fputs(tmp, f);
908 fclose(f);
911 free(buf);
914 fclose(fp);
915 killall("vsftpd", SIGHUP);
917 /* start vsftpd if it's not already running */
918 if (pidof("vsftpd") <= 0)
919 eval("vsftpd");
921 #endif
923 void start_ftpd(void)
925 #ifdef TCONFIG_FTP
926 int fd = file_lock("usb");
927 do_start_stop_ftpd(0, 1);
928 file_unlock(fd);
929 #endif
932 void stop_ftpd(void)
934 #ifdef TCONFIG_FTP
935 int fd = file_lock("usb");
936 do_start_stop_ftpd(1, 0);
937 unlink(vsftpd_passwd);
938 unlink(vsftpd_conf);
939 eval("rm", "-rf", vsftpd_users);
940 file_unlock(fd);
941 #endif
944 // -----------------------------------------------------------------------------
946 // !!TB - Samba
948 #ifdef TCONFIG_SAMBASRV
949 void kill_samba(int sig)
951 killall("smbd", sig);
952 killall("nmbd", sig);
954 #endif
956 #ifdef TCONFIG_SAMBASRV
957 static void do_start_stop_samba(int stop, int start)
959 if (stop) kill_samba(SIGTERM);
961 FILE *fp;
962 DIR *dir = NULL;
963 struct dirent *dp;
964 char nlsmod[15];
965 int mode;
966 char *nv;
968 mode = nvram_get_int("smbd_enable");
969 if (!start || !mode || !nvram_invmatch("lan_hostname", ""))
970 return;
972 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
973 return;
975 fprintf(fp, "[global]\n"
976 " interfaces = %s\n"
977 " bind interfaces only = yes\n"
978 " workgroup = %s\n"
979 " server string = %s\n"
980 " guest account = nobody\n"
981 " security = %s\n"
982 " browseable = yes\n"
983 " guest ok = yes\n"
984 " guest only = no\n"
985 " log level = %d\n"
986 " syslog only = yes\n"
987 " timestamp logs = no\n"
988 " syslog = 1\n"
989 " encrypt passwords = yes\n"
990 " preserve case = yes\n"
991 " short preserve case = yes\n",
992 nvram_safe_get("lan_ifname"),
993 nvram_get("smbd_wgroup") ? : "WORKGROUP",
994 nvram_get("router_name") ? : "Tomato",
995 mode == 2 ? "user" : "share",
996 nvram_get_int("smbd_loglevel")
999 if (nvram_get_int("smbd_wins")) {
1000 nv = nvram_safe_get("wan_wins");
1001 if ((*nv == 0) || (strcmp(nv, "0.0.0.0") == 0)) {
1002 fprintf(fp, " wins support = yes\n");
1006 if (nvram_get_int("smbd_master")) {
1007 fprintf(fp,
1008 " domain master = yes\n"
1009 " local master = yes\n"
1010 " preferred master = yes\n"
1011 " os level = 65\n");
1014 nv = nvram_safe_get("smbd_cpage");
1015 if (*nv) {
1016 fprintf(fp, " client code page = %s\n", nv);
1017 sprintf(nlsmod, "nls_cp%s", nv);
1019 nv = nvram_safe_get("smbd_nlsmod");
1020 if ((*nv) && (strcmp(nv, nlsmod) != 0))
1021 modprobe_r(nv);
1023 modprobe(nlsmod);
1024 nvram_set("smbd_nlsmod", nlsmod);
1027 if (nvram_match("smbd_cset", "utf8"))
1028 fprintf(fp, " coding system = utf8\n");
1029 else if (nvram_invmatch("smbd_cset", ""))
1030 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1032 fprintf(fp, "%s\n\n", nvram_safe_get("smbd_custom"));
1034 /* configure shares */
1036 char *buf;
1037 char *p, *q;
1038 char *name, *path, *comment, *writeable, *hidden;
1039 int cnt = 0;
1041 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1043 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1045 p = buf;
1046 while ((q = strsep(&p, ">")) != NULL) {
1047 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1048 if (!path || !name) continue;
1050 /* share name */
1051 fprintf(fp, "\n[%s]\n", name);
1053 /* path */
1054 fprintf(fp, " path = %s\n", path);
1056 /* access level */
1057 if (!strcmp(writeable, "1"))
1058 fprintf(fp, " writable = yes\n force user = %s\n", "root");
1059 if (!strcmp(hidden, "1"))
1060 fprintf(fp, " browseable = no\n");
1062 /* comment */
1063 if (comment)
1064 fprintf(fp, " comment = %s\n", comment);
1066 cnt++;
1068 free(buf);
1071 /* share everything below MOUNT_ROOT */
1072 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1073 while ((dp = readdir(dir))) {
1074 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1076 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1077 fprintf(fp, "\n[%s]\n path = %s/%s\n comment = %s\n",
1078 dp->d_name, MOUNT_ROOT, dp->d_name, dp->d_name);
1079 if (nvram_match("smbd_autoshare", "3")) // Hidden
1080 fprintf(fp, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1081 dp->d_name, MOUNT_ROOT, dp->d_name);
1082 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1083 fprintf(fp, " writable = yes\n force user = %s\n", "root");
1085 cnt++;
1089 if (dir) closedir(dir);
1091 if (cnt == 0) {
1092 /* by default share MOUNT_ROOT as read-only */
1093 fprintf(fp, "\n[share]\n"
1094 " path = %s\n"
1095 " writable = no\n",
1096 MOUNT_ROOT);
1099 fclose(fp);
1101 mkdir_if_none("/var/run/samba");
1102 mkdir_if_none("/etc/samba");
1104 /* write smbpasswd */
1105 eval("smbpasswd", "-a", "nobody", "\"\"");
1106 if (mode == 2) {
1107 char *smbd_user;
1108 if (((smbd_user = nvram_get("smbd_user")) == NULL) || (*smbd_user == 0) || !strcmp(smbd_user, "root"))
1109 smbd_user = "nas";
1110 eval("smbpasswd", "-a", smbd_user, nvram_safe_get("smbd_passwd"));
1113 kill_samba(SIGHUP);
1114 int ret1 = 0, ret2 = 0;
1115 /* start samba if it's not already running */
1116 if (pidof("nmbd") <= 0)
1117 ret1 = eval("nmbd", "-D");
1118 if (pidof("smbd") <= 0)
1119 ret2 = eval("smbd", "-D");
1121 if (ret1 || ret2) kill_samba(SIGTERM);
1123 #endif
1125 void start_samba(void)
1127 #ifdef TCONFIG_SAMBASRV
1128 int fd = file_lock("usb");
1129 do_start_stop_samba(0, 1);
1130 file_unlock(fd);
1131 #endif
1134 void stop_samba(void)
1136 #ifdef TCONFIG_SAMBASRV
1137 int fd = file_lock("usb");
1138 do_start_stop_samba(1, 0);
1139 sleep(2); /* wait for smbd to finish */
1141 if (nvram_invmatch("smbd_nlsmod", "")) {
1142 modprobe_r(nvram_get("smbd_nlsmod"));
1143 nvram_set("smbd_nlsmod", "");
1146 /* clean up */
1147 unlink("/var/log/smb");
1148 unlink("/var/log/nmb");
1149 eval("rm", "-rf", "/var/run/samba");
1150 file_unlock(fd);
1151 #endif
1154 #ifdef TCONFIG_USB
1155 void restart_nas_services(int stop, int start)
1157 /* restart all NAS applications */
1158 #if TCONFIG_SAMBASRV || TCONFIG_FTP
1159 int fd = file_lock("usb");
1160 #ifdef TCONFIG_SAMBASRV
1161 do_start_stop_samba(stop, start && nvram_get_int("smbd_enable"));
1162 #endif
1163 #ifdef TCONFIG_FTP
1164 do_start_stop_ftpd(stop, start && nvram_get_int("ftp_enable"));
1165 #endif
1166 file_unlock(fd);
1167 #endif // TCONFIG_SAMBASRV || TCONFIG_FTP
1169 #endif // TCONFIG_USB
1171 // -----------------------------------------------------------------------------
1173 static void _check(pid_t *pid, const char *name, void (*func)(void) )
1175 if (*pid != -1) {
1176 if (kill(*pid, 0) != 0) {
1177 if ((*pid = pidof(name)) == -1) func();
1182 void check_services(void)
1184 _check(&pid_dnsmasq, "dnsmasq", start_dnsmasq);
1185 _check(&pid_crond, "crond", start_cron);
1186 _check(&pid_igmp, "igmpproxy", start_igmp_proxy);
1189 // -----------------------------------------------------------------------------
1191 void start_services(void)
1193 static int once = 1;
1195 if (once) {
1196 once = 0;
1198 create_passwd();
1199 if (nvram_get_int("telnetd_eas")) start_telnetd();
1200 if (nvram_get_int("sshd_eas")) start_sshd();
1203 start_syslog();
1204 start_nas();
1205 start_zebra();
1206 start_dnsmasq();
1207 start_cifs();
1208 start_httpd();
1209 start_cron();
1210 // start_upnp();
1211 start_rstats(0);
1212 start_sched();
1213 restart_nas_services(1, 1); // !!TB - Samba and FTP Server
1216 void stop_services(void)
1218 clear_resolv();
1220 stop_ftpd(); // !!TB - FTP Server
1221 stop_samba(); // !!TB - Samba
1222 stop_sched();
1223 stop_rstats();
1224 // stop_upnp();
1225 stop_cron();
1226 stop_httpd();
1227 stop_cifs();
1228 stop_dnsmasq();
1229 stop_zebra();
1230 stop_nas();
1231 stop_syslog();
1234 // -----------------------------------------------------------------------------
1236 void exec_service(void)
1238 const int A_START = 1;
1239 const int A_STOP = 2;
1240 const int A_RESTART = 1|2;
1241 char buffer[128];
1242 char *service;
1243 char *act;
1244 char *next;
1245 int action;
1246 int i;
1248 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
1249 next = buffer;
1251 TOP:
1252 act = strsep(&next, ",");
1253 service = strsep(&act, "-");
1254 if (act == NULL) {
1255 next = NULL;
1256 goto CLEAR;
1259 TRACE_PT("service=%s action=%s\n", service, act);
1261 if (strcmp(act, "start") == 0) action = A_START;
1262 else if (strcmp(act, "stop") == 0) action = A_STOP;
1263 else if (strcmp(act, "restart") == 0) action = A_RESTART;
1264 else action = 0;
1267 if (strcmp(service, "dhcpc") == 0) {
1268 if (action & A_STOP) stop_dhcpc();
1269 if (action & A_START) start_dhcpc();
1270 goto CLEAR;
1273 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
1274 if (action & A_STOP) stop_dnsmasq();
1275 if (action & A_START) {
1276 dns_to_resolv();
1277 start_dnsmasq();
1279 goto CLEAR;
1282 if (strcmp(service, "firewall") == 0) {
1283 if (action & A_STOP) {
1284 stop_firewall();
1285 stop_igmp_proxy();
1287 if (action & A_START) {
1288 start_firewall();
1289 start_igmp_proxy();
1291 goto CLEAR;
1294 if (strcmp(service, "restrict") == 0) {
1295 if (action & A_STOP) {
1296 stop_firewall();
1298 if (action & A_START) {
1299 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
1301 start_firewall();
1303 // if radio was disabled by access restriction, but no rule is handling it now, enable it
1304 if (i == 1) {
1305 if (nvram_get_int("rrules_radio") < 0) {
1306 if (!get_radio()) eval("radio", "on");
1310 goto CLEAR;
1313 if (strcmp(service, "qos") == 0) {
1314 if (action & A_STOP) {
1315 stop_qos();
1317 stop_firewall(); start_firewall(); // always restarted
1318 if (action & A_START) {
1319 start_qos();
1320 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
1322 goto CLEAR;
1325 if (strcmp(service, "upnp") == 0) {
1326 if (action & A_STOP) {
1327 stop_upnp();
1329 stop_firewall(); start_firewall(); // always restarted
1330 if (action & A_START) {
1331 start_upnp();
1333 goto CLEAR;
1336 if (strcmp(service, "telnetd") == 0) {
1337 if (action & A_STOP) stop_telnetd();
1338 if (action & A_START) start_telnetd();
1339 goto CLEAR;
1342 if (strcmp(service, "sshd") == 0) {
1343 if (action & A_STOP) stop_sshd();
1344 if (action & A_START) start_sshd();
1345 goto CLEAR;
1348 if (strcmp(service, "httpd") == 0) {
1349 if (action & A_STOP) stop_httpd();
1350 if (action & A_START) start_httpd();
1351 goto CLEAR;
1354 if (strcmp(service, "admin") == 0) {
1355 if (action & A_STOP) {
1356 stop_sshd();
1357 stop_telnetd();
1358 stop_httpd();
1360 stop_firewall(); start_firewall(); // always restarted
1361 if (action & A_START) {
1362 start_httpd();
1363 create_passwd();
1364 if (nvram_match("telnetd_eas", "1")) start_telnetd();
1365 if (nvram_match("sshd_eas", "1")) start_sshd();
1367 goto CLEAR;
1370 if (strcmp(service, "ddns") == 0) {
1371 if (action & A_STOP) stop_ddns();
1372 if (action & A_START) start_ddns();
1373 goto CLEAR;
1376 if (strcmp(service, "ntpc") == 0) {
1377 if (action & A_STOP) stop_ntpc();
1378 if (action & A_START) start_ntpc();
1379 goto CLEAR;
1382 if (strcmp(service, "logging") == 0) {
1383 if (action & A_STOP) {
1384 stop_syslog();
1385 stop_cron();
1387 stop_firewall(); start_firewall(); // always restarted
1388 if (action & A_START) {
1389 start_cron();
1390 start_syslog();
1392 goto CLEAR;
1395 if (strcmp(service, "crond") == 0) {
1396 if (action & A_STOP) {
1397 stop_cron();
1399 if (action & A_START) {
1400 start_cron();
1402 goto CLEAR;
1405 if (strcmp(service, "upgrade") == 0) {
1406 if (action & A_START) {
1407 #if TOMATO_SL
1408 stop_usbevent();
1409 stop_smbd();
1410 #endif
1411 stop_ftpd(); // !!TB - FTP Server
1412 stop_samba(); // !!TB - Samba
1413 stop_jffs2();
1414 // stop_cifs();
1415 stop_zebra();
1416 stop_cron();
1417 stop_ntpc();
1418 stop_upnp();
1419 // stop_dhcpc();
1420 killall("rstats", SIGTERM);
1421 killall("buttons", SIGTERM);
1422 stop_syslog();
1423 remove_storage_main(1); // !!TB - USB Support
1424 stop_usb(); // !!TB - USB Support
1426 goto CLEAR;
1429 #ifdef TCONFIG_CIFS
1430 if (strcmp(service, "cifs") == 0) {
1431 if (action & A_STOP) stop_cifs();
1432 if (action & A_START) start_cifs();
1433 goto CLEAR;
1435 #endif
1437 #ifdef TCONFIG_JFFS2
1438 if (strcmp(service, "jffs2") == 0) {
1439 if (action & A_STOP) stop_jffs2();
1440 if (action & A_START) start_jffs2();
1441 goto CLEAR;
1443 #endif
1445 if (strcmp(service, "routing") == 0) {
1446 if (action & A_STOP) {
1447 stop_zebra();
1448 do_static_routes(0); // remove old '_saved'
1449 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
1451 stop_firewall();
1452 start_firewall();
1453 if (action & A_START) {
1454 do_static_routes(1); // add new
1455 start_zebra();
1456 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
1458 goto CLEAR;
1461 if (strcmp(service, "ctnf") == 0) {
1462 if (action & A_START) {
1463 setup_conntrack();
1464 stop_firewall();
1465 start_firewall();
1467 goto CLEAR;
1470 if (strcmp(service, "wan") == 0) {
1471 if (action & A_STOP) {
1472 if (get_wan_proto() == WP_PPPOE) {
1473 stop_dnsmasq();
1474 stop_redial();
1475 stop_singe_pppoe(PPPOE0);
1476 if (((action & A_START) == 0) && (nvram_match("ppp_demand", "1"))) {
1477 sleep(1);
1478 start_pppoe(PPPOE0);
1480 start_dnsmasq();
1482 else {
1483 stop_wan();
1487 if (action & A_START) {
1488 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
1490 if (get_wan_proto() == WP_PPPOE) {
1491 stop_singe_pppoe(PPPOE0);
1492 start_pppoe(PPPOE0);
1493 if (nvram_invmatch("ppp_demand", "1")) {
1494 start_redial();
1497 else {
1498 start_wan(BOOT);
1500 sleep(2);
1501 force_to_dial();
1503 goto CLEAR;
1506 if (strcmp(service, "net") == 0) {
1507 if (action & A_STOP) {
1508 stop_wan();
1509 stop_lan();
1510 stop_vlan();
1512 if (action & A_START) {
1513 start_vlan();
1514 start_lan();
1515 start_wan(BOOT);
1517 goto CLEAR;
1520 if (strcmp(service, "rstats") == 0) {
1521 if (action & A_STOP) stop_rstats();
1522 if (action & A_START) start_rstats(0);
1523 goto CLEAR;
1526 if (strcmp(service, "rstatsnew") == 0) {
1527 if (action & A_STOP) stop_rstats();
1528 if (action & A_START) start_rstats(1);
1529 goto CLEAR;
1532 if (strcmp(service, "sched") == 0) {
1533 if (action & A_STOP) stop_sched();
1534 if (action & A_START) start_sched();
1535 goto CLEAR;
1538 #ifdef TCONFIG_USB
1539 // !!TB - USB Support
1540 if (strcmp(service, "usb") == 0) {
1541 if (action & A_STOP) stop_usb();
1542 if (action & A_START) {
1543 start_usb();
1544 // restart Samba and ftp since they may be killed by stop_usb()
1545 restart_nas_services(0, 1);
1547 goto CLEAR;
1549 #endif
1551 #ifdef TCONFIG_FTP
1552 // !!TB - FTP Server
1553 if (strcmp(service, "ftpd") == 0) {
1554 if (action & A_STOP) stop_ftpd();
1555 setup_conntrack();
1556 stop_firewall();
1557 start_firewall();
1558 if (action & A_START) start_ftpd();
1559 goto CLEAR;
1561 #endif
1563 #ifdef TCONFIG_SAMBASRV
1564 // !!TB - Samba
1565 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
1566 if (action & A_STOP) stop_samba();
1567 if (action & A_START) {
1568 create_passwd();
1569 stop_dnsmasq();
1570 start_dnsmasq();
1571 start_samba();
1573 goto CLEAR;
1575 #endif
1577 CLEAR:
1578 if (next) goto TOP;
1580 // some functions check action_service and must be cleared at end -- zzz
1581 nvram_set("action_service", "");
1584 static void do_service(const char *name, const char *action, int user)
1586 int n;
1587 char s[64];
1589 n = 15;
1590 while (!nvram_match("action_service", "")) {
1591 if (user) {
1592 putchar('*');
1593 fflush(stdout);
1595 else if (--n < 0) break;
1596 sleep(1);
1599 snprintf(s, sizeof(s), "%s-%s", name, action);
1600 nvram_set("action_service", s);
1601 kill(1, SIGUSR1);
1603 n = 15;
1604 while (nvram_match("action_service", s)) {
1605 if (user) {
1606 putchar('.');
1607 fflush(stdout);
1609 else if (--n < 0) {
1610 break;
1612 sleep(1);
1616 int service_main(int argc, char *argv[])
1618 if (argc != 3) usage_exit(argv[0], "<service> <action>");
1619 do_service(argv[1], argv[2], 1);
1620 printf("\nDone.\n");
1621 return 0;
1624 void start_service(const char *name)
1626 do_service(name, "start", 0);
1629 void stop_service(const char *name)
1631 do_service(name, "stop", 0);
1635 void restart_service(const char *name)
1637 do_service(name, "restart", 0);