Tomato 1.25
[tomato.git] / release / src / router / rc / services.c
blobeab948f88aba17fadd09dc89d989411582114c55
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
37 #include "rc.h"
39 #include <arpa/inet.h>
40 #include <time.h>
41 #include <sys/time.h>
42 #include <errno.h>
44 #define IFUP (IFF_UP | IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST)
45 #define sin_addr(s) (((struct sockaddr_in *)(s))->sin_addr)
50 // -----------------------------------------------------------------------------
52 static const char dmhosts[] = "/etc/hosts.dnsmasq";
53 static const char dmresolv[] = "/etc/resolv.dnsmasq";
54 static const char dmpid[] = "/var/run/dnsmasq.pid";
56 static pid_t pid_dnsmasq = -1;
59 void start_dnsmasq()
61 FILE *f;
62 const char *nv;
63 char buf[512];
64 char lan[24];
65 const char *router_ip;
66 const char *lan_ifname;
67 char sdhcp_lease[32];
68 char *e;
69 int n;
70 char *mac, *ip, *name;
71 char *p;
72 int ipn;
73 char ipbuf[32];
74 FILE *hf;
75 int dhcp_start;
76 int dhcp_count;
77 int dhcp_lease;
78 int do_dhcpd;
79 int do_dns;
81 TRACE_PT("begin\n");
83 if (getpid() != 1) {
84 start_service("dnsmasq");
85 return;
88 stop_dnsmasq();
90 if (nvram_match("wl_mode", "wet")) return;
91 if ((f = fopen("/etc/dnsmasq.conf", "w")) == NULL) return;
93 lan_ifname = nvram_safe_get("lan_ifname");
94 router_ip = nvram_safe_get("lan_ipaddr");
95 strlcpy(lan, router_ip, sizeof(lan));
96 if ((p = strrchr(lan, '.')) != NULL) *(p + 1) = 0;
98 fprintf(f,
99 "pid-file=%s\n"
100 "interface=%s\n",
101 dmpid, lan_ifname);
102 if (((nv = nvram_get("wan_domain")) != NULL) || ((nv = nvram_get("wan_get_domain")) != NULL)) {
103 if (*nv) fprintf(f, "domain=%s\n", nv);
106 // dns
107 if (((nv = nvram_get("dns_minport")) != NULL) && (*nv)) n = atoi(nv);
108 else n = 4096;
109 fprintf(f,
110 "resolv-file=%s\n" // the real stuff is here
111 "addn-hosts=%s\n" // "
112 "expand-hosts\n" // expand hostnames in hosts file
113 "min-port=%u\n", // min port used for random src port
114 dmresolv, dmhosts, n);
115 do_dns = nvram_match("dhcpd_dmdns", "1");
118 // dhcp
119 do_dhcpd = nvram_match("lan_proto", "dhcp");
120 if (do_dhcpd) {
121 dhcp_lease = nvram_get_int("dhcp_lease");
122 if (dhcp_lease <= 0) dhcp_lease = 1440;
124 if ((e = nvram_get("dhcpd_slt")) != NULL) n = atoi(e); else n = 0;
125 if (n < 0) strcpy(sdhcp_lease, "infinite");
126 else sprintf(sdhcp_lease, "%dm", (n > 0) ? n : dhcp_lease);
128 if (!do_dns) {
129 // if not using dnsmasq for dns
131 const dns_list_t *dns = get_dns(); // this always points to a static buffer
132 if ((dns->count == 0) && (nvram_match("dhcpd_llndns", "1"))) {
133 // no DNS might be temporary. use a low lease time to force clients to update.
134 dhcp_lease = 2;
135 strcpy(sdhcp_lease, "2m");
136 do_dns = 1;
138 else {
139 // pass the dns directly
140 buf[0] = 0;
141 for (n = 0 ; n < dns->count; ++n) {
142 sprintf(buf + strlen(buf), ",%s", inet_ntoa(dns->dns[n]));
144 fprintf(f, "dhcp-option=6%s\n", buf);
148 if ((p = nvram_get("dhcpd_startip")) && (*p) && (e = nvram_get("dhcpd_endip")) && (*e)) {
149 fprintf(f, "dhcp-range=%s,%s,%s,%dm\n", p, e, nvram_safe_get("lan_netmask"), dhcp_lease);
151 else {
152 // for compatibility
153 dhcp_start = nvram_get_int("dhcp_start");
154 dhcp_count = nvram_get_int("dhcp_num");
155 fprintf(f, "dhcp-range=%s%d,%s%d,%s,%dm\n",
156 lan, dhcp_start, lan, dhcp_start + dhcp_count - 1, nvram_safe_get("lan_netmask"), dhcp_lease);
158 n = nvram_get_int("dhcpd_lmax");
159 fprintf(f,
160 "dhcp-option=3,%s\n" // gateway
161 "dhcp-lease-max=%d\n",
162 router_ip,
163 (n > 0) ? n : 255);
165 if (nvram_get_int("dhcpd_auth") >= 0) {
166 fprintf(f, "dhcp-authoritative\n");
169 if (((nv = nvram_get("wan_wins")) != NULL) && (*nv) && (strcmp(nv, "0.0.0.0") != 0)) {
170 fprintf(f, "dhcp-option=44,%s\n", nv);
173 else {
174 fprintf(f, "no-dhcp-interface=%s\n", lan_ifname);
177 // write static lease entries & create hosts file
179 if ((hf = fopen(dmhosts, "w")) != NULL) {
180 if (((nv = nvram_get("wan_hostname")) != NULL) && (*nv))
181 fprintf(hf, "%s %s\n", router_ip, nv);
184 // 00:aa:bb:cc:dd:ee<123<xxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 53 w/ delim
185 // 00:aa:bb:cc:dd:ee<123.123.123.123<xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xyz> = 85 w/ delim
186 p = nvram_safe_get("dhcpd_static");
187 while ((e = strchr(p, '>')) != NULL) {
188 n = (e - p);
189 if (n > 84) {
190 p = e + 1;
191 continue;
194 strncpy(buf, p, n);
195 buf[n] = 0;
196 p = e + 1;
198 if ((e = strchr(buf, '<')) == NULL) continue;
199 *e = 0;
200 mac = buf;
202 ip = e + 1;
203 if ((e = strchr(ip, '<')) == NULL) continue;
204 *e = 0;
205 if (strchr(ip, '.') == NULL) {
206 ipn = atoi(ip);
207 if ((ipn <= 0) || (ipn > 255)) continue;
208 sprintf(ipbuf, "%s%d", lan, ipn);
209 ip = ipbuf;
211 else {
212 if (inet_addr(ip) == INADDR_NONE) continue;
215 name = e + 1;
217 if ((hf) && (*name != 0)) {
218 fprintf(hf, "%s %s\n", ip, name);
221 if ((do_dhcpd) && (*mac != 0) && (strcmp(mac, "00:00:00:00:00:00") != 0)) {
222 fprintf(f, "dhcp-host=%s,%s,%s\n", mac, ip, sdhcp_lease);
226 if (hf) fclose(hf);
230 fprintf(f, "%s\n\n", nvram_safe_get("dnsmasq_custom"));
232 fappend(f, "/etc/dnsmasq.custom");
236 fclose(f);
238 if (do_dns) {
239 unlink("/etc/resolv.conf");
240 symlink("/rom/etc/resolv.conf", "/etc/resolv.conf"); // nameserver 127.0.0.1
243 TRACE_PT("run dnsmasq\n");
245 eval("dnsmasq");
247 if (!nvram_contains_word("debug_norestart", "dnsmasq")) {
248 f_read_string(dmpid, buf, sizeof(buf));
249 pid_dnsmasq = atol(buf);
252 TRACE_PT("end\n");
255 void stop_dnsmasq(void)
257 TRACE_PT("begin\n");
259 if (getpid() != 1) {
260 stop_service("dnsmasq");
261 return;
264 pid_dnsmasq = -1;
266 unlink("/etc/resolv.conf");
267 symlink(dmresolv, "/etc/resolv.conf");
269 killall_tk("dnsmasq");
271 TRACE_PT("end\n");
274 void clear_resolv(void)
276 _dprintf("%s\n", __FUNCTION__);
278 f_write(dmresolv, NULL, 0, 0, 0); // blank
281 void dns_to_resolv(void)
283 FILE *f;
284 const dns_list_t *dns;
285 int i;
286 mode_t m;
288 _dprintf("%s\n", __FUNCTION__);
290 m = umask(022); // 077 from pppoecd
291 if ((f = fopen(dmresolv, "w")) != NULL) {
292 dns = get_dns(); // static buffer
293 if (dns->count == 0) {
294 // Put a pseudo DNS IP to trigger Connect On Demand
295 if ((nvram_match("ppp_demand", "1")) &&
296 (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "pptp") || nvram_match("wan_proto", "l2tp"))) {
297 fprintf(f, "nameserver 1.1.1.1\n");
300 else {
301 for (i = 0; i < dns->count; i++) {
302 fprintf(f, "nameserver %s\n", inet_ntoa(dns->dns[i]));
305 fclose(f);
307 umask(m);
310 // -----------------------------------------------------------------------------
312 void start_httpd(void)
314 chdir("/www");
315 if (!nvram_match("http_enable", "0")) {
316 xstart("httpd");
318 if (!nvram_match("https_enable", "0")) {
319 xstart("httpd", "-s");
321 chdir("/");
324 void stop_httpd(void)
326 killall_tk("httpd");
329 // -----------------------------------------------------------------------------
331 void start_upnp(void)
333 if (get_wan_proto() == WP_DISABLED) return;
335 #ifdef USE_MINIUPNPD
336 int enable;
337 FILE *f;
338 int upnp_port;
340 if (((enable = nvram_get_int("upnp_enable")) & 3) != 0) {
341 mkdir("/etc/upnp", 0777);
342 if (f_exists("/etc/upnp/config.alt")) {
343 xstart("miniupnpd", "-f", "/etc/upnp/config.alt");
345 else {
346 if ((f = fopen("/etc/upnp/config", "w")) != NULL) {
347 upnp_port = nvram_get_int("upnp_port");
348 if ((upnp_port <= 0) || (upnp_port >= 0xFFFF)) upnp_port = 5000;
350 fprintf(f,
351 "ext_ifname=%s\n"
352 "listening_ip=%s\n"
353 "port=%d\n"
354 "enable_upnp=%s\n"
355 "enable_natpmp=%s\n"
356 "secure_mode=%s\n"
357 "upnp_forward_chain=upnp\n"
358 "upnp_nat_chain=upnp\n"
359 "system_uptime=yes\n"
360 "\n"
362 nvram_safe_get("wan_iface"),
363 nvram_safe_get("lan_ipaddr"),
364 upnp_port,
365 (enable & 1) ? "yes" : "no", // upnp enable
366 (enable & 2) ? "yes" : "no", // natpmp enable
367 nvram_get_int("upnp_secure") ? "yes" : "no" // secure_mode (only forward to self)
369 fappend(f, "/etc/upnp/config.custom");
370 fclose(f);
372 xstart("miniupnpd", "-f", "/etc/upnp/config");
376 #else
377 if (nvram_get_int("upnp_enable")) {
378 xstart("upnp",
379 "-D",
380 "-L", nvram_safe_get("lan_ifname"),
381 "-W", nvram_safe_get("wan_iface"),
382 "-I", nvram_safe_get("upnp_ssdp_interval"),
383 "-A", nvram_safe_get("upnp_max_age"));
385 #endif
388 void stop_upnp(void)
390 #ifdef USE_MINIUPNPD
391 killall_tk("miniupnpd");
392 #else
393 killall_tk("upnp");
394 #endif
397 // -----------------------------------------------------------------------------
399 static pid_t pid_crond = -1;
401 void start_cron(void)
403 char *argv[] = { "crond", "-l", "9", NULL };
405 stop_cron();
407 if (nvram_contains_word("log_events", "crond")) argv[1] = NULL;
408 _eval(argv, NULL, 0, NULL);
409 if (!nvram_contains_word("debug_norestart", "crond")) {
410 pid_crond = -2;
415 void stop_cron(void)
417 pid_crond = -1;
418 killall_tk("crond");
421 // -----------------------------------------------------------------------------
423 // Written by Sparq in 2002/07/16
424 void start_zebra(void)
426 #ifdef TCONFIG_ZEBRA
427 FILE *fp;
429 char *lan_tx = nvram_safe_get("dr_lan_tx");
430 char *lan_rx = nvram_safe_get("dr_lan_rx");
431 char *wan_tx = nvram_safe_get("dr_wan_tx");
432 char *wan_rx = nvram_safe_get("dr_wan_rx");
434 if ((*lan_tx == '0') && (*lan_rx == '0') && (*wan_tx == '0') && (*wan_rx == '0')) {
435 return;
438 // empty
439 if ((fp = fopen("/etc/zebra.conf", "w")) != NULL) {
440 fclose(fp);
444 if ((fp = fopen("/etc/ripd.conf", "w")) != NULL) {
445 char *lan_ifname = nvram_safe_get("lan_ifname");
446 char *wan_ifname = nvram_safe_get("wan_ifname");
448 fprintf(fp, "router rip\n");
449 fprintf(fp, "network %s\n", lan_ifname);
450 fprintf(fp, "network %s\n", wan_ifname);
451 fprintf(fp, "redistribute connected\n");
452 //fprintf(fp, "redistribute static\n");
454 // 43011: modify by zg 2006.10.18 for cdrouter3.3 item 173(cdrouter_rip_30) bug
455 // fprintf(fp, "redistribute kernel\n"); // 1.11: removed, redistributes indirect -- zzz
457 fprintf(fp, "interface %s\n", lan_ifname);
458 if (*lan_tx != '0') fprintf(fp, "ip rip send version %s\n", lan_tx);
459 if (*lan_rx != '0') fprintf(fp, "ip rip receive version %s\n", lan_rx);
461 fprintf(fp, "interface %s\n", wan_ifname);
462 if (*wan_tx != '0') fprintf(fp, "ip rip send version %s\n", wan_tx);
463 if (*wan_rx != '0') fprintf(fp, "ip rip receive version %s\n", wan_rx);
465 fprintf(fp, "router rip\n");
466 if (*lan_tx == '0') fprintf(fp, "distribute-list private out %s\n", lan_ifname);
467 if (*lan_rx == '0') fprintf(fp, "distribute-list private in %s\n", lan_ifname);
468 if (*wan_tx == '0') fprintf(fp, "distribute-list private out %s\n", wan_ifname);
469 if (*wan_rx == '0') fprintf(fp, "distribute-list private in %s\n", wan_ifname);
470 fprintf(fp, "access-list private deny any\n");
472 //fprintf(fp, "debug rip events\n");
473 //fprintf(fp, "log file /etc/ripd.log\n");
474 fclose(fp);
477 xstart("zebra", "-d", "-f", "/etc/zebra.conf");
478 xstart("ripd", "-d", "-f", "/etc/ripd.conf");
479 #endif
482 void stop_zebra(void)
484 #ifdef TCONFIG_ZEBRA
485 killall("zebra", SIGTERM);
486 killall("ripd", SIGTERM);
488 unlink("/etc/zebra.conf");
489 unlink("/etc/ripd.conf");
490 #endif
493 // -----------------------------------------------------------------------------
495 void start_syslog(void)
497 #if 1
498 char *argv[12];
499 int argc;
500 char *nv;
501 char rem[256];
502 int n;
503 char s[64];
505 argv[0] = "syslogd";
506 argc = 1;
508 if (nvram_match("log_remote", "1")) {
509 nv = nvram_safe_get("log_remoteip");
510 if (*nv) {
511 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
512 argv[argc++] = "-R";
513 argv[argc++] = rem;
517 if (nvram_match("log_file", "1")) {
518 argv[argc++] = "-L";
519 argv[argc++] = "-s";
520 argv[argc++] = "50";
523 if (argc > 1) {
524 argv[argc] = NULL;
525 _eval(argv, NULL, 0, NULL);
526 usleep(500000);
528 argv[0] = "klogd";
529 argv[1] = NULL;
530 _eval(argv, NULL, 0, NULL);
531 usleep(500000);
533 // used to be available in syslogd -m
534 n = nvram_get_int("log_mark");
535 if (n > 0) {
536 sprintf(s, "cru a syslogdmark \"%s %s * * * logger -p syslog.info -- -- MARK --\"",
537 (n < 60) ? "*/30" : "0", (n < 120) ? "*" : "*/2");
538 system(s);
540 else {
541 system("cru d syslogdmark");
545 #else
546 char *argv[12];
547 int argc;
548 char *nv;
549 char rem[256];
551 argv[0] = "syslogd";
552 argv[1] = "-m";
553 argv[2] = nvram_get("log_mark");
554 argc = 3;
556 if (nvram_match("log_remote", "1")) {
557 nv = nvram_safe_get("log_remoteip");
558 if (*nv) {
559 snprintf(rem, sizeof(rem), "%s:%s", nv, nvram_safe_get("log_remoteport"));
560 argv[argc++] = "-R";
561 argv[argc++] = rem;
565 if (nvram_match("log_file", "1")) {
566 argv[argc++] = "-L";
567 argv[argc++] = "-s";
568 argv[argc++] = "50";
571 if (argc > 3) {
572 argv[argc] = NULL;
573 _eval(argv, NULL, 0, NULL);
574 usleep(500000);
576 argv[0] = "klogd";
577 argv[1] = NULL;
578 _eval(argv, NULL, 0, NULL);
579 usleep(500000);
581 #endif
584 void stop_syslog(void)
586 killall("klogd", SIGTERM);
587 killall("syslogd", SIGTERM);
590 // -----------------------------------------------------------------------------
592 static pid_t pid_igmp = -1;
594 void start_igmp_proxy(void)
596 char *p;
598 pid_igmp = -1;
599 if (nvram_match("multicast_pass", "1")) {
600 switch (get_wan_proto()) {
601 case WP_PPPOE:
602 case WP_PPTP:
603 case WP_L2TP:
604 p = "wan_iface";
605 break;
606 default:
607 p = "wan_ifname";
608 break;
610 xstart("igmprt", "-f", "-i", nvram_safe_get(p));
612 if (!nvram_contains_word("debug_norestart", "igmprt")) {
613 pid_igmp = -2;
618 void stop_igmp_proxy(void)
620 pid_igmp = -1;
621 killall("igmprt", SIGTERM);
625 // -----------------------------------------------------------------------------
627 void set_tz(void)
629 f_write_string("/etc/TZ", nvram_safe_get("tm_tz"), FW_CREATE|FW_NEWLINE, 0644);
632 void start_ntpc(void)
634 set_tz();
636 stop_ntpc();
638 if (nvram_get_int("ntp_updates") >= 0) {
639 xstart("ntpsync", "--init");
643 void stop_ntpc(void)
645 killall("ntpsync", SIGTERM);
648 // -----------------------------------------------------------------------------
650 static void stop_rstats(void)
652 int n;
653 int pid;
655 n = 60;
656 while ((n-- > 0) && ((pid = pidof("rstats")) > 0)) {
657 if (kill(pid, SIGTERM) != 0) break;
658 sleep(1);
662 static void start_rstats(int new)
664 if (nvram_match("rstats_enable", "1")) {
665 stop_rstats();
666 if (new) xstart("rstats", "--new");
667 else xstart("rstats");
671 // -----------------------------------------------------------------------------
673 static void _check(pid_t *pid, const char *name, void (*func)(void) )
675 if (*pid != -1) {
676 if (kill(*pid, 0) != 0) {
677 if ((*pid = pidof(name)) == -1) func();
682 void check_services(void)
684 _check(&pid_dnsmasq, "dnsmasq", start_dnsmasq);
685 _check(&pid_crond, "crond", start_cron);
686 _check(&pid_igmp, "igmprt", start_igmp_proxy);
689 // -----------------------------------------------------------------------------
691 void start_services(void)
693 static int once = 1;
695 if (once) {
696 once = 0;
698 create_passwd();
699 if (nvram_get_int("telnetd_eas")) start_telnetd();
700 if (nvram_get_int("sshd_eas")) start_sshd();
703 start_syslog();
704 #if TOMATO_SL
705 start_usbevent();
706 #endif
707 start_nas();
708 start_zebra();
709 start_dnsmasq();
710 start_cifs();
711 start_httpd();
712 start_cron();
713 start_upnp();
714 start_rstats(0);
715 start_sched();
716 #ifdef TCONFIG_SAMBA
717 start_smbd();
718 #endif
721 void stop_services(void)
723 clear_resolv();
725 #ifdef TCONFIG_SAMBA
726 stop_smbd();
727 #endif
728 stop_sched();
729 stop_rstats();
730 stop_upnp();
731 stop_cron();
732 stop_httpd();
733 stop_cifs();
734 stop_dnsmasq();
735 stop_zebra();
736 stop_nas();
737 #if TOMATO_SL
738 stop_usbevent();
739 #endif
740 stop_syslog();
743 // -----------------------------------------------------------------------------
745 void exec_service(void)
747 const int A_START = 1;
748 const int A_STOP = 2;
749 const int A_RESTART = 1|2;
750 char buffer[128];
751 char *service;
752 char *act;
753 char *next;
754 int action;
755 int i;
757 strlcpy(buffer, nvram_safe_get("action_service"), sizeof(buffer));
758 next = buffer;
760 TOP:
761 act = strsep(&next, ",");
762 service = strsep(&act, "-");
763 if (act == NULL) {
764 next = NULL;
765 goto CLEAR;
768 TRACE_PT("service=%s action=%s\n", service, act);
770 if (strcmp(act, "start") == 0) action = A_START;
771 else if (strcmp(act, "stop") == 0) action = A_STOP;
772 else if (strcmp(act, "restart") == 0) action = A_RESTART;
773 else action = 0;
776 if (strcmp(service, "dhcpc") == 0) {
777 if (action & A_STOP) stop_dhcpc();
778 if (action & A_START) start_dhcpc();
779 goto CLEAR;
782 if ((strcmp(service, "dhcpd") == 0) || (strcmp(service, "dns") == 0) || (strcmp(service, "dnsmasq") == 0)) {
783 if (action & A_STOP) stop_dnsmasq();
784 if (action & A_START) {
785 dns_to_resolv();
786 start_dnsmasq();
788 goto CLEAR;
791 if (strcmp(service, "firewall") == 0) {
792 if (action & A_STOP) {
793 stop_firewall();
794 stop_igmp_proxy();
796 if (action & A_START) {
797 start_firewall();
798 start_igmp_proxy();
800 goto CLEAR;
803 if (strcmp(service, "restrict") == 0) {
804 if (action & A_STOP) {
805 stop_firewall();
807 if (action & A_START) {
808 i = nvram_get_int("rrules_radio"); // -1 = not used, 0 = enabled by rule, 1 = disabled by rule
810 start_firewall();
812 // if radio was disabled by access restriction, but no rule is handling it now, enable it
813 if (i == 1) {
814 if (nvram_get_int("rrules_radio") < 0) {
815 if (!get_radio()) eval("radio", "on");
819 goto CLEAR;
822 if (strcmp(service, "qos") == 0) {
823 if (action & A_STOP) {
824 stop_qos();
826 stop_firewall(); start_firewall(); // always restarted
827 if (action & A_START) {
828 start_qos();
829 if (nvram_match("qos_reset", "1")) f_write_string("/proc/net/clear_marks", "1", 0, 0);
831 goto CLEAR;
834 if (strcmp(service, "upnp") == 0) {
835 if (action & A_STOP) {
836 stop_upnp();
838 stop_firewall(); start_firewall(); // always restarted
839 if (action & A_START) {
840 start_upnp();
842 goto CLEAR;
845 if (strcmp(service, "telnetd") == 0) {
846 if (action & A_STOP) stop_telnetd();
847 if (action & A_START) start_telnetd();
848 goto CLEAR;
851 if (strcmp(service, "sshd") == 0) {
852 if (action & A_STOP) stop_sshd();
853 if (action & A_START) start_sshd();
854 goto CLEAR;
857 if (strcmp(service, "httpd") == 0) {
858 if (action & A_STOP) stop_httpd();
859 if (action & A_START) start_httpd();
860 goto CLEAR;
863 if (strcmp(service, "admin") == 0) {
864 if (action & A_STOP) {
865 stop_sshd();
866 stop_telnetd();
867 stop_httpd();
869 stop_firewall(); start_firewall(); // always restarted
870 if (action & A_START) {
871 start_httpd();
872 create_passwd();
873 if (nvram_match("telnetd_eas", "1")) start_telnetd();
874 if (nvram_match("sshd_eas", "1")) start_sshd();
876 goto CLEAR;
879 if (strcmp(service, "ddns") == 0) {
880 if (action & A_STOP) stop_ddns();
881 if (action & A_START) start_ddns();
882 goto CLEAR;
885 if (strcmp(service, "ntpc") == 0) {
886 if (action & A_STOP) stop_ntpc();
887 if (action & A_START) start_ntpc();
888 goto CLEAR;
891 if (strcmp(service, "logging") == 0) {
892 if (action & A_STOP) {
893 stop_syslog();
894 stop_cron();
896 stop_firewall(); start_firewall(); // always restarted
897 if (action & A_START) {
898 start_cron();
899 start_syslog();
901 goto CLEAR;
904 if (strcmp(service, "crond") == 0) {
905 if (action & A_STOP) {
906 stop_cron();
908 if (action & A_START) {
909 start_cron();
911 goto CLEAR;
914 if (strcmp(service, "upgrade") == 0) {
915 if (action & A_START) {
916 #if TOMATO_SL
917 stop_usbevent();
918 stop_smbd();
919 #endif
920 stop_jffs2();
921 // stop_cifs();
922 stop_zebra();
923 stop_cron();
924 stop_ntpc();
925 stop_upnp();
926 // stop_dhcpc();
927 killall("rstats", SIGTERM);
928 killall("buttons", SIGTERM);
929 stop_syslog();
931 goto CLEAR;
934 #ifdef TCONFIG_CIFS
935 if (strcmp(service, "cifs") == 0) {
936 if (action & A_STOP) stop_cifs();
937 if (action & A_START) start_cifs();
938 goto CLEAR;
940 #endif
942 #ifdef TCONFIG_JFFS2
943 if (strcmp(service, "jffs2") == 0) {
944 if (action & A_STOP) stop_jffs2();
945 if (action & A_START) start_jffs2();
946 goto CLEAR;
948 #endif
950 if (strcmp(service, "routing") == 0) {
951 if (action & A_STOP) {
952 stop_zebra();
953 do_static_routes(0); // remove old '_saved'
954 eval("brctl", "stp", nvram_safe_get("lan_ifname"), "0");
956 stop_firewall();
957 start_firewall();
958 if (action & A_START) {
959 do_static_routes(1); // add new
960 start_zebra();
961 eval("brctl", "stp", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_stp"));
963 goto CLEAR;
966 if (strcmp(service, "ctnf") == 0) {
967 if (action & A_START) {
968 setup_conntrack();
969 stop_firewall();
970 start_firewall();
972 goto CLEAR;
975 if (strcmp(service, "wan") == 0) {
976 if (action & A_STOP) {
977 if (get_wan_proto() == WP_PPPOE) {
978 stop_dnsmasq();
979 stop_redial();
980 stop_singe_pppoe(PPPOE0);
981 if (((action & A_START) == 0) && (nvram_match("ppp_demand", "1"))) {
982 sleep(1);
983 start_pppoe(PPPOE0);
985 start_dnsmasq();
987 else {
988 stop_wan();
992 if (action & A_START) {
993 rename("/tmp/ppp/log", "/tmp/ppp/log.~");
995 if (get_wan_proto() == WP_PPPOE) {
996 stop_singe_pppoe(PPPOE0);
997 start_pppoe(PPPOE0);
998 if (nvram_invmatch("ppp_demand", "1")) {
999 start_redial();
1002 else {
1003 start_wan(BOOT);
1005 sleep(2);
1006 force_to_dial();
1008 goto CLEAR;
1011 if (strcmp(service, "net") == 0) {
1012 if (action & A_STOP) {
1013 stop_wan();
1014 stop_lan();
1015 stop_vlan();
1017 if (action & A_START) {
1018 start_vlan();
1019 start_lan();
1020 start_wan(BOOT);
1022 goto CLEAR;
1025 if (strcmp(service, "rstats") == 0) {
1026 if (action & A_STOP) stop_rstats();
1027 if (action & A_START) start_rstats(0);
1028 goto CLEAR;
1031 if (strcmp(service, "rstatsnew") == 0) {
1032 if (action & A_STOP) stop_rstats();
1033 if (action & A_START) start_rstats(1);
1034 goto CLEAR;
1037 if (strcmp(service, "sched") == 0) {
1038 if (action & A_STOP) stop_sched();
1039 if (action & A_START) start_sched();
1040 goto CLEAR;
1043 CLEAR:
1044 if (next) goto TOP;
1046 // some functions check action_service and must be cleared at end -- zzz
1047 nvram_set("action_service", "");
1050 static void do_service(const char *name, const char *action, int user)
1052 int n;
1053 char s[64];
1055 n = 15;
1056 while (!nvram_match("action_service", "")) {
1057 if (user) {
1058 putchar('*');
1059 fflush(stdout);
1061 else if (--n < 0) break;
1062 sleep(1);
1065 snprintf(s, sizeof(s), "%s-%s", name, action);
1066 nvram_set("action_service", s);
1067 kill(1, SIGUSR1);
1069 n = 15;
1070 while (nvram_match("action_service", s)) {
1071 if (user) {
1072 putchar('.');
1073 fflush(stdout);
1075 else if (--n < 0) {
1076 break;
1078 sleep(1);
1082 int service_main(int argc, char *argv[])
1084 if (argc != 3) usage_exit(argv[0], "<service> <action>");
1085 do_service(argv[1], argv[2], 1);
1086 printf("\nDone.\n");
1087 return 0;
1090 void start_service(const char *name)
1092 do_service(name, "start", 0);
1095 void stop_service(const char *name)
1097 do_service(name, "stop", 0);
1101 void restart_service(const char *name)
1103 do_service(name, "restart", 0);