1 /*
2 * Copyright 1996, 1997, 1998, 1999 by Daniel B. Suthers,
3 * Pleasanton Ca. 94588 USA
4 * E-MAIL dbs@tanj.com
5 *
6 */
7
8 /*
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24
25 #include <stdio.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <signal.h>
34 #include <setjmp.h>
35 #include <errno.h>
36 #include <syslog.h>
37 #if defined(SYSV) || defined(FREEBSD) || defined(OPENBSD)
38 #include <string.h>
39 #else
40 #include <strings.h>
41 #endif
42
43 #include <time.h>
44
45 #include "x10.h"
46 #include "process.h"
47
48
49 #ifdef __GLIBC__
50 /* msf - added for glibc/rh 5.0 */
51 #include <sys/types.h>
52 #endif
53
54 extern int timeout;
55 extern int sptty;
56 extern int i_am_monitor, i_am_state, i_am_relay, i_am_rfxmeter;
57 extern int heyu_parent;
58 extern void fix_tznames ( void );
59 extern void x10state_init_all ();
60 extern int read_x10state_file ();
61 extern CONFIG config;
62 extern CONFIG *configp;
63 extern FILE *fdsout, *fdserr;
64 extern FILE *fprfxo, *fprfxe;
65 extern char *datstrf(void);
66 extern int clear_data_storage( void );
67
68 void iquit();
69 jmp_buf mjb;
70
iquit(int signo)71 void iquit( int signo )
72 {
73 longjmp(mjb, 1);
74 }
75
engine_quit(int signo)76 void engine_quit ( int signo )
77 {
78 char buffer[PATH_LEN + 1];
79 signal(SIGTERM, engine_quit);
80 syslog(LOG_ERR, "interrupt received\n");
81 write_x10state_file();
82 sprintf(buffer, "%s/LCK..%s%s", LOCKDIR, STATE_LOCKFILE, configp->suffix);
83 unlink(buffer);
84 exit(0);
85 }
86
c_monitor(int argc,char * argv[])87 int c_monitor( int argc, char *argv[] )
88 {
89 off_t f_offset;
90 int check4poll();
91 struct stat stat_buf;
92 char spoolfile[100];
93 time_t time_now, time_prev;
94
95 sprintf( spoolfile, "%s/%s%s", SPOOLDIR, SPOOLFILE, configp->suffix);
96 (void) signal(SIGCHLD, iquit);
97 (void) signal(SIGINT, iquit);
98 if (setjmp(mjb))
99 return(0);
100
101 i_am_monitor = 1;
102
103 if ( read_x10state_file() != 0 )
104 x10state_init_all();
105
106 if ( argc == 3 && strcmp(argv[2], "rfxmeter") == 0 ) {
107 /* Disable display except for RFXMeter setup file pointers */
108 i_am_monitor = 0;
109 i_am_rfxmeter = 1;
110 fdsout = fopen("/dev/null", "w");
111 fdserr = fopen("/dev/null", "w");
112 fprfxo = stdout;
113 fprfxe = stderr;
114 }
115 else {
116 fprintf(stdout, "%s Monitor started\n", datstrf());
117 fflush(stdout);
118 }
119
120 f_offset = lseek(sptty, 0, SEEK_CUR); /* find current position */
121
122 time_now = time_prev = time(NULL);
123
124
125 while (1) {
126 if( f_offset == lseek(sptty, 0, SEEK_END) ) { /* find end of file */
127 if( stat( spoolfile, &stat_buf ) < 0)
128 return(0);
129
130 /* this imposes a delay between the start of new output*/
131 /* It keeps the disk from being thrashed. */
132 microsleep(configp->engine_poll);
133 }
134 else {
135 if ( fstat( sptty, &stat_buf ) < 0 )
136 return(0);
137 lseek(sptty, f_offset, SEEK_SET);
138 check4poll(1,1);
139 f_offset = lseek(sptty, 0, SEEK_CUR); /* find current position */
140 }
141
142 /* Activate countdown timers */
143 if ( (time_now = time(NULL)) != time_prev ) {
144 second_tick(time_now, (long)(time_now - time_prev));
145 time_prev = time_now;
146 }
147 }
148 /* return(0); */
149 }
150
c_engine(int argc,char * argv[])151 int c_engine( int argc, char *argv[] )
152 {
153 off_t f_offset;
154 int check4poll();
155 struct stat stat_buf;
156 char spoolfile[100];
157 time_t time_now, time_prev;
158 long tmin_now, tmin_prev, thour_now, thour_prev;
159 mode_t oldumask;
160 extern FILE *fdsout;
161 extern FILE *fdserr;
162
163 sprintf( spoolfile, "%s/%s%s", SPOOLDIR, SPOOLFILE, configp->suffix);
164
165 (void) signal(SIGINT, engine_quit /*iquit*/);
166 (void) signal(SIGTERM, engine_quit);
167
168 if (setjmp(mjb))
169 return(0);
170
171 i_am_state = 1;
172 i_am_monitor = 1;
173 heyu_parent = D_CMDLINE;
174
175 openlog( "heyu_engine", 0, LOG_DAEMON);
176 syslog(LOG_ERR, "engine setting up-\n");
177
178 if ( read_x10state_file() != 0 )
179 x10state_init_all();
180
181 time_now = time_prev = time(NULL);
182 tmin_now = tmin_prev = (long)time_now / 60L;
183 thour_now = thour_prev = (long)time_now / 3600;
184
185 engine_local_setup(E_START);
186 fix_tznames();
187
188 f_offset = lseek(sptty, 0, SEEK_CUR); /* find current position */
189
190 oldumask = umask(configp->log_umask);
191 fdsout = freopen(configp->logfile, "a", stdout);
192 fdserr = freopen(configp->logfile, "a", stderr);
193 umask(oldumask);
194
195 fprintf(fdsout, "%s Engine started\n", datstrf());
196 fflush(fdsout);
197
198 while (1) {
199 if ( f_offset == lseek(sptty, 0, SEEK_END) ) { /* find end of file */
200 if( stat( spoolfile, &stat_buf ) < 0)
201 engine_quit(SIGTERM) /* return(0) */;
202
203 /* this imposes a delay between the start of new output*/
204 /* It keeps the disk from being thrashed. */
205 microsleep(configp->engine_poll);
206 }
207 else {
208 if ( fstat( sptty, &stat_buf ) < 0)
209 return(0);
210 lseek(sptty, f_offset, SEEK_SET);
211 check4poll(1,1);
212 f_offset = lseek(sptty, 0, SEEK_CUR); /* find current position */
213 }
214
215 if ( (time_now = time(NULL)) != time_prev ) {
216 if ( is_tomorrow(time_now) ) {
217 /* Local Midnight. STD Time */
218 midnight_tick(time_now);
219 set_global_tomorrow(time_now);
220 }
221 if ( (thour_now = (long)time_now / 3600L) != thour_prev ) {
222 /* Once every hour */
223 hour_tick(time_now);
224 thour_prev = thour_now;
225 }
226 if ( (tmin_now = (long)time_now / 60L) != tmin_prev ) {
227 /* Once every minute */
228 minute_tick(time_now);
229 tmin_prev = tmin_now;
230 }
231 /* Once every second */
232 /* Activate countdown timers */
233 second_tick(time_now, (long)(time_now - time_prev));
234 time_prev = time_now;
235 }
236 }
237 /* return(0); */
238 }
239
240