Allow to compile with no USB support
[tomato.git] / release / src / router / rc / services.c
blob945064e1951a6ca324fbbfd5efd5b0adeb1db800
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 if (((nv = nvram_get("dns_minport")) != NULL) && (*nv)) n = atoi(nv);
109 else n = 4096;
110 fprintf(f,
111 "resolv-file=%s\n" // the real stuff is here
112 "addn-hosts=%s\n" // "
113 "expand-hosts\n" // expand hostnames in hosts file
114 "min-port=%u\n", // min port used for random src port
115 dmresolv, dmhosts, n);
116 do_dns = nvram_match("dhcpd_dmdns", "1");
119 // dhcp
120 do_dhcpd = nvram_match("lan_proto", "dhcp");
121 if (do_dhcpd) {
122 dhcp_lease = nvram_get_int("dhcp_lease");
123 if (dhcp_lease <= 0) dhcp_lease = 1440;
125 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
126 if (n < 0) strcpy(sdhcp_lease, "infinite");
127 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
129 if (!do_dns) {
130 // if not using dnsmasq for dns
132 const dns_list_t *dns = get_dns(); // this always points to a static buffer
133 if ((dns->count == 0) && (nvram_match("dhcpd_llndns", "1"))) {
134 // no DNS might be temporary. use a low lease time to force clients to update.
135 dhcp_lease = 2;
136 strcpy(sdhcp_lease, "2m");
137 do_dns = 1;
139 else {
140 // pass the dns directly
141 buf[0] = 0;
142 for (n = 0 ; n < dns->count; ++n) {
143 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n]));
145 fprintf(f, "dhcp-option=6%s\n", buf);
149 if ((p = nvram_get("dhcpd_startip")) && (*p) && (e = nvram_get("dhcpd_endip")) && (*e)) {
150 fprintf(f, "dhcp-range=%s,%s,%s,%dm\n", p, e, nvram_safe_get("lan_netmask"), dhcp_lease);
152 else {
153 // for compatibility
154 dhcp_start = nvram_get_int("dhcp_start");
155 dhcp_count = nvram_get_int("dhcp_num");
156 fprintf(f, "dhcp-range=%s%d,%s%d,%s,%dm\n",
157 lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get("lan_netmask"), dhcp_lease);
159 n = nvram_get_int("dhcpd_lmax");
160 fprintf(f,
161 "dhcp-option=3,%s\n" // gateway
162 "dhcp-lease-max=%d\n",
163 router_ip,
164 (n > 0) ? n : 255);
166 if (nvram_get_int("dhcpd_auth") >= 0) {
167 fprintf(f, "dhcp-authoritative\n");
170 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
171 fprintf(f, "dhcp-option=44,%s\n", nv);
174 else {
175 fprintf(f, "no-dhcp-interface=%s\n", lan_ifname);
178 // write static lease entries & create hosts file
180 if ((hf = fopen(dmhosts, "w")) != NULL) {
181 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
182 fprintf(hf, "%s %s\n", router_ip, nv);
183 #ifdef TCONFIG_SAMBASRV
184 else if (((nv = nvram_get("lan_hostname")) != NULL) && (*nv))
185 fprintf(hf, "%s %s\n", router_ip, nv);
186 #endif
189 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
190 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
191 p = nvram_safe_get("dhcpd_static");
192 while ((e = strchr(p, '>')) != NULL) {
193 n = (e - p);
194 if (n > 84) {
195 p = e + 1;
196 continue;
199 strncpy(buf, p, n);
200 buf[n] = 0;
201 p = e + 1;
203 if ((e = strchr(buf, '<')) == NULL) continue;
204 *e = 0;
205 mac = buf;
207 ip = e + 1;
208 if ((e = strchr(ip, '<')) == NULL) continue;
209 *e = 0;
210 if (strchr(ip, '.') == NULL) {
211 ipn = atoi(ip);
212 if ((ipn <= 0) || (ipn > 255)) continue;
213 sprintf(ipbuf, "%s%d", lan, ipn);
214 ip = ipbuf;
216 else {
217 if (inet_addr(ip) == INADDR_NONE) continue;
220 name = e + 1;
222 if ((hf) && (*name != 0)) {
223 fprintf(hf, "%s %s\n", ip, name);
226 if ((do_dhcpd) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
227 fprintf(f, "dhcp-host=%s,%s,%s\n", mac, ip, sdhcp_lease);
231 if (hf) fclose(hf);
235 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
237 fappend(f, "/etc/dnsmasq.custom");
241 fclose(f);
243 if (do_dns) {
244 unlink("/etc/resolv.conf");
245 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
248 TRACE_PT("run dnsmasq\n");
250 eval("dnsmasq");
252 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
253 f_read_string(dmpid, buf, sizeof(buf));
254 pid_dnsmasq = atol(buf);
257 TRACE_PT("end\n");
260 void stop_dnsmasq(void)
262 TRACE_PT("begin\n");
264 if (getpid() != 1) {
265 stop_service("dnsmasq");
266 return;
269 pid_dnsmasq = -1;
271 unlink("/etc/resolv.conf");
272 symlink(dmresolv, "/etc/resolv.conf");
274 killall_tk("dnsmasq");
276 TRACE_PT("end\n");
279 void clear_resolv(void)
281 _dprintf("%s\n", __FUNCTION__);
283 f_write(dmresolv, NULL, 0, 0, 0); // blank
286 void dns_to_resolv(void)
288 FILE *f;
289 const dns_list_t *dns;
290 int i;
291 mode_t m;
293 _dprintf("%s\n", __FUNCTION__);
295 m = umask(022); // 077 from pppoecd
296 if ((f = fopen(dmresolv, "w")) != NULL) {
297 dns = get_dns(); // static buffer
298 if (dns->count == 0) {
299 // Put a pseudo DNS IP to trigger Connect On Demand
300 if ((nvram_match("ppp_demand", "1")) &&
301 (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "pptp") || nvram_match("wan_proto", "l2tp"))) {
302 fprintf(f, "nameserver 1.1.1.1\n");
305 else {
306 for (i = 0; i < dns->count; i++) {
307 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i]));
310 fclose(f);
312 umask(m);
315 // -----------------------------------------------------------------------------
317 void start_httpd(void)
319 chdir("/www");
320 if (!nvram_match("http_enable", "0")) {
321 xstart("httpd");
323 if (!nvram_match("https_enable", "0")) {
324 xstart("httpd", "-s");
326 chdir("/");
329 void stop_httpd(void)
331 killall_tk("httpd");
334 // -----------------------------------------------------------------------------
336 void start_upnp(void)
338 if (get_wan_proto() == WP_DISABLED) return;
340 #ifdef USE_MINIUPNPD
341 int enable;
342 FILE *f;
343 int upnp_port;
345 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
346 mkdir("/etc/upnp", 0777);
347 if (f_exists("/etc/upnp/config.alt")) {
348 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
350 else {
351 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
352 upnp_port = nvram_get_int("upnp_port");
353 if ((upnp_port <= 0) || (upnp_port >= 0xFFFF)) upnp_port = 5000;
355 fprintf(f,
356 "ext_ifname=%s\n"
357 "listening_ip=%s\n"
358 "port=%d\n"
359 "enable_upnp=%s\n"
360 "enable_natpmp=%s\n"
361 "secure_mode=%s\n"
362 "upnp_forward_chain=upnp\n"
363 "upnp_nat_chain=upnp\n"
364 "system_uptime=yes\n"
365 "\n"
367 nvram_safe_get("wan_iface"),
368 nvram_safe_get("lan_ipaddr"),
369 upnp_port,
370 (enable & 1) ? "yes" : "no", // upnp enable
371 (enable & 2) ? "yes" : "no", // natpmp enable
372 nvram_get_int("upnp_secure") ? "yes" : "no" // secure_mode (only forward to self)
374 fappend(f, "/etc/upnp/config.custom");
375 fclose(f);
377 xstart("miniupnpd", "-f", "/etc/upnp/config");
381 #else
382 if (nvram_get_int("upnp_enable")) {
383 xstart("upnp",
384 "-D",
385 "-L", nvram_safe_get("lan_ifname"),
386 "-W", nvram_safe_get("wan_iface"),
387 "-I", nvram_safe_get("upnp_ssdp_interval"),
388 "-A", nvram_safe_get("upnp_max_age"));
390 #endif
393 void stop_upnp(void)
395 #ifdef USE_MINIUPNPD
396 killall_tk("miniupnpd");
397 #else
398 killall_tk("upnp");
399 #endif
402 // -----------------------------------------------------------------------------
404 static pid_t pid_crond = -1;
406 void start_cron(void)
408 char *argv[] = { "crond", "-l", "9", NULL };
410 stop_cron();
412 if (nvram_contains_word("log_events", "crond")) argv[1] = NULL;
413 _eval(argv, NULL, 0, NULL);
414 if (!nvram_contains_word("debug_norestart", "crond")) {
415 pid_crond = -2;
420 void stop_cron(void)
422 pid_crond = -1;
423 killall_tk("crond");
426 // -----------------------------------------------------------------------------
428 // Written by Sparq in 2002/07/16
429 void start_zebra(void)
431 #ifdef TCONFIG_ZEBRA
432 FILE *fp;
434 char *lan_tx = nvram_safe_get("dr_lan_tx");
435 char *lan_rx = nvram_safe_get("dr_lan_rx");
436 char *wan_tx = nvram_safe_get("dr_wan_tx");
437 char *wan_rx = nvram_safe_get("dr_wan_rx");
439 if ((*lan_tx == '0') && (*lan_rx == '0') && (*wan_tx == '0') && (*wan_rx == '0')) {
440 return;
443 // empty
444 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
445 fclose(fp);
449 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
450 char *lan_ifname = nvram_safe_get("lan_ifname");
451 char *wan_ifname = nvram_safe_get("wan_ifname");
453 fprintf(fp, "router rip\n");
454 fprintf(fp, "network %s\n", lan_ifname);
455 fprintf(fp, "network %s\n", wan_ifname);
456 fprintf(fp, "redistribute connected\n");
457 //fprintf(fp, "redistribute static\n");
459 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
460 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
462 fprintf(fp, "interface %s\n", lan_ifname);
463 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
464 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
466 fprintf(fp, "interface %s\n", wan_ifname);
467 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
468 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
470 fprintf(fp, "router rip\n");
471 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
472 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
473 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
474 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
475 fprintf(fp, "access-list private deny any\n");
477 //fprintf(fp, "debug rip events\n");
478 //fprintf(fp, "log file /etc/ripd.log\n");
479 fclose(fp);
482 xstart("zebra", "-d", "-f", "/etc/zebra.conf");
483 xstart("ripd", "-d", "-f", "/etc/ripd.conf");
484 #endif
487 void stop_zebra(void)
489 #ifdef TCONFIG_ZEBRA
490 killall("zebra", SIGTERM);
491 killall("ripd", SIGTERM);
493 unlink("/etc/zebra.conf");
494 unlink("/etc/ripd.conf");
495 #endif
498 // -----------------------------------------------------------------------------
500 void start_syslog(void)
502 #if 1
503 char *argv[12];
504 int argc;
505 char *nv;
506 char rem[256];
507 int n;
508 char s[64];
510 argv[0] = "syslogd";
511 argc = 1;
513 if (nvram_match("log_remote", "1")) {
514 nv = nvram_safe_get("log_remoteip");
515 if (*nv) {
516 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
517 argv[argc++] = "-R";
518 argv[argc++] = rem;
522 if (nvram_match("log_file", "1")) {
523 argv[argc++] = "-L";
524 argv[argc++] = "-s";
525 argv[argc++] = "50";
528 if (argc > 1) {
529 argv[argc] = NULL;
530 _eval(argv, NULL, 0, NULL);
531 usleep(500000);
533 argv[0] = "klogd";
534 argv[1] = NULL;
535 _eval(argv, NULL, 0, NULL);
536 usleep(500000);
538 // used to be available in syslogd -m
539 n = nvram_get_int("log_mark");
540 if (n > 0) {
541 sprintf(s, "cru a syslogdmark \"%s %s * * * logger -p syslog.info -- -- MARK --\"",
542 (n < 60) ? "*/30" : "0", (n < 120) ? "*" : "*/2");
543 system(s);
545 else {
546 system("cru d syslogdmark");
550 #else
551 char *argv[12];
552 int argc;
553 char *nv;
554 char rem[256];
556 argv[0] = "syslogd";
557 argv[1] = "-m";
558 argv[2] = nvram_get("log_mark");
559 argc = 3;
561 if (nvram_match("log_remote", "1")) {
562 nv = nvram_safe_get("log_remoteip");
563 if (*nv) {
564 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
565 argv[argc++] = "-R";
566 argv[argc++] = rem;
570 if (nvram_match("log_file", "1")) {
571 argv[argc++] = "-L";
572 argv[argc++] = "-s";
573 argv[argc++] = "50";
576 if (argc > 3) {
577 argv[argc] = NULL;
578 _eval(argv, NULL, 0, NULL);
579 usleep(500000);
581 argv[0] = "klogd";
582 argv[1] = NULL;
583 _eval(argv, NULL, 0, NULL);
584 usleep(500000);
586 #endif
589 void stop_syslog(void)
591 killall("klogd", SIGTERM);
592 killall("syslogd", SIGTERM);
595 // -----------------------------------------------------------------------------
597 static pid_t pid_igmp = -1;
599 void start_igmp_proxy(void)
601 static char *igmpproxy_conf = "/etc/igmpproxy.conf";
602 FILE *fp;
603 char *p;
605 pid_igmp = -1;
606 if (nvram_match("multicast_pass", "1")) {
607 switch (get_wan_proto()) {
608 case WP_PPPOE:
609 case WP_PPTP:
610 case WP_L2TP:
611 p = "wan_iface";
612 break;
613 default:
614 p = "wan_ifname";
615 break;
618 if ((fp = fopen(igmpproxy_conf, "w")) != NULL) {
619 fprintf(fp,
620 "quickleave\n"
621 "phyint %s upstream\n"
622 "\taltnet %s\n"
623 "phyint %s downstream ratelimit 0\n",
624 nvram_safe_get(p),
625 nvram_get("multicast_altnet") ? : "0.0.0.0/0",
626 nvram_safe_get("lan_ifname") ? : "br0");
627 fclose(fp);
628 xstart("igmpproxy", igmpproxy_conf);
630 if (!nvram_contains_word("debug_norestart", "igmprt")) {
631 pid_igmp = -2;
637 void stop_igmp_proxy(void)
639 pid_igmp = -1;
640 killall("igmpproxy", SIGTERM);
644 // -----------------------------------------------------------------------------
646 void set_tz(void)
648 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
651 void start_ntpc(void)
653 set_tz();
655 stop_ntpc();
657 if (nvram_get_int("ntp_updates") >= 0) {
658 xstart("ntpsync", "--init");
662 void stop_ntpc(void)
664 killall("ntpsync", SIGTERM);
667 // -----------------------------------------------------------------------------
669 static void stop_rstats(void)
671 int n;
672 int pid;
674 n = 60;
675 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
676 if (kill(pid, SIGTERM) != 0) break;
677 sleep(1);
681 static void start_rstats(int new)
683 if (nvram_match("rstats_enable", "1")) {
684 stop_rstats();
685 if (new) xstart("rstats", "--new");
686 else xstart("rstats");
690 // -----------------------------------------------------------------------------
692 // !!TB - FTP Server
694 #ifdef TCONFIG_USB
696 * Return non-zero if we created the directory,
697 * and zero if it already existed.
699 int mkdir_if_none(char *dir)
701 DIR *dp;
702 if (!(dp=opendir(dir))) {
703 umask(0000);
704 mkdir(dir, 0777);
705 return 1;
707 closedir(dp);
708 return 0;
711 char *get_full_storage_path(char *val)
713 static char buf[128];
714 int len;
716 if (val[0] == '/')
717 len = sprintf(buf, "%s", val);
718 else
719 len = sprintf(buf, "%s/%s", MOUNT_ROOT, val);
721 if (len > 1 && buf[len - 1] == '/')
722 buf[len - 1] = 0;
724 return buf;
727 char *nvram_storage_path(char *var)
729 char *val = nvram_safe_get(var);
730 return get_full_storage_path(val);
732 #endif // TCONFIG_USB
734 #ifdef TCONFIG_FTP
736 char vsftpd_conf[] = "/etc/vsftpd.conf";
737 char vsftpd_users[] = "/etc/vsftpd.users";
738 char vsftpd_passwd[] = "/etc/vsftpd.passwd";
739 #endif
741 #ifdef TCONFIG_FTP
742 /* VSFTPD code mostly stolen from Oleg's ASUS Custom Firmware GPL sources */
743 static void do_start_stop_ftpd(int stop, int start)
745 if (stop) killall("vsftpd", SIGTERM);
747 char tmp[256];
748 FILE *fp, *f;
750 if (!start || !nvram_get_int("ftp_enable")) return;
752 mkdir_if_none(vsftpd_users);
753 mkdir_if_none("/var/run/vsftpd");
755 if ((fp = fopen(vsftpd_conf, "w")) == NULL)
756 return;
758 if (nvram_get_int("ftp_super"))
760 /* rights */
761 sprintf(tmp, "%s/%s", vsftpd_users, "admin");
762 if ((f = fopen(tmp, "w")))
764 fprintf(f,
765 "dirlist_enable=yes\n"
766 "write_enable=yes\n"
767 "download_enable=yes\n");
768 fclose(f);
772 #ifdef TCONFIG_SAMBASRV
773 if (nvram_match("smbd_cset", "utf8"))
774 fprintf(fp, "utf8=yes\n");
775 #endif
777 if (nvram_invmatch("ftp_anonymous", "0"))
779 fprintf(fp,
780 "anon_allow_writable_root=yes\n"
781 "anon_world_readable_only=no\n"
782 "anon_umask=022\n");
784 /* rights */
785 sprintf(tmp, "%s/ftp", vsftpd_users);
786 if ((f = fopen(tmp, "w")))
788 if (nvram_match("ftp_dirlist", "0"))
789 fprintf(f, "dirlist_enable=yes\n");
790 if (nvram_match("ftp_anonymous", "1") ||
791 nvram_match("ftp_anonymous", "3"))
792 fprintf(f, "write_enable=yes\n");
793 if (nvram_match("ftp_anonymous", "1") ||
794 nvram_match("ftp_anonymous", "2"))
795 fprintf(f, "download_enable=yes\n");
796 fclose(f);
798 if (nvram_match("ftp_anonymous", "1") ||
799 nvram_match("ftp_anonymous", "3"))
800 fprintf(fp,
801 "anon_upload_enable=yes\n"
802 "anon_mkdir_write_enable=yes\n"
803 "anon_other_write_enable=yes\n");
804 } else {
805 fprintf(fp, "anonymous_enable=no\n");
808 fprintf(fp,
809 "dirmessage_enable=yes\n"
810 "download_enable=no\n"
811 "dirlist_enable=no\n"
812 "hide_ids=yes\n"
813 "syslog_enable=yes\n"
814 "local_enable=yes\n"
815 "local_umask=022\n"
816 "chmod_enable=no\n"
817 "chroot_local_user=yes\n"
818 "check_shell=no\n"
819 "log_ftp_protocol=%s\n"
820 "user_config_dir=%s\n"
821 "passwd_file=%s\n"
822 "listen=yes\n"
823 "listen_port=%s\n"
824 "background=yes\n"
825 "max_clients=%d\n"
826 "max_per_ip=%d\n"
827 "idle_session_timeout=%s\n"
828 "use_sendfile=no\n"
829 "anon_max_rate=%d\n"
830 "local_max_rate=%d\n"
831 "%s\n",
832 nvram_get_int("log_ftp") ? "yes" : "no",
833 vsftpd_users, vsftpd_passwd,
834 nvram_get("ftp_port") ? : "21",
835 nvram_get_int("ftp_max"),
836 nvram_get_int("ftp_ipmax"),
837 nvram_get("ftp_staytimeout") ? : "300",
838 nvram_get_int("ftp_anonrate") * 1024,
839 nvram_get_int("ftp_rate") * 1024,
840 nvram_safe_get("ftp_custom"));
842 fclose(fp);
844 /* prepare passwd file and default users */
845 if ((fp = fopen(vsftpd_passwd, "w")) == NULL)
846 return;
848 fprintf(fp, /* anonymous, admin, nobody */
849 "ftp:x:0:0:ftp:%s:/sbin/nologin\n"
850 "%s:%s:0:0:root:/:/sbin/nologin\n"
851 "nobody:x:65534:65534:nobody:%s/:/sbin/nologin\n",
852 nvram_storage_path("ftp_anonroot"), "admin",
853 nvram_get_int("ftp_super") ? crypt(nvram_safe_get("http_passwd"), "$1$") : "x",
854 MOUNT_ROOT);
856 char *buf;
857 char *p, *q;
858 char *user, *pass, *rights;
860 if ((buf = strdup(nvram_safe_get("ftp_users"))) != NULL)
863 username<password<rights
864 rights:
865 Read/Write
866 Read Only
867 View Only
868 Private
870 p = buf;
871 while ((q = strsep(&p, ">")) != NULL) {
872 if (vstrsep(q, "<", &user, &pass, &rights) != 3) continue;
873 if (!user || !pass) continue;
875 /* directory */
876 if (strncmp(rights, "Private", 7) == 0)
878 sprintf(tmp, "%s/%s", nvram_storage_path("ftp_pvtroot"), user);
879 mkdir_if_none(tmp);
881 else
882 sprintf(tmp, "%s", nvram_storage_path("ftp_pubroot"));
884 fprintf(fp, "%s:%s:0:0:%s:%s:/sbin/nologin\n",
885 user, crypt(pass, "$1$"), user, tmp);
887 /* rights */
888 sprintf(tmp, "%s/%s", vsftpd_users, user);
889 if ((f = fopen(tmp, "w")))
891 tmp[0] = 0;
892 if (nvram_invmatch("ftp_dirlist", "1"))
893 strcat(tmp, "dirlist_enable=yes\n");
894 if (strstr(rights, "Read") || !strcmp(rights, "Private"))
895 strcat(tmp, "download_enable=yes\n");
896 if (strstr(rights, "Write") || !strncmp(rights, "Private", 7))
897 strcat(tmp, "write_enable=yes\n");
899 fputs(tmp, f);
900 fclose(f);
903 free(buf);
906 fclose(fp);
907 killall("vsftpd", SIGHUP);
909 /* start vsftpd if it's not already running */
910 if (pidof("vsftpd") <= 0)
911 eval("vsftpd");
913 #endif
915 void start_ftpd(void)
917 #ifdef TCONFIG_FTP
918 int fd = file_lock("usb");
919 do_start_stop_ftpd(0, 1);
920 file_unlock(fd);
921 #endif
924 void stop_ftpd(void)
926 #ifdef TCONFIG_FTP
927 int fd = file_lock("usb");
928 do_start_stop_ftpd(1, 0);
929 unlink(vsftpd_passwd);
930 unlink(vsftpd_conf);
931 eval("rm", "-rf", vsftpd_users);
932 file_unlock(fd);
933 #endif
936 // -----------------------------------------------------------------------------
938 // !!TB - Samba
940 #ifdef TCONFIG_SAMBASRV
941 void kill_samba(int sig)
943 killall("smbd", sig);
944 killall("nmbd", sig);
946 #endif
948 #ifdef TCONFIG_SAMBASRV
949 static void do_start_stop_samba(int stop, int start)
951 if (stop) kill_samba(SIGTERM);
953 FILE *fp;
954 DIR *dir = NULL;
955 struct dirent *dp;
956 char nlsmod[15];
957 int mode;
959 mode = nvram_get_int("smbd_enable");
960 if (!start || !mode || !nvram_invmatch("lan_hostname", ""))
961 return;
963 if ((fp = fopen("/etc/smb.conf", "w")) == NULL)
964 return;
966 fprintf(fp, "[global]\n"
967 " interfaces = %s\n"
968 " bind interfaces only = yes\n"
969 " workgroup = %s\n"
970 " server string = %s\n"
971 " guest account = nobody\n"
972 " security = %s\n"
973 " browseable = yes\n"
974 " guest ok = yes\n"
975 " guest only = no\n"
976 " log level = %d\n"
977 " syslog only = yes\n"
978 " syslog = 1\n"
979 " encrypt passwords = yes\n"
980 " preserve case = yes\n"
981 " short preserve case = yes\n",
982 nvram_safe_get("lan_ifname"),
983 nvram_get("smbd_wgroup") ? : "WORKGROUP",
984 nvram_get("router_name") ? : "Tomato",
985 mode == 2 ? "user" : "share",
986 nvram_get_int("smbd_loglevel")
989 if (nvram_invmatch("smbd_master", "")) {
990 char *master = nvram_get_int("smbd_master") ? "yes" : "no";
991 fprintf(fp,
992 " local master = %s\n"
993 " preferred master = %s\n",
994 master, master);
997 if (nvram_invmatch("smbd_cpage", "")) {
998 char *cp = nvram_safe_get("smbd_cpage");
1000 fprintf(fp, " client code page = %s\n", cp);
1001 sprintf(nlsmod, "nls_cp%s", cp);
1003 cp = nvram_get("smbd_nlsmod");
1004 if ((cp) && (*cp != 0) && (strcmp(cp, nlsmod) != 0))
1005 modprobe_r(cp);
1007 modprobe(nlsmod);
1008 nvram_set("smbd_nlsmod", nlsmod);
1011 if (nvram_match("smbd_cset", "utf8"))
1012 fprintf(fp, " coding system = utf8\n");
1013 else if (nvram_invmatch("smbd_cset", ""))
1014 fprintf(fp, " character set = %s\n", nvram_safe_get("smbd_cset"));
1016 fprintf(fp, "%s\n\n", nvram_safe_get("smbd_custom"));
1018 /* configure shares */
1020 char *buf;
1021 char *p, *q;
1022 char *name, *path, *comment, *writeable, *hidden;
1023 int cnt = 0;
1025 if ((buf = strdup(nvram_safe_get("smbd_shares"))) != NULL)
1027 /* sharename<path<comment<writeable[0|1]<hidden[0|1] */
1029 p = buf;
1030 while ((q = strsep(&p, ">")) != NULL) {
1031 if (vstrsep(q, "<", &name, &path, &comment, &writeable, &hidden) != 5) continue;
1032 if (!path || !name) continue;
1034 /* share name */
1035 fprintf(fp, "\n[%s]\n", name);
1037 /* path */
1038 fprintf(fp, " path = %s\n", path);
1040 /* access level */
1041 if (!strcmp(writeable, "1"))
1042 fprintf(fp, " writable = yes\n force user = %s\n", "root");
1043 if (!strcmp(hidden, "1"))
1044 fprintf(fp, " browseable = no\n");
1046 /* comment */
1047 if (comment)
1048 fprintf(fp, " comment = %s\n", comment);
1050 cnt++;
1052 free(buf);
1055 /* share everything below MOUNT_ROOT */
1056 if (nvram_get_int("smbd_autoshare") && (dir = opendir(MOUNT_ROOT))) {
1057 while ((dp = readdir(dir))) {
1058 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
1060 /* smbd_autoshare: 0 - disable, 1 - read-only, 2 - writable, 3 - hidden writable */
1061 fprintf(fp, "\n[%s]\n path = %s/%s\n comment = %s\n",
1062 dp->d_name, MOUNT_ROOT, dp->d_name, dp->d_name);
1063 if (nvram_match("smbd_autoshare", "3")) // Hidden
1064 fprintf(fp, "\n[%s$]\n path = %s/%s\n browseable = no\n",
1065 dp->d_name, MOUNT_ROOT, dp->d_name);
1066 if (nvram_match("smbd_autoshare", "2") || nvram_match("smbd_autoshare", "3")) // RW
1067 fprintf(fp, " writable = yes\n force user = %s\n", "root");
1069 cnt++;
1073 if (dir) closedir(dir);
1075 if (cnt == 0) {
1076 /* by default share MOUNT_ROOT as read-only */
1077 fprintf(fp, "\n[share]\n"
1078 " path = %s\n"
1079 " writable = no\n",
1080 MOUNT_ROOT);
1083 fclose(fp);
1085 mkdir_if_none("/var/run/samba");
1086 mkdir_if_none("/etc/samba");
1088 /* write smbpasswd */
1089 eval("smbpasswd", "-a", "nobody", "\"\"");
1090 if (mode == 2) {
1091 char *smbd_user;
1092 if (((smbd_user = nvram_get("smbd_user")) == NULL) || (*smbd_user == 0) || !strcmp(smbd_user, "root"))
1093 smbd_user = "nas";
1094 eval("smbpasswd", "-a", smbd_user, nvram_safe_get("smbd_passwd"));
1097 kill_samba(SIGHUP);
1098 int ret1 = 0, ret2 = 0;
1099 /* start samba if it's not already running */
1100 if (pidof("nmbd") <= 0)
1101 ret1 = eval("nmbd", "-D");
1102 if (pidof("smbd") <= 0)
1103 ret2 = eval("smbd", "-D");
1105 if (ret1 || ret2) kill_samba(SIGTERM);
1107 #endif
1109 void start_samba(void)
1111 #ifdef TCONFIG_SAMBASRV
1112 int fd = file_lock("usb");
1113 do_start_stop_samba(0, 1);
1114 file_unlock(fd);
1115 #endif
1118 void stop_samba(void)
1120 #ifdef TCONFIG_SAMBASRV
1121 int fd = file_lock("usb");
1122 do_start_stop_samba(1, 0);
1123 sleep(2); /* wait for smbd to finish */
1125 if (nvram_invmatch("smbd_nlsmod", "")) {
1126 modprobe_r(nvram_get("smbd_nlsmod"));
1127 nvram_set("smbd_nlsmod", "");
1130 /* clean up */
1131 unlink("/var/log/smb");
1132 unlink("/var/log/nmb");
1133 eval("rm", "-rf", "/var/run/samba");
1134 file_unlock(fd);
1135 #endif
1138 #ifdef TCONFIG_USB
1139 void restart_nas_services(int start)
1141 /* restart all NAS applications */
1142 #if TCONFIG_SAMBASRV || TCONFIG_FTP
1143 int fd = file_lock("usb");
1144 #ifdef TCONFIG_SAMBASRV
1145 if (start && nvram_get_int("smbd_enable"))
1146 do_start_stop_samba(0, 1);
1147 else
1148 do_start_stop_samba(1, 0);
1149 #endif
1150 #ifdef TCONFIG_FTP
1151 if (start && nvram_get_int("ftp_enable"))
1152 do_start_stop_ftpd(0, 1);
1153 else
1154 do_start_stop_ftpd(1, 0);
1155 #endif
1156 file_unlock(fd);
1157 #endif // TCONFIG_SAMBASRV || TCONFIG_FTP
1159 #endif // TCONFIG_USB
1161 // -----------------------------------------------------------------------------
1163 static void _check(pid_t *pid, const char *name, void (*func)(void) )
1165 if (*pid != -1) {
1166 if (kill(*pid, 0) != 0) {
1167 if ((*pid = pidof(name)) == -1) func();
1172 void check_services(void)
1174 _check(&pid_dnsmasq, "dnsmasq", start_dnsmasq);
1175 _check(&pid_crond, "crond", start_cron);
1176 _check(&pid_igmp, "igmpproxy", start_igmp_proxy);
1179 // -----------------------------------------------------------------------------
1181 void start_services(void)
1183 static int once = 1;
1185 if (once) {
1186 once = 0;
1188 create_passwd();
1189 if (nvram_get_int("telnetd_eas")) start_telnetd();
1190 if (nvram_get_int("sshd_eas")) start_sshd();
1193 start_syslog();
1194 #if TOMATO_SL
1195 start_usbevent();
1196 #endif
1197 start_nas();
1198 start_zebra();
1199 start_dnsmasq();
1200 start_cifs();
1201 start_httpd();
1202 start_cron();
1203 start_upnp();
1204 start_rstats(0);
1205 start_sched();
1206 #ifdef TCONFIG_SAMBA
1207 start_smbd();
1208 #endif
1209 start_samba(); // !!TB - Samba
1210 start_ftpd(); // !!TB - FTP Server
1213 void stop_services(void)
1215 clear_resolv();
1217 stop_ftpd(); // !!TB - FTP Server
1218 stop_samba(); // !!TB - Samba
1219 #ifdef TCONFIG_SAMBA
1220 stop_smbd();
1221 #endif
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 #if TOMATO_SL
1232 stop_usbevent();
1233 #endif
1234 stop_syslog();
1237 // -----------------------------------------------------------------------------
1239 void exec_service(void)
1241 const int A_START = 1;
1242 const int A_STOP = 2;
1243 const int A_RESTART = 1|2;
1244 char buffer[128];
1245 char *service;
1246 char *act;
1247 char *next;
1248 int action;
1249 int i;
1251 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
1252 next = buffer;
1254 TOP:
1255 act = strsep(&next, ",");
1256 service = strsep(&act, "-");
1257 if (act == NULL) {
1258 next = NULL;
1259 goto CLEAR;
1262 TRACE_PT("service=%s action=%s\n", service, act);
1264 if (strcmp(act, "start") == 0) action = A_START;
1265 else if (strcmp(act, "stop") == 0) action = A_STOP;
1266 else if (strcmp(act, "restart") == 0) action = A_RESTART;
1267 else action = 0;
1270 if (strcmp(service, "dhcpc") == 0) {
1271 if (action & A_STOP) stop_dhcpc();
1272 if (action & A_START) start_dhcpc();
1273 goto CLEAR;
1276 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
1277 if (action & A_STOP) stop_dnsmasq();
1278 if (action & A_START) {
1279 dns_to_resolv();
1280 start_dnsmasq();
1282 goto CLEAR;
1285 if (strcmp(service, "firewall") == 0) {
1286 if (action & A_STOP) {
1287 stop_firewall();
1288 stop_igmp_proxy();
1290 if (action & A_START) {
1291 start_firewall();
1292 start_igmp_proxy();
1294 goto CLEAR;
1297 if (strcmp(service, "restrict") == 0) {
1298 if (action & A_STOP) {
1299 stop_firewall();
1301 if (action & A_START) {
1302 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
1304 start_firewall();
1306 // if radio was disabled by access restriction, but no rule is handling it now, enable it
1307 if (i == 1) {
1308 if (nvram_get_int("rrules_radio") < 0) {
1309 if (!get_radio()) eval("radio", "on");
1313 goto CLEAR;
1316 if (strcmp(service, "qos") == 0) {
1317 if (action & A_STOP) {
1318 stop_qos();
1320 stop_firewall(); start_firewall(); // always restarted
1321 if (action & A_START) {
1322 start_qos();
1323 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
1325 goto CLEAR;
1328 if (strcmp(service, "upnp") == 0) {
1329 if (action & A_STOP) {
1330 stop_upnp();
1332 stop_firewall(); start_firewall(); // always restarted
1333 if (action & A_START) {
1334 start_upnp();
1336 goto CLEAR;
1339 if (strcmp(service, "telnetd") == 0) {
1340 if (action & A_STOP) stop_telnetd();
1341 if (action & A_START) start_telnetd();
1342 goto CLEAR;
1345 if (strcmp(service, "sshd") == 0) {
1346 if (action & A_STOP) stop_sshd();
1347 if (action & A_START) start_sshd();
1348 goto CLEAR;
1351 if (strcmp(service, "httpd") == 0) {
1352 if (action & A_STOP) stop_httpd();
1353 if (action & A_START) start_httpd();
1354 goto CLEAR;
1357 if (strcmp(service, "admin") == 0) {
1358 if (action & A_STOP) {
1359 stop_sshd();
1360 stop_telnetd();
1361 stop_httpd();
1363 stop_firewall(); start_firewall(); // always restarted
1364 if (action & A_START) {
1365 start_httpd();
1366 create_passwd();
1367 if (nvram_match("telnetd_eas", "1")) start_telnetd();
1368 if (nvram_match("sshd_eas", "1")) start_sshd();
1370 goto CLEAR;
1373 if (strcmp(service, "ddns") == 0) {
1374 if (action & A_STOP) stop_ddns();
1375 if (action & A_START) start_ddns();
1376 goto CLEAR;
1379 if (strcmp(service, "ntpc") == 0) {
1380 if (action & A_STOP) stop_ntpc();
1381 if (action & A_START) start_ntpc();
1382 goto CLEAR;
1385 if (strcmp(service, "logging") == 0) {
1386 if (action & A_STOP) {
1387 stop_syslog();
1388 stop_cron();
1390 stop_firewall(); start_firewall(); // always restarted
1391 if (action & A_START) {
1392 start_cron();
1393 start_syslog();
1395 goto CLEAR;
1398 if (strcmp(service, "crond") == 0) {
1399 if (action & A_STOP) {
1400 stop_cron();
1402 if (action & A_START) {
1403 start_cron();
1405 goto CLEAR;
1408 if (strcmp(service, "upgrade") == 0) {
1409 if (action & A_START) {
1410 #if TOMATO_SL
1411 stop_usbevent();
1412 stop_smbd();
1413 #endif
1414 stop_ftpd(); // !!TB - FTP Server
1415 stop_samba(); // !!TB - Samba
1416 stop_jffs2();
1417 // stop_cifs();
1418 stop_zebra();
1419 stop_cron();
1420 stop_ntpc();
1421 stop_upnp();
1422 // stop_dhcpc();
1423 killall("rstats", SIGTERM);
1424 killall("buttons", SIGTERM);
1425 stop_syslog();
1426 remove_storage_main(); // !!TB - USB Support
1427 stop_usb(); // !!TB - USB Support
1429 goto CLEAR;
1432 #ifdef TCONFIG_CIFS
1433 if (strcmp(service, "cifs") == 0) {
1434 if (action & A_STOP) stop_cifs();
1435 if (action & A_START) start_cifs();
1436 goto CLEAR;
1438 #endif
1440 #ifdef TCONFIG_JFFS2
1441 if (strcmp(service, "jffs2") == 0) {
1442 if (action & A_STOP) stop_jffs2();
1443 if (action & A_START) start_jffs2();
1444 goto CLEAR;
1446 #endif
1448 if (strcmp(service, "routing") == 0) {
1449 if (action & A_STOP) {
1450 stop_zebra();
1451 do_static_routes(0); // remove old '_saved'
1452 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
1454 stop_firewall();
1455 start_firewall();
1456 if (action & A_START) {
1457 do_static_routes(1); // add new
1458 start_zebra();
1459 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
1461 goto CLEAR;
1464 if (strcmp(service, "ctnf") == 0) {
1465 if (action & A_START) {
1466 setup_conntrack();
1467 stop_firewall();
1468 start_firewall();
1470 goto CLEAR;
1473 if (strcmp(service, "wan") == 0) {
1474 if (action & A_STOP) {
1475 if (get_wan_proto() == WP_PPPOE) {
1476 stop_dnsmasq();
1477 stop_redial();
1478 stop_singe_pppoe(PPPOE0);
1479 if (((action & A_START) == 0) && (nvram_match("ppp_demand", "1"))) {
1480 sleep(1);
1481 start_pppoe(PPPOE0);
1483 start_dnsmasq();
1485 else {
1486 stop_wan();
1490 if (action & A_START) {
1491 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
1493 if (get_wan_proto() == WP_PPPOE) {
1494 stop_singe_pppoe(PPPOE0);
1495 start_pppoe(PPPOE0);
1496 if (nvram_invmatch("ppp_demand", "1")) {
1497 start_redial();
1500 else {
1501 start_wan(BOOT);
1503 sleep(2);
1504 force_to_dial();
1506 goto CLEAR;
1509 if (strcmp(service, "net") == 0) {
1510 if (action & A_STOP) {
1511 stop_wan();
1512 stop_lan();
1513 stop_vlan();
1515 if (action & A_START) {
1516 start_vlan();
1517 start_lan();
1518 start_wan(BOOT);
1520 goto CLEAR;
1523 if (strcmp(service, "rstats") == 0) {
1524 if (action & A_STOP) stop_rstats();
1525 if (action & A_START) start_rstats(0);
1526 goto CLEAR;
1529 if (strcmp(service, "rstatsnew") == 0) {
1530 if (action & A_STOP) stop_rstats();
1531 if (action & A_START) start_rstats(1);
1532 goto CLEAR;
1535 if (strcmp(service, "sched") == 0) {
1536 if (action & A_STOP) stop_sched();
1537 if (action & A_START) start_sched();
1538 goto CLEAR;
1541 #ifdef TCONFIG_USB
1542 // !!TB - USB Support
1543 if (strcmp(service, "usb") == 0) {
1544 if (action & A_STOP) stop_usb();
1545 if (action & A_START) {
1546 start_usb();
1547 // restart Samba and ftp since they may be killed by stop_usb()
1548 restart_nas_services(1);
1550 goto CLEAR;
1552 #endif
1554 #ifdef TCONFIG_FTP
1555 // !!TB - FTP Server
1556 if (strcmp(service, "ftpd") == 0) {
1557 if (action & A_STOP) stop_ftpd();
1558 setup_conntrack();
1559 stop_firewall();
1560 start_firewall();
1561 if (action & A_START) start_ftpd();
1562 goto CLEAR;
1564 #endif
1566 #ifdef TCONFIG_SAMBASRV
1567 // !!TB - Samba
1568 if (strcmp(service, "samba") == 0 || strcmp(service, "smbd") == 0) {
1569 if (action & A_STOP) stop_samba();
1570 if (action & A_START) {
1571 create_passwd();
1572 start_samba();
1574 goto CLEAR;
1576 #endif
1578 CLEAR:
1579 if (next) goto TOP;
1581 // some functions check action_service and must be cleared at end -- zzz
1582 nvram_set("action_service", "");
1585 static void do_service(const char *name, const char *action, int user)
1587 int n;
1588 char s[64];
1590 n = 15;
1591 while (!nvram_match("action_service", "")) {
1592 if (user) {
1593 putchar('*');
1594 fflush(stdout);
1596 else if (--n < 0) break;
1597 sleep(1);
1600 snprintf(s, sizeof(s), "%s-%s", name, action);
1601 nvram_set("action_service", s);
1602 kill(1, SIGUSR1);
1604 n = 15;
1605 while (nvram_match("action_service", s)) {
1606 if (user) {
1607 putchar('.');
1608 fflush(stdout);
1610 else if (--n < 0) {
1611 break;
1613 sleep(1);
1617 int service_main(int argc, char *argv[])
1619 if (argc != 3) usage_exit(argv[0], "<service> <action>");
1620 do_service(argv[1], argv[2], 1);
1621 printf("\nDone.\n");
1622 return 0;
1625 void start_service(const char *name)
1627 do_service(name, "start", 0);
1630 void stop_service(const char *name)
1632 do_service(name, "stop", 0);
1636 void restart_service(const char *name)
1638 do_service(name, "restart", 0);