Subversion Repositories heizung

Rev

Rev 10 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 10 Rev 11
Line 1... Line 1...
1
/*
1
/*
2
 * (C) Copyright 2010, 2011 by Andreas Theofilu <andreas@theosys.at>
2
 * (C) Copyright 2010 to 2015, 2024 by Andreas Theofilu <andreas@theosys.at>
3
 * All rights reserved!
3
 * All rights reserved!
4
 */
4
 */
-
 
5
//#define SENSOR_ELV
-
 
6
#define SENSOR_ETHERNET
5
 
7
 
6
#include <stdio.h>
8
#include <stdio.h>
7
#include <string.h>
9
#include <string.h>
8
#include <unistd.h>
10
#include <unistd.h>
9
#include <stdlib.h>
11
#include <stdlib.h>
Line 15... Line 17...
15
#include <errno.h>
17
#include <errno.h>
16
#include <pthread.h>
18
#include <pthread.h>
17
#include <sys/stat.h>
19
#include <sys/stat.h>
18
#include <sys/types.h>
20
#include <sys/types.h>
19
#include <sys/socket.h>
21
#include <sys/socket.h>
-
 
22
#include <poll.h>
20
#include <fcntl.h>
23
#include <fcntl.h>
21
#include <netdb.h>
24
#include <netdb.h>
22
#include <dirent.h>
25
#include <dirent.h>
23
#include <netinet/in.h>
26
#include <netinet/in.h>
-
 
27
#include <arpa/inet.h>
24
#include <sys/param.h>
28
#include <sys/param.h>
25
#include <sys/ioctl.h>
29
#include <sys/ioctl.h>
-
 
30
#include <sys/time.h>
26
#include <pwd.h>
31
#include <pwd.h>
27
#include <grp.h>
32
#include <grp.h>
28
#include "sensor.h"
33
#include "sensor.h"
29
#include "usb_comm.h"
34
#include "usb_comm.h"
30
#include "heizung.h"
35
#include "heizung.h"
31
 
36
 
-
 
37
#ifndef ulong
-
 
38
#define ulong       unsigned long
-
 
39
#endif
-
 
40
 
32
typedef struct
41
typedef struct
33
{
42
{
34
      int wday;
43
    int wday;
35
      ulong start;
44
    ulong start;
36
      ulong end;
45
    ulong end;
37
      float temp;
46
    float temp;
38
}HEIZUNG;
47
} HEIZUNG;
39
 
48
 
40
typedef struct HEIZINDEX
49
typedef struct HEIZINDEX
41
{
50
{
42
      HEIZUNG *heizung;
51
    HEIZUNG *heizung;
43
      struct HEIZINDEX *next;
52
    struct HEIZINDEX *next;
44
}HEIZINDEX;
53
} HEIZINDEX;
45
 
54
 
46
struct SOCKETS
55
struct SOCKETS
47
{
56
{
48
      int sockfd;
57
    int sockfd;
49
      int newfd;
58
    int newfd;
-
 
59
    int valid;
50
};
60
};
51
 
61
 
52
CONFIGURE configs;
62
CONFIGURE configs;
53
HEIZINDEX *HeizFirst;
63
HEIZINDEX *HeizFirst;
54
float ActTemperature;
64
float ActTemperature;
55
float ActPressure;
65
float ActPressure;
-
 
66
struct SOCKETS soc;
-
 
67
int killed = 0;
56
 
68
 
57
static pthread_t pthr_pars, pthr_temp_pars, pthr_process;
69
static pthread_t pthr_pars, pthr_temp_pars, pthr_process, pthr_run_change;
58
 
70
 
59
// Prototypes
71
// Prototypes
60
void daemon_start(int ignsigcld);
72
void daemon_start(int ignsigcld);
61
void *pthr_temperature(void *pV_data);
73
void *pthr_temperature(void *pV_data);
62
void *pthr_parser(void *pV_data);
74
void *pthr_parser(void *pV_data);
63
void sig_child(void);
75
void sig_child(int);
64
void sendList(int s1);
76
void sendList(int s1);
65
int listSchemas(int s1);
77
int listSchemas(int s1);
66
int parseCommand(int s1, char *cmd);
78
int parseCommand(int s1, char *cmd);
67
void *processCommands(void *pV_data);
79
void *processCommands(void *pV_data);
68
void changeToUser(char *, char *);
80
void changeToUser(char *, char *);
-
 
81
void *pthr_report(void *pV_data);
69
 
82
 
70
HEIZINDEX *allocateMemory(void);
83
HEIZINDEX *allocateMemory(void);
71
HEIZINDEX *insertMemory(HEIZINDEX *pos);
84
HEIZINDEX *insertMemory(HEIZINDEX *pos);
72
void freeMemory(void);
85
void freeMemory(void);
73
HEIZINDEX *freeChainMember(HEIZINDEX *member);
86
HEIZINDEX *freeChainMember(HEIZINDEX *member);
Line 86... Line 99...
86
char *readLine(int fd, char *buf, int bufLen);
99
char *readLine(int fd, char *buf, int bufLen);
87
char *trim(char *str);
100
char *trim(char *str);
88
char *remove_string(char *str, char *search, char *ret);
101
char *remove_string(char *str, char *search, char *ret);
89
 
102
 
90
//static pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
103
//static pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
91
static pthread_mutex_t fastmutex_ser = PTHREAD_MUTEX_INITIALIZER;
104
//static pthread_mutex_t fastmutex_ser = PTHREAD_MUTEX_INITIALIZER;
92
static pthread_mutex_t fastmutex_proc = PTHREAD_MUTEX_INITIALIZER;
105
//static pthread_mutex_t fastmutex_proc = PTHREAD_MUTEX_INITIALIZER;
93
 
106
 
94
/*
107
/*
95
 * The main program, initializing everything and start the daemon.
108
 * The main program, initializing everything and start the daemon.
96
 */
109
 */
97
int main(int argc, char *argv[])
110
int main(int argc, char *argv[])
98
{
111
{
99
int fd, index;
-
 
100
 
-
 
101
	HeizFirst = NULL;
112
    HeizFirst = NULL;
102
	readConf();
-
 
103
	// Initialize USB
-
 
104
	serialDev.fd = -1;
-
 
105
	serialDev.switch_fd = -1;
-
 
106
	serialDev.handle = NULL;
-
 
107
	// Now daemonize this application
-
 
108
	daemon_start(0);
-
 
109
	changeToUser(&configs.User[0], &configs.Grp[0]);
-
 
110
	// Now start our Thread
-
 
111
	if (pthread_create(&pthr_pars, NULL, pthr_parser, (void *)0) != 0)
-
 
112
	{
-
 
113
	   syslog (LOG_DAEMON,"Create of thread \"pthr_parser\" failed!");
-
 
114
	   return 1;
-
 
115
	}
-
 
116
 
-
 
117
	// Here we start another thread to read the temperature
-
 
118
	if (pthread_create(&pthr_temp_pars, NULL, pthr_temperature, (void *)0) != 0)
-
 
119
	{
-
 
120
	   syslog(LOG_DAEMON,"Create of thread \"pthr_temperature\" failed!");
-
 
121
	   pthread_cancel(pthr_pars);
113
    memset(&soc, 0, sizeof(soc));
122
	   return 1;
-
 
123
	}
-
 
124
 
114
 
-
 
115
    readConf();
-
 
116
    // Initialize USB
-
 
117
    serialDev.fd = -1;
-
 
118
    serialDev.switch_fd = -1;
-
 
119
    serialDev.handle = NULL;
-
 
120
    // Now daemonize this application
-
 
121
    daemon_start(0);
-
 
122
    changeToUser(&configs.User[0], &configs.Grp[0]);
-
 
123
 
-
 
124
    // Now start our Thread
-
 
125
    if (pthread_create(&pthr_pars, NULL, pthr_parser, (void *)0) != 0)
-
 
126
    {
-
 
127
        syslog(LOG_DAEMON | LOG_ERR, "Create of thread \"pthr_parser\" failed!");
-
 
128
        return 1;
-
 
129
    }
-
 
130
 
-
 
131
    pthread_detach(pthr_pars);
-
 
132
 
-
 
133
    // Here we start another thread to read the temperature
-
 
134
    if (pthread_create(&pthr_temp_pars, NULL, pthr_temperature, (void *)0) != 0)
-
 
135
    {
-
 
136
        syslog(LOG_DAEMON | LOG_ERR, "Create of thread \"pthr_temperature\" failed!");
-
 
137
        pthread_cancel(pthr_pars);
-
 
138
        return 1;
-
 
139
    }
-
 
140
 
-
 
141
    pthread_detach(pthr_temp_pars);
-
 
142
 
-
 
143
    // At least we neeed a thread to send the on/off status whenever it changes.
-
 
144
    if (pthread_create(&pthr_run_change, NULL, pthr_report, (void *)0) != 0)
-
 
145
    {
-
 
146
        syslog(LOG_DAEMON | LOG_ERR, "Create of thread \"pthr_report\" failed!");
-
 
147
        pthread_cancel(pthr_pars);
-
 
148
        pthread_cancel(pthr_temp_pars);
-
 
149
        return 1;
-
 
150
    }
-
 
151
 
-
 
152
    pthread_detach(pthr_run_change);
-
 
153
 
125
	while (1)
154
    while (!killed)
126
	   sleep(3600);
155
        sleep(1);
127
 
156
 
-
 
157
    unlink(configs.Pidfile);
128
	pthread_exit(NULL);
158
    pthread_exit(NULL);
129
	return 0;
159
    return 0;
130
}
160
}
131
 
161
 
132
/*
162
/*
133
 * Detach application from console and make it a daemon.
163
 * Detach application from console and make it a daemon.
134
 */
164
 */
135
void daemon_start (int ignsigcld)
165
void daemon_start(int ignsigcld)
136
{
166
{
137
int childpid, fd;
167
    int childpid, fd;
138
char hv0[64];
168
    char hv0[64];
139
 
169
 
140
        if (getpid () == 1)
170
    if (getpid() == 1)
141
           goto out;
171
        goto out;
142
 
172
 
143
#ifdef SIGTTOU
173
#ifdef SIGTTOU
144
        signal (SIGTTOU, SIG_IGN);
174
    signal(SIGTTOU, SIG_IGN);
145
#endif
175
#endif
146
#ifdef SIGTTIN
176
#ifdef SIGTTIN
147
        signal (SIGTTIN, SIG_IGN);
177
    signal(SIGTTIN, SIG_IGN);
148
#endif
178
#endif
149
#ifdef SIGTSTP
179
#ifdef SIGTSTP
150
        signal (SIGTSTP, SIG_IGN);
180
    signal(SIGTSTP, SIG_IGN);
151
#endif
181
#endif
152
 
182
 
153
        if ((childpid = fork ()) < 0)
183
    if ((childpid = fork()) < 0)
154
           fprintf (stderr, "Can't fork this child\n");
184
        fprintf(stderr, "Can't fork this child\n");
155
        else if (childpid > 0)
185
    else if (childpid > 0)
156
           exit (0);
186
        exit(0);
157
 
187
 
158
        if (setpgrp () == -1)
188
    if (setpgrp() == -1)
159
           fprintf (stderr, "Can't change process group\n");
189
        fprintf(stderr, "Can't change process group\n");
160
 
190
 
161
        signal (SIGHUP, SIG_IGN);
191
    signal(SIGHUP, SIG_IGN);
162
 
192
 
163
        if ((childpid = fork ()) < 0)
193
    if ((childpid = fork()) < 0)
164
           syslog (LOG_DAEMON, "Can't fork second child");
194
        syslog(LOG_DAEMON | LOG_ERR, "Can't fork second child");
165
        else if (childpid > 0)
195
    else if (childpid > 0)
166
           exit (0);            /* first child */
196
        exit(0);             /* first child */
167
 
197
 
168
        /* second child */
198
    /* second child */
169
out:
199
out:
170
        for (fd = 0; fd < NOFILE; fd++)
-
 
171
           close (fd);
-
 
172
 
200
 
173
        errno = 0;
-
 
174
        chdir ("/");
201
    for (fd = 0; fd < NOFILE; fd++)
175
        umask (0);
202
        close(fd);
176
 
-
 
177
        if (ignsigcld)
-
 
178
        {
-
 
179
//#ifdef SIGTSTP
-
 
180
//           signal (SIGCLD, sig_child);
-
 
181
//#else
-
 
182
           signal (SIGCLD, SIG_IGN);
-
 
183
//#endif
-
 
184
        }
-
 
185
 
-
 
186
	// Create PID file
-
 
187
	if ((fd = open(configs.Pidfile, O_RDWR | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
-
 
188
	{
-
 
189
	   syslog(LOG_WARNING,"Can't create PID file %s: %s",configs.Pidfile, strerror(errno));
-
 
190
	   return;
-
 
191
	}
-
 
192
	
-
 
193
	sprintf(&hv0[0],"%d", getpid());
-
 
194
	write(fd, hv0, strlen(hv0));
-
 
195
	close(fd);
-
 
196
}
-
 
197
 
-
 
198
void sig_child ()
-
 
199
{
-
 
200
#if defined(BSD) && !defined(sinix) && !defined(Linux)
-
 
201
int pid;
-
 
202
union wait status;
-
 
203
 
203
 
-
 
204
    errno = 0;
-
 
205
    chdir("/");
-
 
206
    umask(0);
-
 
207
 
-
 
208
    if (ignsigcld)
-
 
209
        signal(SIGCLD, SIG_IGN);
-
 
210
 
-
 
211
    signal(SIGTERM, sig_child);
-
 
212
    // Create PID file
-
 
213
    if ((fd = open(configs.Pidfile, O_RDWR | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
-
 
214
    {
204
        while ((pid = wait3 (&status, WNOHANG, (struct rusage *)0)) > 0)
215
        syslog(LOG_DAEMON | LOG_WARNING, "Can't create PID file %s: %s", configs.Pidfile, strerror(errno));
205
                ;
216
        return;
206
#endif
217
    }
-
 
218
 
-
 
219
    sprintf(&hv0[0], "%d", getpid());
-
 
220
    write(fd, hv0, strlen(hv0));
-
 
221
    close(fd);
-
 
222
}
-
 
223
 
-
 
224
void sig_child(int)
-
 
225
{
-
 
226
    syslog(LOG_DAEMON | LOG_INFO, "Program was killed by signal 15!");
-
 
227
    killed = 1;
207
}
228
}
208
 
229
 
209
void changeToUser(char *usr, char *grp)
230
void changeToUser(char *usr, char *grp)
210
{
231
{
211
gid_t gr_gid;
232
    gid_t gr_gid;
-
 
233
 
-
 
234
    if (usr && strlen(usr))
-
 
235
    {
-
 
236
        /* get uid */
-
 
237
        struct passwd *userpwd;
-
 
238
        struct group *usergrp;
-
 
239
 
-
 
240
        if ((userpwd = getpwnam(usr)) == NULL)
-
 
241
        {
-
 
242
            syslog(LOG_DAEMON | LOG_ERR, "no such user: %s", usr);
-
 
243
            exit(EXIT_FAILURE);
-
 
244
        }
-
 
245
 
-
 
246
        if (!grp || strlen(grp) || (usergrp = getgrnam(grp)) == NULL)
-
 
247
        {
-
 
248
            if (grp && strlen(grp))
-
 
249
                syslog(LOG_DAEMON | LOG_WARNING, "no such group: %s", grp);
-
 
250
 
-
 
251
            gr_gid = userpwd->pw_gid;
-
 
252
        }
-
 
253
        else
-
 
254
            gr_gid = usergrp->gr_gid;
212
 
255
 
213
	if (usr && strlen(usr))
-
 
214
	{
-
 
215
	   /* get uid */
-
 
216
	   struct passwd *userpwd;
-
 
217
	   struct group *usergrp;
-
 
218
 
-
 
219
	   if ((userpwd = getpwnam(usr)) == NULL)
-
 
220
	   {
-
 
221
	      syslog(LOG_DAEMON,"no such user: %s", usr);
-
 
222
	      exit(EXIT_FAILURE);
-
 
223
	   }
-
 
224
 
-
 
225
	   if (!grp || strlen(grp) || (usergrp = getgrnam(grp)) == NULL)
-
 
226
	   {
-
 
227
	      if (grp && strlen(grp))
-
 
228
	         syslog(LOG_WARNING,"no such group: %s", grp);
-
 
229
 
-
 
230
	      gr_gid = userpwd->pw_gid;
-
 
231
	   }
-
 
232
	   else
-
 
233
	      gr_gid = usergrp->gr_gid;
-
 
234
 
-
 
235
	   if (setgid(gr_gid) == -1)
256
        if (setgid(gr_gid) == -1)
236
	   {
257
        {
237
	      syslog(LOG_DAEMON,"cannot setgid of user %s: %s", usr, strerror(errno));
258
            syslog(LOG_DAEMON | LOG_ERR, "cannot setgid of user %s: %s", usr, strerror(errno));
238
	      exit(EXIT_FAILURE);
259
            exit(EXIT_FAILURE);
239
	   }
260
        }
240
 
261
 
241
#ifdef _BSD_SOURCE
262
#ifdef _BSD_SOURCE
242
	   /* init suplementary groups
263
        /* init suplementary groups
243
	    * (must be done before we change our uid)
264
         * (must be done before we change our uid)
244
	    */
265
         */
245
	   if (initgroups(usr, gr_gid) == -1)
266
        if (initgroups(usr, gr_gid) == -1)
246
	      syslog(LOG_DAEMON,"cannot init suplementary groups of user %s: %s", usr, strerror(errno));
267
            syslog(LOG_DAEMON | LOG_ERR, "cannot init suplementary groups of user %s: %s", usr, strerror(errno));
247
#endif
268
#endif
248
 
269
 
249
	   /* set uid */
270
        /* set uid */
250
	   if (setuid(userpwd->pw_uid) == -1)
271
        if (setuid(userpwd->pw_uid) == -1)
251
	   {
272
        {
252
	      syslog(LOG_DAEMON,"cannot change to uid of user %s: %s\n", usr, strerror(errno));
273
            syslog(LOG_DAEMON | LOG_ERR, "cannot change to uid of user %s: %s\n", usr, strerror(errno));
253
	      exit(EXIT_FAILURE);
274
            exit(EXIT_FAILURE);
254
	   }
-
 
255
 
-
 
256
	   if(userpwd->pw_dir)
-
 
257
	      setenv("HOME", userpwd->pw_dir, 1);
-
 
258
        }
275
        }
-
 
276
 
-
 
277
        if (userpwd->pw_dir)
-
 
278
            setenv("HOME", userpwd->pw_dir, 1);
-
 
279
    }
259
}
280
}
260
 
281
 
261
void *pthr_temperature(void *pV_data)
282
void *pthr_temperature(void *pV_data)
262
{
283
{
263
time_t t, tstart;
284
    time_t t, tstart;
264
struct tm *zeit, sz;
285
    struct tm *zeit, sz;
265
int sleep_sec;
286
    int sleep_sec;
266
 
287
 
267
	// Initialize the serial port.
288
    // Initialize the serial port.
268
	serial_set_method((strlen(configs.Device)) ? 1 : 0, configs.VID, configs.PID);
289
    serial_set_method((strlen(configs.Device)) ? 1 : 0, configs.VID, configs.PID);
269
 
290
 
270
	if (strlen(configs.Device))
291
    if (strlen(configs.Device))
271
	   serial_set_device(configs.Device);
292
        serial_set_device(configs.Device);
272
 
293
 
273
	if (!serial_open())
294
    if (!serial_open())
274
	   return NULL;
295
        return NULL;
275
 
296
 
276
	if (serialDev.switch_fd == -1)
297
    if (serialDev.switch_fd == -1)
277
	{
298
    {
278
	   if (!serial_open())
299
        if (!serial_open())
279
	      return NULL;
300
            return NULL;
280
	}
-
 
281
 
-
 
282
	pthread_mutex_lock (&fastmutex_ser);
-
 
283
	sleep(1);	// Give the other thread time to initialize the structure
-
 
284
 
-
 
285
	while(1)
-
 
286
	{
-
 
287
	   HEIZINDEX *act;
-
 
288
 
-
 
289
	   GetTemp();
-
 
290
	   sleep_sec = 300;
-
 
291
 
-
 
292
	   // Compare the actual temperature with the one that should be
-
 
293
	   // and switch heating on or off
-
 
294
	   if (HeizFirst)
-
 
295
	   {
-
 
296
	      int wday;
-
 
297
	      unsigned long loctm;
-
 
298
 
-
 
299
	      t = time (NULL);
-
 
300
	      sleep_sec = 300 - (int)((t + 300L) % 300L);
-
 
301
	      sleep_sec++;
-
 
302
	      zeit = localtime (&t);
-
 
303
 
-
 
304
	      wday = (zeit->tm_wday == 0) ? 7 : zeit->tm_wday;
-
 
305
	      memset (&sz, 0, sizeof (struct tm));
-
 
306
	      sz.tm_min = 0;
-
 
307
	      sz.tm_hour = 0;
-
 
308
	      sz.tm_mon = zeit->tm_mon;
-
 
309
	      sz.tm_mday = zeit->tm_mday;
-
 
310
	      sz.tm_year = zeit->tm_year;
-
 
311
	      sz.tm_isdst = zeit->tm_isdst;
-
 
312
	      tstart = mktime(&sz);
-
 
313
	      loctm = (t - tstart) + 1;	// Seconds since midnight
-
 
314
	      act = HeizFirst;
-
 
315
 
-
 
316
	      while(act)
-
 
317
	      {
-
 
318
		 if (act->heizung->wday == wday && loctm >= act->heizung->start && loctm <= act->heizung->end)
-
 
319
		 {
-
 
320
		    if (ActTemperature == 9999.0)
-
 
321
		       SwitchOff();		// No temperature, no heating
-
 
322
		    else if (ActTemperature < 5.0)
-
 
323
		       SwitchOn();		// Make sure it will not freeze
-
 
324
		    else if (ActTemperature > 30.0)
-
 
325
		       SwitchOff();		// Don't over heat
-
 
326
		    else if (ActTemperature <= (act->heizung->temp - 0.5))
-
 
327
		       SwitchOn();
-
 
328
		    else if (ActTemperature > act->heizung->temp)
-
 
329
		       SwitchOff();
-
 
330
		 }
-
 
331
 
-
 
332
		 act = act->next;
-
 
333
	      }
-
 
334
	   }
301
    }
335
	   else
-
 
336
	      syslog(LOG_INFO,"Structure not initialized!");
-
 
337
 
302
 
338
	   sleep(sleep_sec);		// Wait 5 Minutes
303
    sleep(1);   // Give the other thread time to initialize the structure
339
	}
-
 
340
 
304
 
-
 
305
    while (!killed)
-
 
306
    {
-
 
307
        HEIZINDEX *act;
-
 
308
 
-
 
309
        GetTemp();
-
 
310
        sleep_sec = 300;
-
 
311
 
-
 
312
        // Compare the actual temperature with the one that should be
-
 
313
        // and switch heating on or off
-
 
314
        if (HeizFirst)
-
 
315
        {
-
 
316
            int wday;
-
 
317
            unsigned long loctm;
-
 
318
 
-
 
319
            t = time(NULL);
-
 
320
            sleep_sec = 300 - (int)((t + 300L) % 300L);
-
 
321
            sleep_sec++;
341
	pthread_mutex_unlock(&fastmutex_ser);
322
            zeit = localtime(&t);
-
 
323
 
-
 
324
            wday = (zeit->tm_wday == 0) ? 7 : zeit->tm_wday;
-
 
325
            memset(&sz, 0, sizeof(struct tm));
-
 
326
            sz.tm_min = 0;
-
 
327
            sz.tm_hour = 0;
-
 
328
            sz.tm_mon = zeit->tm_mon;
-
 
329
            sz.tm_mday = zeit->tm_mday;
-
 
330
            sz.tm_year = zeit->tm_year;
-
 
331
            sz.tm_isdst = zeit->tm_isdst;
-
 
332
            tstart = mktime(&sz);
-
 
333
            loctm = (t - tstart) + 1; // Seconds since midnight
-
 
334
            act = HeizFirst;
-
 
335
 
-
 
336
            while (act)
-
 
337
            {
-
 
338
                if (act->heizung->wday == wday && loctm >= act->heizung->start && loctm <= act->heizung->end)
-
 
339
                {
-
 
340
                    if (ActTemperature == 9999.0)
-
 
341
                        SwitchOff();     // No temperature, no heating
-
 
342
                    else if (ActTemperature < 5.0)
-
 
343
                        SwitchOn();      // Make sure it will not freeze
-
 
344
                    else if (ActTemperature > 30.0)
-
 
345
                        SwitchOff();     // Don't over heat
-
 
346
                    else if (ActTemperature <= (act->heizung->temp - 0.5))
-
 
347
                        SwitchOn();
-
 
348
                    else if (ActTemperature > act->heizung->temp)
-
 
349
                        SwitchOff();
-
 
350
                }
-
 
351
 
-
 
352
                act = act->next;
-
 
353
            }
-
 
354
        }
-
 
355
        else
-
 
356
            syslog(LOG_DAEMON | LOG_INFO, "Structure not initialized!");
-
 
357
 
-
 
358
        sleep(sleep_sec);        // Wait 5 Minutes
-
 
359
    }
342
}
360
}
343
 
361
 
344
void *processCommands(void *pV_data)
362
void *processCommands(void *pV_data)
345
{
363
{
346
char ch, buf[128];
364
    char ch, buf[128];
347
int i, s1, s;
365
    int i, s1, s;
348
struct SOCKETS *soc;
366
    struct SOCKETS *soc;
-
 
367
    struct timeval tv;
-
 
368
    tv.tv_sec = 1;
-
 
369
    tv.tv_usec = 0;
349
 
370
 
350
	soc = (struct SOCKETS *)pV_data;
371
    soc = (struct SOCKETS *)pV_data;
351
	s1 = soc->newfd;
372
    s1 = soc->newfd;
352
	s = soc->sockfd;
373
    s = soc->sockfd;
353
	memset(&buf[0], 0, sizeof(buf));
374
    memset(&buf[0], 0, sizeof(buf));
354
	i = 0;
375
    i = 0;
355
 
-
 
356
	while (read(s1,&ch,1) > 0)
376
    int bytes = 0;
357
	{
-
 
358
	   if (i < (sizeof(buf) - 1))
377
    setsockopt(s1, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
359
	   {
-
 
360
	      buf[i] = ch;
-
 
361
 
378
 
362
	      if (ch == ';' || ch == 0x0d)
379
    while ((bytes = read(s1, &ch, 1)) > 0 || bytes < 0)
363
	      {
380
    {
364
	      int pstat;
381
        if (killed)
365
 
-
 
366
		 pthread_mutex_lock (&fastmutex_proc);
-
 
367
 
-
 
368
		 if (!strncmp(buf, "quit", 4))
-
 
369
		    break;
382
            break;
370
 
-
 
371
		 if ((pstat = parseCommand(s1,buf)) == 0)
-
 
372
		 {
-
 
373
		 char hv0[128];
-
 
374
 
-
 
375
		    sprintf(&hv0[0],"INVALID COMMAND: %s;",buf);
-
 
376
		    write(s1,hv0,strlen(hv0));
-
 
377
		 }
-
 
378
		 else if (pstat == 2)
-
 
379
		    write(s1, "NAK;", 4);
-
 
380
		 else
-
 
381
		    write(s1,"OK;",3);
-
 
382
 
-
 
383
		 memset(&buf[0], 0, sizeof(buf));
-
 
384
		 i = 0;
-
 
385
		 pthread_mutex_unlock(&fastmutex_proc);
-
 
386
		 continue;
-
 
387
	      }
-
 
388
	   }
-
 
389
 
383
 
-
 
384
        if ((bytes < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) || bytes == 0)
-
 
385
            continue;
-
 
386
        else
-
 
387
            break;
-
 
388
 
-
 
389
        if (i < (sizeof(buf) - 1))
390
	   i++;
390
        {
-
 
391
            buf[i] = ch;
-
 
392
 
-
 
393
            if (ch == ';' || ch == 0x0d)
-
 
394
            {
-
 
395
                int pstat;
-
 
396
 
-
 
397
                if (!strncmp(buf, "quit", 4))
-
 
398
                    break;
-
 
399
 
-
 
400
                if ((pstat = parseCommand(s1, buf)) == 0)
-
 
401
                {
-
 
402
                    char hv0[128];
-
 
403
 
-
 
404
                    sprintf(&hv0[0], "INVALID COMMAND: %s;", buf);
-
 
405
                    write(s1, hv0, strlen(hv0));
-
 
406
                }
-
 
407
                else if (pstat == 2)
-
 
408
                    write(s1, "NAK;", 4);
-
 
409
                else
-
 
410
                    write(s1, "OK;", 3);
-
 
411
 
-
 
412
                memset(&buf[0], 0, sizeof(buf));
-
 
413
                i = 0;
391
	}
414
 
-
 
415
                continue;
-
 
416
            }
-
 
417
        }
392
 
418
 
-
 
419
        i++;
-
 
420
    }
-
 
421
 
-
 
422
    soc->valid = 0;
393
	close(s1);
423
    close(s1);
394
}
424
}
395
 
425
 
396
void *pthr_parser(void *pV_data)
426
void *pthr_parser(void *pV_data)
397
{
427
{
398
char ch, str[INET_ADDRSTRLEN];
428
    char str[INET_ADDRSTRLEN];
399
// socket structure
429
    // socket structure
400
struct sockaddr_in client1, server1;
430
    struct sockaddr_in client1, server1;
401
struct servent *serviceInfo;
431
    struct servent *serviceInfo;
402
int s1, s;
432
    int s1, s;
403
socklen_t length;
433
    socklen_t length;
404
struct SOCKETS soc;
434
    int optval = 1;
-
 
435
 
-
 
436
    memset(&client1, 0, sizeof(client1));
-
 
437
    memset(&server1, 0, sizeof(server1));
-
 
438
    // socket server
-
 
439
    if (configs.port > 0)
-
 
440
        server1.sin_port = htons(configs.port);
-
 
441
    else if ((serviceInfo = getservbyname("heizung", "tcp")))
-
 
442
        server1.sin_port = serviceInfo->s_port;
-
 
443
    else
-
 
444
    {
-
 
445
        syslog(LOG_DAEMON | LOG_ERR, "Error: No TCP port defined!");
-
 
446
        exit(EXIT_FAILURE);
-
 
447
    }
-
 
448
 
-
 
449
    server1.sin_family = AF_INET;
-
 
450
    server1.sin_addr.s_addr = INADDR_ANY;
-
 
451
 
-
 
452
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-
 
453
    {
-
 
454
        syslog(LOG_DAEMON | LOG_ERR, "Error in socket: %s", strerror(errno));
-
 
455
        exit(EXIT_FAILURE);
-
 
456
    }
-
 
457
 
-
 
458
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)) == -1)
-
 
459
    {
-
 
460
        syslog(LOG_DAEMON | LOG_ERR, "Error setting socket options: %s", strerror(errno));
-
 
461
        close(s);
-
 
462
        exit(EXIT_FAILURE);
-
 
463
    }
-
 
464
 
-
 
465
    if (bind(s, (struct sockaddr *)&server1, sizeof(server1)) < 0)
-
 
466
    {
-
 
467
        syslog(LOG_DAEMON | LOG_ERR, "Error in bind: %s", strerror(errno));
-
 
468
        close(s);
-
 
469
        exit(EXIT_FAILURE);
-
 
470
    }
-
 
471
 
-
 
472
    if (listen(s, 5) < 0)
-
 
473
    {
-
 
474
        syslog(LOG_DAEMON | LOG_ERR, "Error in listen: %s", strerror(errno));
-
 
475
        close(s);
-
 
476
        exit(EXIT_FAILURE);
-
 
477
    }
-
 
478
 
-
 
479
    length = sizeof(client1);
-
 
480
    syslog(LOG_DAEMON | LOG_DEBUG, "Server ready: %d", s);
-
 
481
 
-
 
482
    while (!killed)
-
 
483
    {
-
 
484
        // Read time table at every loop, to be sure to have the latest
-
 
485
        // version (User may change it at every time)
-
 
486
        if (!readHeizPlan())
-
 
487
        {
-
 
488
            if (!HeizFirst)
-
 
489
            {
-
 
490
                syslog(LOG_DAEMON | LOG_ERR, "Error reading table %s with plan!", configs.HeizPath);
-
 
491
                exit(EXIT_FAILURE);
-
 
492
            }
-
 
493
            else
-
 
494
                syslog(LOG_DAEMON | LOG_ERR, "Error reading table with plan! Will work with old one.");
-
 
495
        }
-
 
496
 
-
 
497
        if ((s1 = accept(s, (struct sockaddr *)&client1, &length)) < 0)
-
 
498
        {
-
 
499
            syslog(LOG_DAEMON | LOG_ERR, "Error in accept: %d: %s", s1, strerror(errno));
-
 
500
            continue;
-
 
501
        }
-
 
502
 
-
 
503
        inet_ntop(AF_INET, &(client1.sin_addr), str, INET_ADDRSTRLEN);
-
 
504
        syslog(LOG_DAEMON | LOG_INFO, "Connected to client %s", str);
-
 
505
        soc.sockfd = s;
-
 
506
        soc.newfd = s1;
-
 
507
        soc.valid = 1;
-
 
508
 
-
 
509
        if (pthread_create(&pthr_process, NULL, processCommands, (void *)&soc) != 0)
-
 
510
        {
-
 
511
            syslog(LOG_DAEMON | LOG_ERR, "Create of thread \"pthr_parser\" failed!");
-
 
512
            close(s1);
-
 
513
        }
-
 
514
 
-
 
515
        pthread_detach(pthr_process);
-
 
516
    }
-
 
517
 
-
 
518
    close(s1);
-
 
519
    close(s);
-
 
520
    serial_close();
-
 
521
    return NULL;
-
 
522
}
405
 
523
 
406
	// socket server
-
 
407
	if (configs.port > 0)
524
void *pthr_report(void *pV_data)
408
	   server1.sin_port = htons(configs.port);
-
 
409
	else if ((serviceInfo = getservbyname ("heizung", "tcp")))
-
 
410
	   server1.sin_port = serviceInfo->s_port;
-
 
411
	else
-
 
412
	{
-
 
413
	   syslog(LOG_DAEMON,"Error: No TCP port defined!");
-
 
414
	   exit(EXIT_FAILURE);
-
 
415
	}
-
 
416
 
-
 
417
	server1.sin_family = AF_INET;
-
 
418
	server1.sin_addr.s_addr = INADDR_ANY;
-
 
419
	s = socket(AF_INET,SOCK_STREAM,0);
-
 
420
 
-
 
421
	if (s < 0)
-
 
422
	{
-
 
423
	   syslog (LOG_DAEMON, "Error in socket: %s",strerror(errno));
-
 
424
	   exit(EXIT_FAILURE);
-
 
425
	}
-
 
426
 
-
 
427
	if (bind (s, (struct sockaddr *)&server1, sizeof (server1)) < 0)
-
 
428
	{
525
{
429
	   syslog (LOG_DAEMON, "Error in bind: %s", strerror(errno));
-
 
430
	   exit(EXIT_FAILURE);
-
 
431
	}
-
 
432
 
-
 
433
	if (listen (s, 5) < 0)
526
    int oldState = HeatStatus;
434
	{
-
 
435
	   syslog (LOG_DAEMON, "Error in listen: %s", strerror(errno));
-
 
436
	   exit(EXIT_FAILURE);
527
    char hv0[256];
437
	}
-
 
438
 
-
 
439
	length = sizeof(client1);
-
 
440
        syslog (LOG_DEBUG, "Server ready: %d",s);
-
 
441
 
528
 
442
	while (1)
-
 
443
	{
-
 
444
//	   pthread_mutex_lock (&fastmutex);
-
 
445
	   // Read time table at every loop, to be sure to have the latest
-
 
446
	   // version (User may change it at every time)
-
 
447
	   if (!readHeizPlan())
529
    while(!killed)
448
	   {
530
    {
449
	      if (!HeizFirst)
531
        if (soc.valid && oldState != HeatStatus)
450
	      {
532
        {
451
		 syslog(LOG_DAEMON, "Error reading table %s with plan!", configs.HeizPath);
-
 
452
		 exit(EXIT_FAILURE);
-
 
453
	      }
-
 
454
	      else
-
 
455
		 syslog(LOG_DAEMON, "Error reading table with plan! Will work with old one.");
-
 
456
	   }
-
 
457
 
-
 
458
//	   pthread_mutex_unlock(&fastmutex);
-
 
459
 
-
 
460
	   if ((s1 = accept (s, (struct sockaddr *)&client1, &length)) < 0)
533
            snprintf(&hv0[0], sizeof(hv0), "HEATSTAT:%d;", HeatStatus);
461
	   {
-
 
462
	      syslog (LOG_DAEMON, "Error in accept: %d: %s", s1, strerror(errno));
534
            write(soc.newfd, &hv0[0], strlen(hv0));
463
	      continue;
535
            oldState = HeatStatus;
464
	   }
536
        }
465
 
-
 
466
	   inet_ntop(AF_INET, &(client1.sin_addr), str, INET_ADDRSTRLEN);
-
 
467
	   syslog (LOG_INFO, "Connected to client %s", str);
-
 
468
	   soc.sockfd = s;
-
 
469
	   soc.newfd = s1;
-
 
470
 
537
 
471
	   if (pthread_create(&pthr_process, NULL, processCommands, (void *)&soc) != 0)
-
 
472
	   {
-
 
473
	      syslog (LOG_DAEMON,"Create of thread \"pthr_parser\" failed!");
-
 
474
	      close(s1);
538
        sleep(1);
475
	   }
539
    }
476
	}
-
 
477
 
540
 
478
	close (s);
-
 
479
	serial_close();
-
 
480
	return NULL;
541
    return NULL;
481
}
542
}
482
 
543
 
483
void sendList(int s1)
544
void sendList(int s1)
484
{
545
{
485
char hv0[256];
546
    char hv0[256];
486
int i, wday = 1;
547
    int i, wday = 1;
487
HEIZINDEX *act;
548
    HEIZINDEX *act;
488
 
549
 
489
	// We will write out the week days in the correct order.
550
    // We will write out the week days in the correct order.
490
	// So we need 2 loops. The first one is runnung for every week day
551
    // So we need 2 loops. The first one is runnung for every week day
491
	// and the 2nd one will find every entry for the actual week day.
552
    // and the 2nd one will find every entry for the actual week day.
492
	while (wday <= 7)
553
    while (wday <= 7)
493
	{
554
    {
494
	   act = HeizFirst;
555
        act = HeizFirst;
495
	   i = 1;		// The line counter --> reset it to 1 for every week day
556
        i = 1;       // The line counter --> reset it to 1 for every week day
496
 
-
 
497
	   while (act)
-
 
498
	   {
-
 
499
	      if (act->heizung->wday == wday)
-
 
500
	      {
-
 
501
		 sprintf(&hv0[0], "LINE:%d:%d:%lu:%lu:%.1f;", i, act->heizung->wday,
-
 
502
			act->heizung->start, act->heizung->end, act->heizung->temp);
-
 
503
		 write(s1, &hv0[0], strlen(hv0));
-
 
504
		 i++;
-
 
505
	      }
-
 
506
 
557
 
507
	      act = act->next;
558
        while (act)
508
	   }
559
        {
-
 
560
            if (act->heizung->wday == wday)
-
 
561
            {
-
 
562
                sprintf(&hv0[0], "LINE:%d:%d:%lu:%lu:%.1f;", i, act->heizung->wday,
-
 
563
                        act->heizung->start, act->heizung->end, act->heizung->temp);
-
 
564
                write(s1, &hv0[0], strlen(hv0));
-
 
565
                i++;
-
 
566
            }
509
 
567
 
-
 
568
            act = act->next;
-
 
569
        }
-
 
570
 
510
	   wday++;
571
        wday++;
511
	}
572
    }
512
}
573
}
513
 
574
 
514
int listSchemas(int s1)
575
int listSchemas(int s1)
515
{
576
{
516
char hv0[256];
577
    char hv0[256];
517
DIR *dir;	
578
    DIR *dir;
518
struct dirent *de;
579
    struct dirent *de;
519
char *ldup, *lp;
580
    char *ldup, *lp;
520
 
581
 
521
	if ((ldup = strdup(configs.HeizPath)) == NULL)
582
    if ((ldup = strdup(configs.HeizPath)) == NULL)
522
	{
583
    {
523
	   syslog(LOG_DAEMON, "Not enough memory for path: %s", strerror(errno));
584
        syslog(LOG_DAEMON | LOG_ERR, "Not enough memory for path: %s", strerror(errno));
524
	   return 2;
585
        return 2;
525
	}
586
    }
526
 
587
 
527
	lp = dirname(ldup);
588
    lp = dirname(ldup);
528
 
589
 
529
	if ((dir = opendir(lp)) == NULL)
590
    if ((dir = opendir(lp)) == NULL)
530
	{
591
    {
531
	   syslog(LOG_DAEMON, "Could not open directory %s: %s", lp, strerror(errno));
592
        syslog(LOG_DAEMON | LOG_ERR, "Could not open directory %s: %s", lp, strerror(errno));
532
	   free(ldup);
593
        free(ldup);
533
	   return 2;
594
        return 2;
534
	}
595
    }
535
 
596
 
536
	strcpy(&hv0[0], "SCHEMA START;");
597
    strcpy(&hv0[0], "SCHEMA START;");
537
	write(s1, hv0, strlen(hv0));
598
    write(s1, hv0, strlen(hv0));
538
 
599
 
539
	while ((de = readdir(dir)) != NULL)
600
    while ((de = readdir(dir)) != NULL)
540
	{
601
    {
541
	   if (de->d_type == DT_REG && strstr(de->d_name, ".heat") != NULL)
602
        if (de->d_type == DT_REG && strstr(de->d_name, ".heat") != NULL)
542
	   {
603
        {
543
	   char dn[256], *p;
604
            char dn[256], *p;
544
 
605
 
545
	      memset(&dn[0], 0, sizeof(dn));
606
            memset(&dn[0], 0, sizeof(dn));
546
	      strncpy(dn, de->d_name, sizeof(dn)-1);
607
            strncpy(dn, de->d_name, sizeof(dn) - 1);
547
 
608
 
548
	      if ((p = strrchr(dn, '.')) != NULL)
609
            if ((p = strrchr(dn, '.')) != NULL)
549
		 *p = 0;
610
                * p = 0;
550
	      else
611
            else
551
		 continue;
612
                continue;
552
 
613
 
553
	      sprintf(&hv0[0], "SCHEMA FILE:%s;", dn);
614
            sprintf(&hv0[0], "SCHEMA FILE:%s;", dn);
554
	      write(s1, hv0, strlen(hv0));
615
            write(s1, hv0, strlen(hv0));
555
	   }
616
        }
556
	}
617
    }
557
 
618
 
558
	closedir(dir);
619
    closedir(dir);
559
	free(ldup);
620
    free(ldup);
560
	return 1;
621
    return 1;
561
}
622
}
562
 
623
 
563
int parseCommand(int s1, char *cmd)
624
int parseCommand(int s1, char *cmd)
564
{
625
{
565
char bef[32],par[1024], *p;
626
    char bef[32], par[1024], *p;
566
char hv0[256];
627
    char hv0[256];
567
int i,j;
628
    int i, j;
568
HEIZINDEX *act, *last;
629
    HEIZINDEX *act, *last;
569
 
630
 
570
	memset(bef,0,sizeof(bef));
631
    memset(bef, 0, sizeof(bef));
571
	memset(par,0,sizeof(par));
632
    memset(par, 0, sizeof(par));
572
 
633
 
573
	if ((p = strchr(cmd,':')) != NULL)		// do we have a parameter?
634
    if ((p = strchr(cmd, ':')) != NULL)     // do we have a parameter?
574
	{
635
    {
575
	   strncpy(bef,cmd,p - cmd);
636
        strncpy(bef, cmd, p - cmd);
576
	   strncpy(par,p+1,strlen(p)-2);	// Cut off the trailing semi colon
637
        strncpy(par, p + 1, strlen(p) - 2); // Cut off the trailing semi colon
577
	}
638
    }
578
	else
639
    else
579
	   strncpy(bef,cmd,strlen(cmd)-1);
640
        strncpy(bef, cmd, strlen(cmd) - 1);
580
 
641
 
581
	if (!strcasecmp(bef, "LIST"))		// Write out current list
642
    if (!strcasecmp(bef, "LIST"))       // Write out current list
582
	   sendList(s1);
643
        sendList(s1);
583
 
644
 
584
	if (!strcasecmp(bef, "GET WDAY"))		// Write out a particular week day
645
    if (!strcasecmp(bef, "GET WDAY"))       // Write out a particular week day
585
	{
646
    {
586
	int wday = atoi(par);
647
        int wday = atoi(par);
587
 
648
 
588
	   if (wday < 1 || wday > 7)
649
        if (wday < 1 || wday > 7)
589
	   {
650
        {
590
	      strcpy(&hv0[0], "ERROR:Invalid week day");
651
            strcpy(&hv0[0], "ERROR:Invalid week day");
591
	      write(s1, &hv0[0], strlen(hv0));
652
            write(s1, &hv0[0], strlen(hv0));
592
	      return 0;
653
            return 0;
593
	   }
654
        }
594
 
655
 
595
	   act = HeizFirst;
656
        act = HeizFirst;
596
 
657
 
597
	   while (act && act->heizung->wday != wday)
658
        while (act && act->heizung->wday != wday)
598
	      act = act->next;
659
            act = act->next;
599
 
660
 
600
	   if (!act)
661
        if (!act)
601
	   {
662
        {
602
	      sprintf(&hv0[0], "ERROR:No plan for week day %d", wday);
663
            sprintf(&hv0[0], "ERROR:No plan for week day %d", wday);
603
	      write(s1, &hv0[0], strlen(hv0));
664
            write(s1, &hv0[0], strlen(hv0));
604
	      return 0;
665
            return 0;
605
	   }
666
        }
606
 
667
 
607
	   i = 1;
668
        i = 1;
608
 
669
 
609
	   while (act && act->heizung->wday == wday)
670
        while (act && act->heizung->wday == wday)
610
	   {
671
        {
611
	      sprintf(&hv0[0], "LINE:%d:%d:%lu:%lu:%.1f;", i, act->heizung->wday,
672
            sprintf(&hv0[0], "LINE:%d:%d:%lu:%lu:%.1f;", i, act->heizung->wday,
612
		      act->heizung->start, act->heizung->end, act->heizung->temp);
673
                    act->heizung->start, act->heizung->end, act->heizung->temp);
613
	      write(s1, &hv0[0], strlen(hv0));
674
            write(s1, &hv0[0], strlen(hv0));
614
	      i++;
675
            i++;
615
	      act = act->next;
676
            act = act->next;
616
	   }
677
        }
617
	}
678
    }
618
 
679
 
619
	if (!strcasecmp(bef, "GET TEMP"))	// Return actual temperature
680
    if (!strcasecmp(bef, "GET TEMP"))   // Return actual temperature
620
	{
681
    {
621
	   sprintf(&hv0[0], "TEMP:%.1f;", ActTemperature);
682
        sprintf(&hv0[0], "TEMP:%.1f;", ActTemperature);
622
	   write(s1, &hv0[0], strlen(hv0));
683
        write(s1, &hv0[0], strlen(hv0));
623
	}
684
    }
624
 
685
 
625
	if (!strcasecmp(bef, "GET PRESSURE"))	// Return the actual air pressure
686
    if (!strcasecmp(bef, "GET PRESSURE"))   // Return the actual air pressure
626
	{
687
    {
627
	   sprintf(&hv0[0], "PRESSURE:%.1f;", ActPressure);
688
        sprintf(&hv0[0], "PRESSURE:%.1f;", ActPressure);
628
	   write(s1, &hv0[0], strlen(hv0));
689
        write(s1, &hv0[0], strlen(hv0));
629
	}
690
    }
630
 
691
 
631
        if (!strcasecmp(bef, "HEATSTAT"))	// Return the status of the heating
692
    if (!strcasecmp(bef, "HEATSTAT"))   // Return the status of the heating
632
        {
693
    {
633
	   sprintf(&hv0[0], "HEATSTAT:%d;", HeatStatus);
694
        sprintf(&hv0[0], "HEATSTAT:%d;", HeatStatus);
634
	   write(s1, &hv0[0], strlen(hv0));
695
        write(s1, &hv0[0], strlen(hv0));
635
	}
696
    }
636
 
697
 
637
	// SET DAY:<count>:<day>:<end1>:<temp>[:<end2>:<temp>[:...]];
698
    // SET DAY:<count>:<day>:<end1>:<temp>[:<end2>:<temp>[:...]];
638
	// <count>   number of entries following
699
    // <count>   number of entries following
639
	// <day>     The day of the week
700
    // <day>     The day of the week
640
	// <end1>    The end time
701
    // <end1>    The end time
641
	// <temp>    The temperature wanted until end time is reached
702
    // <temp>    The temperature wanted until end time is reached
642
	//
703
    //
643
	if (!strcasecmp(bef, "SET DAY"))		// Set the plan for a particular day
704
    if (!strcasecmp(bef, "SET DAY"))        // Set the plan for a particular day
644
	{
705
    {
645
	int count, wday, i;
706
        int count, wday, i;
646
	long endt;
707
        long endt;
647
	float temp;
708
        float temp;
648
 
709
 
649
	   count = atoi(par);
710
        count = atoi(par);
650
	   remove_string(par, ":", &hv0[0]);
711
        remove_string(par, ":", &hv0[0]);
651
	   wday = atoi(par);
712
        wday = atoi(par);
652
	   freeDay(wday);
713
        freeDay(wday);
653
	   last = NULL;
714
        last = NULL;
654
 
715
 
655
	   if (count > 0)
716
        if (count > 0)
656
	   {
717
        {
657
	      for (i = 0; i < count; i++)
718
            for (i = 0; i < count; i++)
658
	      {
719
            {
659
		 remove_string(par, ":", &hv0[0]);
720
                remove_string(par, ":", &hv0[0]);
660
		 endt = atol(par);
721
                endt = atol(par);
661
		 remove_string(par, ":", &hv0[0]);
722
                remove_string(par, ":", &hv0[0]);
662
		 temp = atof(par);
723
                temp = atof(par);
663
 
724
 
664
		 if ((act = allocateMemory()) == NULL)
725
                if ((act = allocateMemory()) == NULL)
665
		 {
726
                {
666
		    syslog(LOG_DAEMON,"Error allocating memory for a temperature line.");
727
                    syslog(LOG_DAEMON, "Error allocating memory for a temperature line.");
667
		    sprintf(&hv0[0], "ERROR:Not enough memory!");
728
                    sprintf(&hv0[0], "ERROR:Not enough memory!");
668
		    write(s1, &hv0[0], strlen(hv0));
729
                    write(s1, &hv0[0], strlen(hv0));
669
		    return 2;
730
                    return 2;
670
		 }
731
                }
671
 
732
 
672
		 act->heizung->wday = wday;
733
                act->heizung->wday = wday;
673
		 act->heizung->end = endt;
734
                act->heizung->end = endt;
674
		 act->heizung->temp = temp;
735
                act->heizung->temp = temp;
675
 
736
 
676
		 if (last)
737
                if (last)
677
		    act->heizung->start = last->heizung->end;
738
                    act->heizung->start = last->heizung->end;
678
		 else
739
                else
679
		    act->heizung->start = 0L;
740
                    act->heizung->start = 0L;
680
 
-
 
681
		 last = act;
-
 
682
	      }
-
 
683
 
-
 
684
	      writeHeizPlan();
-
 
685
	   }
-
 
686
	}
-
 
687
 
-
 
688
	// SET TEMP:<wday>:<end>:<temp>;
-
 
689
	if (!strcasecmp(bef, "SET TEMP"))	// Set the temperature for a particular day and line
-
 
690
	{
-
 
691
	int wday;
-
 
692
	unsigned long endt;
-
 
693
	float tmp;
-
 
694
 
-
 
695
	   wday = atoi(par);
-
 
696
	   remove_string(par, ":", &hv0[0]);
-
 
697
	   endt = atol(par);
-
 
698
	   remove_string(par, ":", &hv0[0]);
-
 
699
	   tmp = atof(par);
-
 
700
	   insertMember(wday, endt, tmp);
-
 
701
	   writeHeizPlan();
-
 
702
	}
-
 
703
 
-
 
704
	// SAVE SCHEMA:<name>;
-
 
705
	if (!strcasecmp(bef, "SAVE SCHEMA"))	// Save the current heating plan into a file
-
 
706
        {
-
 
707
	   sprintf(&hv0[0], "%s.heat", par);
-
 
708
 
-
 
709
	   if (!writeHeizPlanName(hv0))
-
 
710
	      return 2;
-
 
711
	}
-
 
712
 
-
 
713
	// LOAD SCHEMA:<name>;
-
 
714
	if (!strcasecmp(bef, "LOAD SCHEMA"))	// Load a previous saved schema from a file
-
 
715
	{
-
 
716
	   sprintf(&hv0[0], "%s.heat", par);
-
 
717
 
-
 
718
	   if (!readHeizPlanName(hv0))
-
 
719
	      return 2;
-
 
720
 
-
 
721
	   // write the new schema immediately to the default file
-
 
722
	   writeHeizPlan();
-
 
723
	   sendList(s1);
-
 
724
	}
-
 
725
 
-
 
726
	// DELETE SCHEMA:<name>;
-
 
727
	if (!strcasecmp(bef, "DELETE SCHEMA"))	// Delete an existing schema
-
 
728
        {
-
 
729
	   makeFileName(&hv0[0], par, sizeof(hv0));
-
 
730
	   
-
 
731
	   if (strlen(hv0) < (sizeof(hv0) - 6))
-
 
732
	      strcat(&hv0[0], ".heat");
-
 
733
	   else
-
 
734
	   {
-
 
735
	      syslog(LOG_DAEMON, "File name too large for internal buffer");
-
 
736
	      return 2;
-
 
737
	   }
-
 
738
 
-
 
739
	   if (access(hv0, R_OK | W_OK))
-
 
740
	   {
-
 
741
	      syslog(LOG_DAEMON,"No access to file %s: %s", hv0, strerror(errno));
-
 
742
	      return 2;
-
 
743
	   }
-
 
744
 
-
 
745
	   if (unlink(hv0) == -1)
-
 
746
	   {
-
 
747
	      syslog(LOG_DAEMON,"Error deleting file %s: %s", hv0, strerror(errno));
-
 
748
	      return 2;
-
 
749
	   }
-
 
750
 
-
 
751
	   return listSchemas(s1);
-
 
752
	}
-
 
753
 
-
 
754
	// LIST SCHEMA;
-
 
755
	if (!strcasecmp(bef, "LIST SCHEMA"))	// Return a list of all available schamas
-
 
756
	   return listSchemas(s1);
-
 
757
 
741
 
-
 
742
                last = act;
-
 
743
            }
-
 
744
 
-
 
745
            writeHeizPlan();
-
 
746
        }
-
 
747
    }
-
 
748
 
-
 
749
    // SET TEMP:<wday>:<end>:<temp>;
-
 
750
    if (!strcasecmp(bef, "SET TEMP"))   // Set the temperature for a particular day and line
-
 
751
    {
-
 
752
        int wday;
-
 
753
        unsigned long endt;
-
 
754
        float tmp;
-
 
755
 
-
 
756
        wday = atoi(par);
-
 
757
        remove_string(par, ":", &hv0[0]);
-
 
758
        endt = atol(par);
-
 
759
        remove_string(par, ":", &hv0[0]);
-
 
760
        tmp = atof(par);
-
 
761
        insertMember(wday, endt, tmp);
-
 
762
        writeHeizPlan();
-
 
763
    }
-
 
764
 
-
 
765
    // SAVE SCHEMA:<name>;
-
 
766
    if (!strcasecmp(bef, "SAVE SCHEMA"))    // Save the current heating plan into a file
-
 
767
    {
-
 
768
        sprintf(&hv0[0], "%s.heat", par);
-
 
769
 
-
 
770
        if (!writeHeizPlanName(hv0))
-
 
771
            return 2;
-
 
772
    }
-
 
773
 
-
 
774
    // LOAD SCHEMA:<name>;
-
 
775
    if (!strcasecmp(bef, "LOAD SCHEMA"))    // Load a previous saved schema from a file
-
 
776
    {
-
 
777
        sprintf(&hv0[0], "%s.heat", par);
-
 
778
 
-
 
779
        if (!readHeizPlanName(hv0))
-
 
780
            return 2;
-
 
781
 
-
 
782
        // write the new schema immediately to the default file
-
 
783
        writeHeizPlan();
-
 
784
        sendList(s1);
-
 
785
    }
-
 
786
 
-
 
787
    // DELETE SCHEMA:<name>;
-
 
788
    if (!strcasecmp(bef, "DELETE SCHEMA"))  // Delete an existing schema
-
 
789
    {
-
 
790
        makeFileName(&hv0[0], par, sizeof(hv0));
-
 
791
 
-
 
792
        if (strlen(hv0) < (sizeof(hv0) - 6))
-
 
793
            strcat(&hv0[0], ".heat");
-
 
794
        else
-
 
795
        {
-
 
796
            syslog(LOG_DAEMON, "File name too large for internal buffer");
-
 
797
            return 2;
-
 
798
        }
-
 
799
 
-
 
800
        if (access(hv0, R_OK | W_OK))
-
 
801
        {
-
 
802
            syslog(LOG_DAEMON, "No access to file %s: %s", hv0, strerror(errno));
-
 
803
            return 2;
-
 
804
        }
-
 
805
 
-
 
806
        if (unlink(hv0) == -1)
-
 
807
        {
-
 
808
            syslog(LOG_DAEMON, "Error deleting file %s: %s", hv0, strerror(errno));
-
 
809
            return 2;
-
 
810
        }
-
 
811
 
-
 
812
        return listSchemas(s1);
-
 
813
    }
-
 
814
 
-
 
815
    // LIST SCHEMA;
-
 
816
    if (!strcasecmp(bef, "LIST SCHEMA"))    // Return a list of all available schamas
-
 
817
        return listSchemas(s1);
-
 
818
 
758
	return 1;
819
    return 1;
759
}
820
}
760
 
821
 
761
/*
822
/*
762
 * Remove a complete day
823
 * Remove a complete day
763
 */
824
 */
764
void freeDay(int wday)
825
void freeDay(int wday)
765
{
826
{
766
HEIZINDEX *act, *next, *prev;
827
    HEIZINDEX *act, *next, *prev;
767
 
828
 
768
	act = HeizFirst;
829
    act = HeizFirst;
769
	prev = NULL;
830
    prev = NULL;
770
 
831
 
771
	while(act)
832
    while (act)
772
	{
833
    {
773
	   if (act->heizung->wday == wday)
834
        if (act->heizung->wday == wday)
774
	      act = freeChainMember(act);
835
            act = freeChainMember(act);
775
 
836
 
776
	   act = act->next;
837
        act = act->next;
777
	}  
838
    }
778
}
839
}
779
 
840
 
780
/*
841
/*
781
 * Insert a new entry
842
 * Insert a new entry
782
 */
843
 */
783
void insertMember(int wday, long endt, float temp)
844
void insertMember(int wday, long endt, float temp)
784
{
845
{
785
HEIZINDEX *act;
846
    HEIZINDEX *act;
-
 
847
 
-
 
848
    act = HeizFirst;
786
 
849
 
-
 
850
    while (act)
-
 
851
    {
-
 
852
        if (act->heizung->wday == wday && act->heizung->end == endt)
-
 
853
        {
-
 
854
            act->heizung->temp = temp;
787
	act = HeizFirst;
855
            return;
-
 
856
        }
788
 
857
 
789
	while(act)
-
 
790
	{
-
 
791
	   if (act->heizung->wday == wday && act->heizung->end == endt)
-
 
792
	   {
-
 
793
	      act->heizung->temp = temp;
858
        act = act->next;
794
	      return;
-
 
795
	   }
859
    }
796
 
-
 
797
	   act = act->next;
-
 
798
	}
-
 
799
 
860
 
800
	if ((act = allocateMemory()) != NULL)
861
    if ((act = allocateMemory()) != NULL)
801
	{
862
    {
802
	   act->heizung->wday = wday;
863
        act->heizung->wday = wday;
803
	   act->heizung->end = endt;
864
        act->heizung->end = endt;
804
	   act->heizung->temp = temp;
865
        act->heizung->temp = temp;
805
	}
866
    }
806
}
867
}
807
 
868
 
808
/*
869
/*
809
 * Free the memory for the actual heizung plan.
870
 * Free the memory for the actual heizung plan.
810
 */
871
 */
811
void freeMemory()
872
void freeMemory()
812
{
873
{
813
HEIZINDEX *act, *next;
874
    HEIZINDEX *act, *next;
-
 
875
 
-
 
876
    act = HeizFirst;
814
 
877
 
815
	act = HeizFirst;
878
    while (act)
-
 
879
    {
-
 
880
        if (act->heizung)
-
 
881
        {
-
 
882
            free(act->heizung);
-
 
883
            act->heizung = NULL;
-
 
884
        }
816
 
885
 
817
	while(act)
-
 
818
	{
-
 
819
	   if (act->heizung)
-
 
820
	   {
-
 
821
	      free(act->heizung);
-
 
822
	      act->heizung = NULL;
-
 
823
	   }
-
 
824
 
-
 
825
	   next = act->next;
886
        next = act->next;
826
	   free(act);
887
        free(act);
827
	   act = next;
888
        act = next;
828
	}
889
    }
829
 
890
 
830
	HeizFirst = NULL;
891
    HeizFirst = NULL;
831
}
892
}
832
 
893
 
833
/*
894
/*
834
 * Free only one entry in the chain
895
 * Free only one entry in the chain
835
 */
896
 */
836
HEIZINDEX *freeChainMember(HEIZINDEX *member)
897
HEIZINDEX *freeChainMember(HEIZINDEX *member)
837
{
898
{
838
HEIZINDEX *act,*prev;
899
    HEIZINDEX *act, *prev;
-
 
900
 
-
 
901
    act = HeizFirst;
-
 
902
    prev = NULL;
-
 
903
 
-
 
904
    while (act != member)
-
 
905
    {
-
 
906
        prev = act;
-
 
907
        act = act->next;
-
 
908
    }
-
 
909
 
-
 
910
    if (act == member)
-
 
911
    {
-
 
912
        if (prev)
-
 
913
            prev->next = act->next;
-
 
914
        else
-
 
915
        {
-
 
916
            prev = act->next;
-
 
917
 
-
 
918
            if (act == HeizFirst)
-
 
919
                HeizFirst = act->next;
-
 
920
        }
839
 
921
 
840
	act = HeizFirst;
922
        if (act->heizung)
841
	prev = NULL;
923
            free(act->heizung);
842
 
924
 
843
	while(act != member)
-
 
844
	{
-
 
845
	   prev = act;
-
 
846
	   act = act->next;
-
 
847
	}
-
 
848
 
-
 
849
	if (act == member)
-
 
850
	{
-
 
851
	   if (prev)
-
 
852
	      prev->next = act->next;
-
 
853
	   else
-
 
854
	   {
-
 
855
	      prev = act->next;
-
 
856
 
-
 
857
	      if (act == HeizFirst)
-
 
858
		 HeizFirst = act->next;
-
 
859
	   }
-
 
860
 
-
 
861
	   if (act->heizung)
-
 
862
	      free(act->heizung);
-
 
863
 
-
 
864
	   free(act);
925
        free(act);
865
	   return prev;
926
        return prev;
866
	}
927
    }
867
 
928
 
868
	return NULL;
929
    return NULL;
869
}
930
}
870
 
931
 
871
/*
932
/*
872
 * Allocate the memory for the actual heizung plan.
933
 * Allocate the memory for the actual heizung plan.
873
 * This function appends an element to the end of the chain.
934
 * This function appends an element to the end of the chain.
874
 */
935
 */
875
HEIZINDEX *allocateMemory()
936
HEIZINDEX *allocateMemory()
876
{
937
{
877
HEIZINDEX *act, *last;
938
    HEIZINDEX *act, *last;
878
 
939
 
879
	if (!HeizFirst)
-
 
880
	{
-
 
881
	   HeizFirst = malloc(sizeof(HEIZINDEX));
-
 
882
 
-
 
883
	   if (HeizFirst)
940
    if (!HeizFirst)
884
	   {
941
    {
885
	      HeizFirst->heizung = malloc(sizeof(HEIZUNG));
942
        HeizFirst = malloc(sizeof(HEIZINDEX));
886
	      HeizFirst->next = NULL;
-
 
887
	   }
-
 
888
	   else
-
 
889
	      return NULL;
-
 
890
 
-
 
891
	   return HeizFirst;
-
 
892
	}
-
 
893
	else
-
 
894
	{
-
 
895
	   // Find last element
-
 
896
	   last = HeizFirst;
-
 
897
 
-
 
898
	   while(last->next)
-
 
899
	      last = last->next;
-
 
900
 
-
 
901
	   act = malloc(sizeof(HEIZINDEX));
-
 
902
 
-
 
903
	   if (act)
-
 
904
	   {
-
 
905
	      act->heizung = malloc(sizeof(HEIZUNG));
-
 
906
	      act->next = NULL;
-
 
907
	      last->next = act;
-
 
908
	   }
-
 
909
	   else
-
 
910
	      return NULL;
-
 
911
 
943
 
-
 
944
        if (HeizFirst)
-
 
945
        {
-
 
946
            HeizFirst->heizung = malloc(sizeof(HEIZUNG));
-
 
947
            HeizFirst->next = NULL;
-
 
948
        }
-
 
949
        else
912
	   return act;
950
            return NULL;
913
	}
951
 
-
 
952
        return HeizFirst;
-
 
953
    }
-
 
954
    else
-
 
955
    {
-
 
956
        // Find last element
-
 
957
        last = HeizFirst;
914
 
958
 
-
 
959
        while (last->next)
-
 
960
            last = last->next;
-
 
961
 
-
 
962
        act = malloc(sizeof(HEIZINDEX));
-
 
963
 
-
 
964
        if (act)
-
 
965
        {
-
 
966
            act->heizung = malloc(sizeof(HEIZUNG));
-
 
967
            act->next = NULL;
-
 
968
            last->next = act;
-
 
969
        }
-
 
970
        else
-
 
971
            return NULL;
-
 
972
 
-
 
973
        return act;
-
 
974
    }
-
 
975
 
915
	return NULL;
976
    return NULL;
916
}
977
}
917
 
978
 
918
/*
979
/*
919
 * Allocate the memory for the actual heizung plan.
980
 * Allocate the memory for the actual heizung plan.
920
 * This function inserts an element into the chain.
981
 * This function inserts an element into the chain.
921
 */
982
 */
922
HEIZINDEX *insertMemory(HEIZINDEX *pos)
983
HEIZINDEX *insertMemory(HEIZINDEX *pos)
923
{
984
{
924
HEIZINDEX *act;
985
    HEIZINDEX *act;
-
 
986
 
-
 
987
    if (!HeizFirst)
-
 
988
    {
-
 
989
        HeizFirst = malloc(sizeof(HEIZINDEX));
-
 
990
 
-
 
991
        if (HeizFirst)
-
 
992
        {
-
 
993
            HeizFirst->heizung = malloc(sizeof(HEIZUNG));
-
 
994
            HeizFirst->next = NULL;
-
 
995
        }
-
 
996
        else
-
 
997
            return NULL;
-
 
998
 
-
 
999
        return HeizFirst;
-
 
1000
    }
-
 
1001
    else
-
 
1002
    {
-
 
1003
        act = malloc(sizeof(HEIZINDEX));
925
 
1004
 
926
	if (!HeizFirst)
-
 
927
	{
-
 
928
	   HeizFirst = malloc(sizeof(HEIZINDEX));
-
 
929
 
-
 
930
	   if (HeizFirst)
-
 
931
	   {
-
 
932
	      HeizFirst->heizung = malloc(sizeof(HEIZUNG));
-
 
933
	      HeizFirst->next = NULL;
-
 
934
	   }
-
 
935
	   else
-
 
936
	      return NULL;
-
 
937
 
-
 
938
	   return HeizFirst;
-
 
939
	}
-
 
940
	else
-
 
941
	{
-
 
942
	   act = malloc(sizeof(HEIZINDEX));
-
 
943
 
-
 
944
	   if (act)
1005
        if (act)
945
	   {
1006
        {
946
	      act->heizung = malloc(sizeof(HEIZUNG));
1007
            act->heizung = malloc(sizeof(HEIZUNG));
947
	      act->next = pos->next;
1008
            act->next = pos->next;
948
	      pos->next = act;
1009
            pos->next = act;
949
	   }
1010
        }
950
	   else
1011
        else
951
	      return NULL;
1012
            return NULL;
952
 
1013
 
953
	   return act;
1014
        return act;
954
	}
1015
    }
955
 
1016
 
956
	return NULL;
1017
    return NULL;
957
}
1018
}
958
 
1019
 
959
/*
1020
/*
960
 * The following functions read a config file and put the
1021
 * The following functions read a config file and put the
961
 * contents into a structure.
1022
 * contents into a structure.
962
 */
1023
 */
963
void readConf(void)
1024
void readConf(void)
964
{
1025
{
965
int fd;
1026
    int fd;
966
char confFile[512], line[512];
1027
    char confFile[512], line[512];
967
char *home, *p;
1028
    char *home, *p;
968
char hv0[64], hv1[128];
1029
    char hv0[64], hv1[128];
969
 
1030
 
970
	home = getenv("HOME");
1031
    home = getenv("HOME");
971
	fd = -1;
1032
    fd = -1;
972
 
1033
 
973
	if (!access("/etc/heizung.conf",R_OK))
1034
    if (!access("/etc/heizung.conf", R_OK))
974
	   strcpy(confFile,"/etc/heizung.conf");
1035
        strcpy(confFile, "/etc/heizung.conf");
975
	else if (!access("/etc/heizung/heizung.conf",R_OK))
1036
    else if (!access("/etc/heizung/heizung.conf", R_OK))
976
	   strcpy(confFile,"/etc/heizung/heizung.conf");
1037
        strcpy(confFile, "/etc/heizung/heizung.conf");
977
	else if (!access("/usr/etc/heizung.conf",R_OK))
1038
    else if (!access("/usr/etc/heizung.conf", R_OK))
978
	   strcpy(confFile,"/usr/etc/heizung.conf");
1039
        strcpy(confFile, "/usr/etc/heizung.conf");
979
	else if (home)
1040
    else if (home)
980
	{
1041
    {
981
	   strcpy(confFile,home);
1042
        strcpy(confFile, home);
982
	   strcat(confFile,"/.heizung.conf");
1043
        strcat(confFile, "/.heizung.conf");
983
 
1044
 
984
	   if (access(confFile,R_OK))
1045
        if (access(confFile, R_OK))
985
	   {
1046
        {
986
	      syslog(LOG_WARNING,"Even config file %s was not found!", confFile);
1047
            syslog(LOG_DAEMON | LOG_WARNING, "Even config file %s was not found!", confFile);
987
	      confFile[0] = 0;
1048
            confFile[0] = 0;
988
	   }
1049
        }
989
	}
1050
    }
990
	else
1051
    else
991
	   confFile[0] = 0;
1052
        confFile[0] = 0;
992
 
1053
 
993
	memset(&configs, 0, sizeof(configs));
1054
    memset(&configs, 0, sizeof(configs));
994
	strcpy(configs.User,"nobody");
1055
    strcpy(configs.User, "nobody");
995
	strcpy(configs.Grp,"nobody");
1056
    strcpy(configs.Grp, "nobody");
996
	strcpy(configs.HeizPath, "/var/www/.HeizPlan.conf");
1057
    strcpy(configs.HeizPath, "/var/www/.HeizPlan.conf");
997
	strcpy(configs.Werte, "/var/log/werte.dat");
1058
    strcpy(configs.Werte, "/var/log/werte.dat");
998
	strcpy(configs.Device, "/dev/ttyS1");
1059
    strcpy(configs.Device, "/dev/ttyS1");
999
	strcpy(configs.Pidfile, "/var/run/heizung.pid");
1060
    strcpy(configs.Pidfile, "/run/heizung.pid");
-
 
1061
#ifdef SENSOR_ETHERNET
-
 
1062
    strcpy(configs.IP, "0.0.0.0");
-
 
1063
#endif
1000
	configs.port = 11001;
1064
    configs.port = 11001;
1001
 
1065
 
1002
	if (!confFile[0] || (fd = open(confFile,O_RDONLY)) == -1)
1066
    if (!confFile[0] || (fd = open(confFile, O_RDONLY)) == -1)
1003
	{
1067
    {
1004
	   if (confFile[0])
1068
        if (confFile[0])
1005
	      syslog(LOG_WARNING,"Error opening the config file %s! Using built in defaults. (%s)", confFile, strerror(errno));
1069
            syslog(LOG_DAEMON | LOG_WARNING, "Error opening the config file %s! Using built in defaults. (%s)", confFile, strerror(errno));
1006
	   else
1070
        else
1007
	      syslog(LOG_WARNING,"Error opening the config file! Using built in defaults.");
1071
            syslog(LOG_DAEMON | LOG_WARNING, "Error opening the config file! Using built in defaults.");
1008
 
1072
 
1009
	   return;
1073
        return;
1010
	}
1074
    }
1011
 
1075
 
1012
	while (readLine(fd, &line[0], sizeof(line)) != NULL)
1076
    while (readLine(fd, &line[0], sizeof(line)) != NULL)
1013
	{
1077
    {
1014
	   int len;
1078
        int len;
1015
 
1079
 
1016
	   trim (&line[0]);
1080
        trim(&line[0]);
1017
 
1081
 
1018
	   if (line[0] == '#' || !strlen(line))
1082
        if (line[0] == '#' || !strlen(line))
1019
	      continue;
-
 
1020
 
-
 
1021
	   if ((p = strchr (line, '=')) == NULL)
-
 
1022
	      continue;
1083
            continue;
1023
 
-
 
1024
	   *p = 0;
-
 
1025
	   p++;
-
 
1026
	   len = strlen(line);
-
 
1027
 
-
 
1028
	   if (len > sizeof(hv0))
-
 
1029
	      len = sizeof(hv0) - 1;
-
 
1030
 
-
 
1031
	   strncpy (hv0, line, len);
-
 
1032
	   hv0[len] = 0;
-
 
1033
	   trim (hv0);
-
 
1034
	   len = strlen(p);
-
 
1035
 
-
 
1036
	   if (len > sizeof(hv1))
-
 
1037
	      len = sizeof(hv0) - 1;
-
 
1038
 
-
 
1039
	   strncpy (hv1, p, len);
-
 
1040
	   hv1[len] = 0;
-
 
1041
	   trim (hv1);
-
 
1042
 
-
 
1043
	   if (!strcasecmp(hv0, "user"))
-
 
1044
	   {
-
 
1045
	      syslog(LOG_INFO,"Found \"user\": %s", hv1);
-
 
1046
	      strncpy (configs.User, hv1, sizeof(configs.User));
-
 
1047
	   }
-
 
1048
 
-
 
1049
	   if (!strcasecmp(hv0, "group"))
-
 
1050
	   {
-
 
1051
	      syslog(LOG_INFO,"Found \"group\": %s", hv1);
-
 
1052
	      strncpy (configs.Grp, hv1, sizeof(configs.Grp));
-
 
1053
	   }
-
 
1054
 
-
 
1055
	   if (!strcasecmp(hv0, "port"))
-
 
1056
	   {
-
 
1057
	      syslog(LOG_INFO,"Found \"port\": %s", hv1);
-
 
1058
	      configs.port = atoi (hv1);
-
 
1059
	   }
-
 
1060
 
-
 
1061
	   if (!strcasecmp(hv0, "heizpath"))
-
 
1062
	   {
-
 
1063
	      syslog(LOG_INFO,"Found \"heizpath\": %s", hv1);
-
 
1064
	      strncpy (configs.HeizPath, hv1, sizeof(configs.HeizPath));
-
 
1065
	   }
-
 
1066
 
-
 
1067
	   if (!strcasecmp(hv0, "Werte"))
-
 
1068
	   {
-
 
1069
	      syslog(LOG_INFO,"Found \"Werte\": %s", hv1);
-
 
1070
	      strncpy (configs.Werte, hv1, sizeof(configs.Werte));
-
 
1071
	   }
-
 
1072
 
-
 
1073
	   if (!strcasecmp(hv0, "Device"))
-
 
1074
	   {
-
 
1075
	      syslog(LOG_INFO,"Found \"Device\": %s", hv1);
-
 
1076
	      strncpy (configs.Device, hv1, sizeof(configs.Device));
-
 
1077
	   }
-
 
1078
 
-
 
1079
	   if (!strcasecmp(hv0, "Pidfile"))
-
 
1080
	   {
-
 
1081
	      syslog(LOG_INFO,"Found \"Pidfile\": %s", hv1);
-
 
1082
	      strncpy (configs.Pidfile, hv1, sizeof(configs.Pidfile));
-
 
1083
	   }
-
 
1084
 
-
 
1085
	   if (!strcasecmp(hv0, "VID"))
-
 
1086
	   {
-
 
1087
	      syslog(LOG_INFO,"Found VendorID: %04x", atoi(hv1));
-
 
1088
	      configs.VID = atoi(hv1);
-
 
1089
	   }
-
 
1090
 
-
 
1091
	   if (!strcasecmp(hv0, "PID"))
-
 
1092
	   {
-
 
1093
	      syslog(LOG_INFO,"Found ProductID: %04x", atoi(hv1));
-
 
1094
	      configs.PID = atoi(hv1);
-
 
1095
	   }
-
 
1096
	}
-
 
1097
 
1084
 
-
 
1085
        if ((p = strchr(line, '=')) == NULL)
-
 
1086
            continue;
-
 
1087
 
-
 
1088
        *p = 0;
-
 
1089
        p++;
-
 
1090
        len = strlen(line);
-
 
1091
 
-
 
1092
        if (len > sizeof(hv0))
-
 
1093
            len = sizeof(hv0) - 1;
-
 
1094
 
-
 
1095
        strncpy(hv0, line, len);
-
 
1096
        hv0[len] = 0;
-
 
1097
        trim(hv0);
-
 
1098
        len = strlen(p);
-
 
1099
 
-
 
1100
        if (len > sizeof(hv1))
-
 
1101
            len = sizeof(hv0) - 1;
-
 
1102
 
-
 
1103
        strncpy(hv1, p, len);
-
 
1104
        hv1[len] = 0;
-
 
1105
        trim(hv1);
-
 
1106
 
-
 
1107
        if (!strcasecmp(hv0, "user"))
-
 
1108
        {
-
 
1109
            syslog(LOG_DAEMON | LOG_INFO, "Found \"user\": %s", hv1);
-
 
1110
            strncpy(configs.User, hv1, sizeof(configs.User));
-
 
1111
        }
-
 
1112
 
-
 
1113
        if (!strcasecmp(hv0, "group"))
-
 
1114
        {
-
 
1115
            syslog(LOG_DAEMON | LOG_INFO, "Found \"group\": %s", hv1);
-
 
1116
            strncpy(configs.Grp, hv1, sizeof(configs.Grp));
-
 
1117
        }
-
 
1118
 
-
 
1119
        if (!strcasecmp(hv0, "port"))
-
 
1120
        {
-
 
1121
            syslog(LOG_DAEMON | LOG_INFO, "Found \"port\": %s", hv1);
-
 
1122
            configs.port = atoi(hv1);
-
 
1123
        }
-
 
1124
 
-
 
1125
        if (!strcasecmp(hv0, "heizpath"))
-
 
1126
        {
-
 
1127
            syslog(LOG_DAEMON | LOG_INFO, "Found \"heizpath\": %s", hv1);
-
 
1128
            strncpy(configs.HeizPath, hv1, sizeof(configs.HeizPath));
-
 
1129
        }
-
 
1130
 
-
 
1131
        if (!strcasecmp(hv0, "Werte"))
-
 
1132
        {
-
 
1133
            syslog(LOG_DAEMON | LOG_INFO, "Found \"Werte\": %s", hv1);
-
 
1134
            strncpy(configs.Werte, hv1, sizeof(configs.Werte));
-
 
1135
        }
-
 
1136
 
-
 
1137
        if (!strcasecmp(hv0, "Device"))
-
 
1138
        {
-
 
1139
            syslog(LOG_DAEMON | LOG_INFO, "Found \"Device\": %s", hv1);
-
 
1140
            strncpy(configs.Device, hv1, sizeof(configs.Device));
-
 
1141
        }
-
 
1142
 
-
 
1143
        if (!strcasecmp(hv0, "Pidfile"))
-
 
1144
        {
-
 
1145
            syslog(LOG_DAEMON | LOG_INFO, "Found \"Pidfile\": %s", hv1);
-
 
1146
            strncpy(configs.Pidfile, hv1, sizeof(configs.Pidfile));
-
 
1147
        }
-
 
1148
 
-
 
1149
        if (!strcasecmp(hv0, "VID"))
-
 
1150
        {
-
 
1151
            syslog(LOG_DAEMON | LOG_INFO, "Found VendorID: %04x", atoi(hv1));
-
 
1152
            configs.VID = atoi(hv1);
-
 
1153
        }
-
 
1154
 
-
 
1155
        if (!strcasecmp(hv0, "PID"))
-
 
1156
        {
-
 
1157
            syslog(LOG_DAEMON | LOG_INFO, "Found ProductID: %04x", atoi(hv1));
-
 
1158
            configs.PID = atoi(hv1);
-
 
1159
        }
-
 
1160
 
-
 
1161
#ifdef SENSOR_ETHERNET
-
 
1162
        if (!strcasecmp(hv0, "IP"))
-
 
1163
        {
-
 
1164
            syslog(LOG_DAEMON | LOG_INFO, "Found IP: %s", hv1);
-
 
1165
            strncpy(configs.IP, hv1, sizeof(configs.IP));
-
 
1166
        }
-
 
1167
 
-
 
1168
        if (!strcasecmp(hv0, "TempPort"))
-
 
1169
        {
-
 
1170
            syslog(LOG_DAEMON | LOG_INFO, "Found temperature network port %d", atoi(hv1));
-
 
1171
            configs.TempPort = atoi(hv1);
-
 
1172
        }
-
 
1173
#endif
-
 
1174
    }
-
 
1175
 
1098
	close (fd);
1176
    close(fd);
1099
}
1177
}
1100
 
1178
 
1101
char *makeFileName(char *ret, char *fname, int len)
1179
char *makeFileName(char *ret, char *fname, int len)
1102
{
1180
{
1103
char *fdup, *pright, *cfg, *lcfg;
1181
    char *fdup, *pright, *cfg, *lcfg;
1104
 
1182
 
1105
	if (ret == NULL || fname == NULL || !len || !strlen(fname))
1183
    if (ret == NULL || fname == NULL || !len || !strlen(fname))
1106
	   return NULL;
1184
        return NULL;
1107
 
1185
 
1108
	if (!access(fname, R_OK | W_OK))
1186
    if (!access(fname, R_OK | W_OK))
1109
	{
1187
    {
1110
	   memset(ret, 0, len);
1188
        memset(ret, 0, len);
1111
	   strncpy(ret, fname, len-1);
1189
        strncpy(ret, fname, len - 1);
1112
	   return ret;
1190
        return ret;
1113
	}
1191
    }
1114
 
1192
 
1115
	fdup = strdup(fname);
1193
    fdup = strdup(fname);
1116
 
1194
 
1117
	if (fdup == NULL)
1195
    if (fdup == NULL)
1118
	{
1196
    {
1119
	   syslog(LOG_DAEMON, "Error allocating memory: %s", strerror(errno));
1197
        syslog(LOG_DAEMON | LOG_ERR, "Error allocating memory: %s", strerror(errno));
1120
	   return NULL;
1198
        return NULL;
1121
	}
1199
    }
1122
 
1200
 
1123
	cfg = strdup(configs.HeizPath);
1201
    cfg = strdup(configs.HeizPath);
1124
	
1202
 
1125
	if (cfg == NULL)
1203
    if (cfg == NULL)
1126
	{
1204
    {
1127
	   syslog(LOG_DAEMON, "Error allocating memory: %s", strerror(errno));
1205
        syslog(LOG_DAEMON | LOG_ERR, "Error allocating memory: %s", strerror(errno));
1128
	   free(fdup);
1206
        free(fdup);
1129
	   return NULL;
1207
        return NULL;
1130
	}
1208
    }
1131
 
1209
 
1132
	pright = basename(fdup);
1210
    pright = basename(fdup);
1133
	lcfg = dirname(cfg);
1211
    lcfg = dirname(cfg);
1134
	memset(ret, 0, len);
1212
    memset(ret, 0, len);
1135
	strncpy(ret, lcfg, len-1);
1213
    strncpy(ret, lcfg, len - 1);
1136
	
1214
 
1137
	if (strlen(ret) < (len - (strlen(pright) + 2)))
1215
    if (strlen(ret) < (len - (strlen(pright) + 2)))
1138
	{
1216
    {
1139
	   strcat(ret, "/");
1217
        strcat(ret, "/");
1140
	   strcat(ret, pright);
1218
        strcat(ret, pright);
1141
	   free(fdup);
1219
        free(fdup);
1142
	   free(cfg);
1220
        free(cfg);
1143
	   return ret;
1221
        return ret;
1144
	}
1222
    }
1145
	
1223
 
1146
	free(fdup);
1224
    free(fdup);
1147
	free(cfg);
1225
    free(cfg);
1148
	return NULL;
1226
    return NULL;
1149
}
1227
}
1150
 
1228
 
1151
int readHeizPlan(void)
1229
int readHeizPlan(void)
1152
{
1230
{
1153
	return readHeizPlanName(configs.HeizPath);
1231
    return readHeizPlanName(configs.HeizPath);
1154
}
1232
}
1155
 
1233
 
1156
int readHeizPlanName(char* fname)
1234
int readHeizPlanName(char* fname)
1157
{
1235
{
1158
int fd, i, wday;
1236
    int fd, i, wday;
1159
ulong tim;
1237
    ulong tim;
1160
char line[512];
1238
    char line[512];
1161
char *p, *xp;
1239
    char *p, *xp;
1162
char hv0[64], hv1[128];
1240
    char hv0[64], hv1[128];
1163
char path[512];
1241
    char path[512];
1164
float temperature;
1242
    float temperature;
1165
int counter = 0;
1243
    int counter = 0;
1166
HEIZINDEX *act, *prev;
1244
    HEIZINDEX *act, *prev;
1167
 
1245
 
1168
	fd = -1;
1246
    fd = -1;
1169
 
1247
 
1170
	if (makeFileName(&path[0], fname, sizeof(path)) == NULL)
1248
    if (makeFileName(&path[0], fname, sizeof(path)) == NULL)
1171
	{
1249
    {
1172
	   syslog(LOG_DAEMON,"No or invalid path %s", fname);
1250
        syslog(LOG_DAEMON | LOG_ERR, "No or invalid path %s", fname);
1173
	   return 0;
1251
        return 0;
1174
	}
1252
    }
1175
 
1253
 
1176
	if (access(path, R_OK))
1254
    if (access(path, R_OK))
1177
	{
1255
    {
1178
	   syslog(LOG_DAEMON,"Access to file %s denied: %s", path, strerror(errno));
1256
        syslog(LOG_DAEMON | LOG_ERR, "Access to file %s denied: %s", path, strerror(errno));
1179
	   return 0;
1257
        return 0;
1180
	}
1258
    }
1181
 
1259
 
1182
	if ((fd = open(path, O_RDONLY)) == -1)
1260
    if ((fd = open(path, O_RDONLY)) == -1)
1183
	{
1261
    {
1184
	   syslog(LOG_DAEMON,"Error opening file %s: %s", path, strerror(errno));
1262
        syslog(LOG_DAEMON | LOG_ERR, "Error opening file %s: %s", path, strerror(errno));
1185
	   return 0;
1263
        return 0;
1186
	}
1264
    }
1187
 
1265
 
1188
	act = prev = NULL;
1266
    act = prev = NULL;
1189
	freeMemory();
1267
    freeMemory();
1190
 
1268
 
1191
	while (readLine(fd, &line[0], sizeof(line)) != NULL)
1269
    while (readLine(fd, &line[0], sizeof(line)) != NULL)
1192
	{
1270
    {
1193
	   int len;
1271
        int len;
1194
 
1272
 
1195
	   trim (&line[0]);
1273
        trim(&line[0]);
1196
 
1274
 
1197
	   if (line[0] == '#' || !strlen(line) || strchr(line, ',') == NULL)
1275
        if (line[0] == '#' || !strlen(line) || strchr(line, ',') == NULL)
1198
	      continue;
1276
            continue;
1199
 
1277
 
1200
	   // We need a place to store the information
1278
        // We need a place to store the information
1201
	   prev = act;
1279
        prev = act;
1202
 
1280
 
1203
	   if ((act = allocateMemory()) == NULL)
1281
        if ((act = allocateMemory()) == NULL)
1204
	   {
1282
        {
1205
	      close(fd);
1283
            close(fd);
1206
	      syslog(LOG_DAEMON,"Error allocating memory for a temperature line! Stopped reading file %s.", configs.HeizPath);
1284
            syslog(LOG_DAEMON | LOG_ERR, "Error allocating memory for a temperature line! Stopped reading file %s.", configs.HeizPath);
1207
	      return 0;
1285
            return 0;
1208
	   }
1286
        }
1209
 
1287
 
1210
	   counter++;
1288
        counter++;
1211
	   memset(act->heizung, 0, sizeof(HEIZUNG));
1289
        memset(act->heizung, 0, sizeof(HEIZUNG));
1212
	   // Parse a line. The line has the format:
1290
        // Parse a line. The line has the format:
1213
	   // <wday>,<end>,<temperature>
1291
        // <wday>,<end>,<temperature>
1214
	   p = strtok(line, ",");
1292
        p = strtok(line, ",");
1215
	   i = 1;
1293
        i = 1;
1216
 
1294
 
1217
	   while(p)
1295
        while (p)
1218
	   {
1296
        {
1219
	      switch(i)
1297
            switch (i)
1220
	      {
1298
            {
1221
		 case 1:	// Week day
1299
                case 1:    // Week day
1222
		    wday = atoi(p);
1300
                    wday = atoi(p);
1223
 
1301
 
1224
		    if (wday < 1 || wday > 7)	// valid line?
1302
                    if (wday < 1 || wday > 7)   // valid line?
1225
		    {
1303
                    {
1226
		       if (prev)
1304
                        if (prev)
1227
			  wday = prev->heizung->wday;
1305
                            wday = prev->heizung->wday;
1228
 
1306
 
1229
		       if (wday < 1 || wday > 7)
1307
                        if (wday < 1 || wday > 7)
1230
		       {
1308
                        {
1231
			  p = strtok(NULL, ",");
1309
                            p = strtok(NULL, ",");
1232
			  i++;
1310
                            i++;
1233
			  continue;
1311
                            continue;
1234
		       }
1312
                        }
1235
		    }
1313
                    }
1236
 
1314
 
1237
		    act->heizung->wday = wday;
1315
                    act->heizung->wday = wday;
1238
		    act->heizung->start = 0;
1316
                    act->heizung->start = 0;
1239
		 break;
1317
                    break;
1240
 
1318
 
1241
		 case 2:	// start/end time
1319
                case 2:    // start/end time
1242
		    if ((xp = strchr(p, ':')) != NULL)
1320
                    if ((xp = strchr(p, ':')) != NULL)
1243
		    {
1321
                    {
1244
		    int hour, min;
1322
                        int hour, min;
1245
 
1323
 
1246
		       hour = atoi(p);
1324
                        hour = atoi(p);
1247
		       min = atoi(xp+1);
1325
                        min = atoi(xp + 1);
1248
 
1326
 
1249
		       if (hour >= 0 && hour <= 23 && min >= 0 && min <= 59)
1327
                        if (hour >= 0 && hour <= 23 && min >= 0 && min <= 59)
1250
		       {
1328
                        {
1251
			  act->heizung->end = hour * 3600 + min * 60 + 59;
1329
                            act->heizung->end = hour * 3600 + min * 60 + 59;
1252
 
1330
 
1253
			  if (prev && prev->heizung->wday == act->heizung->wday)
1331
                            if (prev && prev->heizung->wday == act->heizung->wday)
1254
			     act->heizung->start = prev->heizung->end;
1332
                                act->heizung->start = prev->heizung->end;
1255
		       }
1333
                        }
1256
		    }
1334
                    }
1257
		 break;
1335
 
1258
 
1336
                    break;
1259
		 case 3:	// temperature
1337
 
1260
		    temperature = atof(p);
1338
                case 3:    // temperature
1261
 
1339
                    temperature = atof(p);
1262
		    if (temperature < 5.0 || temperature > 30.0)
1340
 
1263
		    {
1341
                    if (temperature < 5.0 || temperature > 30.0)
1264
		       p = strtok(NULL,",");
1342
                    {
1265
		       i++;
1343
                        p = strtok(NULL, ",");
1266
		       continue;
1344
                        i++;
1267
		    }
1345
                        continue;
1268
 
1346
                    }
1269
		    act->heizung->temp = temperature;
1347
 
1270
		 break;
1348
                    act->heizung->temp = temperature;
1271
	      }
1349
                    break;
1272
 
1350
            }
1273
	      p = strtok(NULL, ",");
1351
 
1274
	      i++;
1352
            p = strtok(NULL, ",");
1275
	   }
1353
            i++;
1276
	}
1354
        }
1277
 
1355
    }
1278
	syslog(LOG_INFO,"Found %d entries in %s", counter, configs.HeizPath);
1356
 
1279
	close (fd);
1357
    syslog(LOG_DAEMON | LOG_INFO, "Found %d entries in %s", counter, configs.HeizPath);
1280
	return 1;
1358
    close(fd);
-
 
1359
    return 1;
1281
}
1360
}
1282
 
1361
 
1283
/*
1362
/*
1284
 * write the (may be) altered plan.
1363
 * write the (may be) altered plan.
1285
 * This function allways writes whole plan.
1364
 * This function allways writes whole plan.
1286
 */
1365
 */
1287
int writeHeizPlan()
1366
int writeHeizPlan()
1288
{
1367
{
1289
	return writeHeizPlanName(configs.HeizPath);
1368
    return writeHeizPlanName(configs.HeizPath);
1290
}
1369
}
1291
 
1370
 
1292
int writeHeizPlanName(char *fname)
1371
int writeHeizPlanName(char *fname)
1293
{
1372
{
1294
int fd, wday;
1373
    int fd, wday;
1295
ulong lastEnd;
1374
    ulong lastEnd;
1296
char hv0[128], path[512];
1375
    char hv0[128], path[512];
1297
HEIZINDEX *act;
1376
    HEIZINDEX *act;
1298
 
1377
 
1299
	fd = -1;
1378
    fd = -1;
1300
 
1379
 
1301
	if (makeFileName(&path[0], fname, sizeof(path)) == NULL)
1380
    if (makeFileName(&path[0], fname, sizeof(path)) == NULL)
1302
	{
1381
    {
1303
	   syslog(LOG_DAEMON,"No or invalid path %s", fname);
1382
        syslog(LOG_DAEMON, "No or invalid path %s", fname);
1304
	   return 0;
1383
        return 0;
1305
	}
1384
    }
1306
 
1385
 
1307
	if (!sortTable())
1386
    if (!sortTable())
1308
	   return 0;
1387
        return 0;
1309
 
1388
 
1310
	if ((fd = open(path, O_RDWR | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
1389
    if ((fd = open(path, O_RDWR | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
1311
	{
1390
    {
1312
	   syslog(LOG_DAEMON, "Error opening/creating file %s: %s", path, strerror(errno));
1391
        syslog(LOG_DAEMON | LOG_ERR, "Error opening/creating file %s: %s", path, strerror(errno));
1313
	   return 0;
1392
        return 0;
1314
	}
1393
    }
1315
 
1394
 
1316
	// Sort table for week days
1395
    // Sort table for week days
1317
	for (wday = 1; wday <= 7; wday++)
1396
    for (wday = 1; wday <= 7; wday++)
1318
	{
1397
    {
1319
	   lastEnd = 0L;
1398
        lastEnd = 0L;
1320
	   act = HeizFirst;
1399
        act = HeizFirst;
1321
 
1400
 
1322
	   while(act)
1401
        while (act)
1323
	   {
1402
        {
1324
	      if (act->heizung->wday == wday)
1403
            if (act->heizung->wday == wday)
1325
	      {
1404
            {
1326
	      int hour, min;
1405
                int hour, min;
1327
 
1406
 
1328
		 hour = act->heizung->end / 3600;
1407
                hour = act->heizung->end / 3600;
1329
		 min = (act->heizung->end - (hour * 3600)) / 60;
1408
                min = (act->heizung->end - (hour * 3600)) / 60;
1330
 
1409
 
1331
		 if (hour > 23)
1410
                if (hour > 23)
1332
		 {
1411
                {
1333
		    hour = 23;
1412
                    hour = 23;
1334
		    min = 59;
1413
                    min = 59;
1335
		 }
1414
                }
1336
 
1415
 
1337
		 sprintf(&hv0[0], "%d,%02d:%02d,%.1f\n",
1416
                sprintf(&hv0[0], "%d,%02d:%02d,%.1f\n",
1338
		     act->heizung->wday, hour, min,
1417
                        act->heizung->wday, hour, min,
1339
		     act->heizung->temp);
1418
                        act->heizung->temp);
1340
		 write(fd, &hv0[0], strlen(hv0));
1419
                write(fd, &hv0[0], strlen(hv0));
1341
	      }
1420
            }
1342
 
-
 
1343
	      act = act->next;
-
 
1344
	   }
-
 
1345
	}
-
 
1346
 
1421
 
-
 
1422
            act = act->next;
-
 
1423
        }
-
 
1424
    }
-
 
1425
 
1347
	close(fd);
1426
    close(fd);
1348
	return 1;
1427
    return 1;
1349
}
1428
}
1350
 
1429
 
1351
/*
1430
/*
1352
 * Allocate the memory for the actual heizung plan.
1431
 * Allocate the memory for the actual heizung plan.
1353
 * This function appends an element to the end of the chain.
1432
 * This function appends an element to the end of the chain.
1354
 */
1433
 */
1355
HEIZINDEX *allocMem(HEIZINDEX *first)
1434
HEIZINDEX *allocMem(HEIZINDEX *first)
1356
{
1435
{
1357
HEIZINDEX *act, *last;
1436
    HEIZINDEX *act, *last;
-
 
1437
 
-
 
1438
    if (!first)
-
 
1439
    {
-
 
1440
        first = malloc(sizeof(HEIZINDEX));
-
 
1441
 
-
 
1442
        if (first)
-
 
1443
        {
-
 
1444
            first->heizung = malloc(sizeof(HEIZUNG));
-
 
1445
            first->next = NULL;
-
 
1446
        }
-
 
1447
        else
-
 
1448
            return NULL;
-
 
1449
 
-
 
1450
        return first;
-
 
1451
    }
-
 
1452
    else
-
 
1453
    {
-
 
1454
        // Find last element
-
 
1455
        last = first;
1358
 
1456
 
1359
	if (!first)
-
 
1360
	{
-
 
1361
	   first = malloc(sizeof(HEIZINDEX));
-
 
1362
 
-
 
1363
	   if (first)
-
 
1364
	   {
-
 
1365
	      first->heizung = malloc(sizeof(HEIZUNG));
-
 
1366
	      first->next = NULL;
-
 
1367
	   }
-
 
1368
	   else
-
 
1369
	      return NULL;
-
 
1370
 
-
 
1371
	   return first;
-
 
1372
	}
-
 
1373
	else
-
 
1374
	{
-
 
1375
	   // Find last element
-
 
1376
	   last = first;
-
 
1377
 
-
 
1378
	   while(last->next)
1457
        while (last->next)
1379
	      last = last->next;
1458
            last = last->next;
1380
 
-
 
1381
	   act = malloc(sizeof(HEIZINDEX));
-
 
1382
 
-
 
1383
	   if (act)
-
 
1384
	   {
-
 
1385
	      act->heizung = malloc(sizeof(HEIZUNG));
-
 
1386
	      act->next = NULL;
-
 
1387
	      last->next = act;
-
 
1388
	   }
-
 
1389
	   else
-
 
1390
	      return NULL;
-
 
1391
 
1459
 
-
 
1460
        act = malloc(sizeof(HEIZINDEX));
-
 
1461
 
1392
	   return act;
1462
        if (act)
-
 
1463
        {
-
 
1464
            act->heizung = malloc(sizeof(HEIZUNG));
-
 
1465
            act->next = NULL;
-
 
1466
            last->next = act;
1393
	}
1467
        }
-
 
1468
        else
-
 
1469
            return NULL;
1394
 
1470
 
-
 
1471
        return act;
-
 
1472
    }
-
 
1473
 
1395
	return NULL;
1474
    return NULL;
1396
}
1475
}
1397
 
1476
 
1398
// This function sorts the table for week days and every into increasing
1477
// This function sorts the table for week days and every into increasing
1399
// time stamps
1478
// time stamps
1400
int sortTable()
1479
int sortTable()
1401
{
1480
{
1402
int count, actElement, wday, flag;
1481
    int count, actElement, wday, flag;
1403
ulong end;
1482
    ulong end;
1404
HEIZINDEX *first, *act, *p;
1483
    HEIZINDEX *first, *act, *p;
1405
 
1484
 
1406
	if (!HeizFirst)
1485
    if (!HeizFirst)
1407
	   return 0;
1486
        return 0;
1408
 
1487
 
1409
	p = HeizFirst;
1488
    p = HeizFirst;
1410
	// Count the number of elements
1489
    // Count the number of elements
1411
	count = 0;
1490
    count = 0;
1412
 
1491
 
1413
	while (p)
1492
    while (p)
1414
	{
1493
    {
1415
	   if (p->heizung->wday)
1494
        if (p->heizung->wday)
1416
	      count++;
1495
            count++;
1417
 
1496
 
1418
	   p = p->next;
1497
        p = p->next;
1419
	}
1498
    }
1420
 
1499
 
1421
	wday = 1;
1500
    wday = 1;
1422
	act = first = NULL;
1501
    act = first = NULL;
1423
	actElement = 0;
1502
    actElement = 0;
1424
 
1503
 
1425
	// First loop sorts for week days
1504
    // First loop sorts for week days
1426
	while (actElement < count && wday <= 7)
1505
    while (actElement < count && wday <= 7)
1427
	{
1506
    {
1428
	int cnt, pos;
1507
        int cnt, pos;
1429
 
1508
 
1430
	   p = HeizFirst;
1509
        p = HeizFirst;
1431
	   flag = 0;
1510
        flag = 0;
1432
	   // find number of entries for actual week day
1511
        // find number of entries for actual week day
1433
	   cnt = 0;
1512
        cnt = 0;
1434
	   act = HeizFirst;
1513
        act = HeizFirst;
1435
 
1514
 
1436
	   while(act)
1515
        while (act)
1437
	   {
1516
        {
1438
	      if (act->heizung->wday == wday)
1517
            if (act->heizung->wday == wday)
1439
		 cnt++;
1518
                cnt++;
1440
 
1519
 
1441
	      act = act->next;
1520
            act = act->next;
1442
	   }
1521
        }
1443
 
1522
 
1444
	   pos = 0;
1523
        pos = 0;
1445
	   end = 0L;
1524
        end = 0L;
1446
 
1525
 
1447
	   // Second loop sorts the actual week day for end times
1526
        // Second loop sorts the actual week day for end times
1448
	   while (p)
1527
        while (p)
1449
	   {
1528
        {
1450
	      if (p->heizung->wday == wday && p->heizung->start == end && p->heizung->end > end)
1529
            if (p->heizung->wday == wday && p->heizung->start == end && p->heizung->end > end)
1451
	      {
1530
            {
1452
		 actElement++;
1531
                actElement++;
1453
		 flag = 1;
1532
                flag = 1;
1454
		 act = allocMem(first);
1533
                act = allocMem(first);
1455
 
1534
 
1456
		 if (!first)
1535
                if (!first)
1457
		    first = act;
1536
                    first = act;
1458
 
1537
 
1459
		 // Check for valid memory block
1538
                // Check for valid memory block
1460
		 if (act)
1539
                if (act)
1461
		 {
1540
                {
1462
		    memmove(act->heizung, p->heizung, sizeof(HEIZUNG));
1541
                    memmove(act->heizung, p->heizung, sizeof(HEIZUNG));
1463
		    end = p->heizung->end;
1542
                    end = p->heizung->end;
1464
		    pos++;
1543
                    pos++;
1465
		 }
1544
                }
1466
		 else
1545
                else
1467
		 {
1546
                {
1468
		    syslog(LOG_DAEMON,"Error allocationg memory for sorting table: %s", strerror(errno));
1547
                    syslog(LOG_DAEMON | LOG_ERR, "Error allocationg memory for sorting table: %s", strerror(errno));
1469
		    // Free allocated memory
1548
                    // Free allocated memory
1470
		    act = first;
1549
                    act = first;
1471
 
1550
 
1472
		    while(act)
1551
                    while (act)
1473
		    {
1552
                    {
1474
		       p = act->next;
1553
                        p = act->next;
1475
		       free(act->heizung);
1554
                        free(act->heizung);
1476
		       free(act);
1555
                        free(act);
1477
		       act = p;
1556
                        act = p;
1478
		    }
1557
                    }
1479
 
1558
 
1480
		    return 0;
1559
                    return 0;
1481
		 }
1560
                }
1482
	      }
1561
            }
1483
 
1562
 
1484
	      p = p->next;
1563
            p = p->next;
1485
 
1564
 
1486
	      // If there are still members left, reset pointer and restart loop
1565
            // If there are still members left, reset pointer and restart loop
1487
	      if (!p && pos < (cnt - 1) && flag)
1566
            if (!p && pos < (cnt - 1) && flag)
1488
	      {
1567
            {
1489
		 p = HeizFirst;
1568
                p = HeizFirst;
1490
		 flag = 0;
1569
                flag = 0;
1491
	      }
1570
            }
1492
	   }
1571
        }
1493
 
1572
 
1494
	   wday++;
1573
        wday++;
1495
	}
1574
    }
1496
 
1575
 
1497
	freeMemory();
1576
    freeMemory();
1498
	HeizFirst = first;
1577
    HeizFirst = first;
1499
	return 1;
1578
    return 1;
1500
}
1579
}
1501
 
1580
 
1502
char *readLine(int fd, char *buf, int bufLen)
1581
char *readLine(int fd, char *buf, int bufLen)
1503
{
1582
{
1504
int i, end;
1583
    int i, end;
1505
char ch, *p;
1584
    char ch, *p;
1506
 
1585
 
1507
        if (fd <= 0)
1586
    if (fd <= 0)
1508
	{
1587
    {
1509
	   syslog(LOG_DAEMON,"Function readLine was called with an invalid file descriptor of %d!", fd);
1588
        syslog(LOG_DAEMON | LOG_ERR, "Function readLine was called with an invalid file descriptor of %d!", fd);
1510
           return NULL;
1589
        return NULL;
1511
	}
1590
    }
1512
 
1591
 
1513
        i = end = 0;
1592
    i = end = 0;
1514
        p = buf;
1593
    p = buf;
1515
 
1594
 
1516
        while (read(fd, &ch, 1) > 0)
1595
    while (read(fd, &ch, 1) > 0)
1517
        {
1596
    {
1518
           end = 1;
1597
        end = 1;
1519
 
1598
 
1520
           if (ch == 0x0a)
1599
        if (ch == 0x0a)
1521
           {
1600
        {
1522
             *p = 0;
1601
            *p = 0;
1523
             return buf;
1602
            return buf;
1524
           }
-
 
1525
 
-
 
1526
           if (ch == 0x0d)      // ignore this!
-
 
1527
              continue;
-
 
1528
 
-
 
1529
           if (i < (bufLen - 1))
-
 
1530
           {
-
 
1531
              *p = ch;
-
 
1532
              p++;
-
 
1533
              i++;
-
 
1534
           }
-
 
1535
        }
1603
        }
1536
 
1604
 
-
 
1605
        if (ch == 0x0d)      // ignore this!
1537
        *p = 0;
1606
            continue;
1538
 
1607
 
-
 
1608
        if (i < (bufLen - 1))
-
 
1609
        {
-
 
1610
            *p = ch;
-
 
1611
            p++;
-
 
1612
            i++;
-
 
1613
        }
-
 
1614
    }
-
 
1615
 
-
 
1616
    *p = 0;
-
 
1617
 
1539
        if (end)
1618
    if (end)
1540
           return buf;
1619
        return buf;
1541
        else
1620
    else
1542
           return NULL;
1621
        return NULL;
1543
}
1622
}
1544
 
1623
 
1545
char *trim(char *str)
1624
char *trim(char *str)
1546
{
1625
{
1547
char *p1, *p2, *p;
1626
    char *p1, *p2, *p;
1548
 
1627
 
1549
	if (!str)
1628
    if (!str)
1550
	   return NULL;
1629
        return NULL;
1551
 
1630
 
1552
	if (!strlen(str))
1631
    if (!strlen(str))
1553
	   return str;
1632
        return str;
1554
 
1633
 
1555
	p = str;
1634
    p = str;
1556
	p1 = p2 = NULL;
1635
    p1 = p2 = NULL;
1557
 
1636
 
1558
	while (*p)
1637
    while (*p)
1559
	{
1638
    {
1560
	   if (!p1 && *p != ' ')
1639
        if (!p1 && *p != ' ')
1561
	   {
1640
        {
1562
	      p1 = p;
1641
            p1 = p;
1563
	      break;
1642
            break;
1564
	   }
1643
        }
1565
 
1644
 
1566
	   p++;
1645
        p++;
1567
	}
1646
    }
1568
 
1647
 
1569
	p2 = str + (strlen(str) - 1);
1648
    p2 = str + (strlen(str) - 1);
1570
 
1649
 
1571
	while (p2 > str && *p2 == ' ')
1650
    while (p2 > str && *p2 == ' ')
1572
	   p2--;
1651
        p2--;
1573
 
1652
 
1574
	if (p2)
1653
    if (p2)
1575
	   *(p2+1) = 0;
1654
        *(p2 + 1) = 0;
1576
 
1655
 
1577
	if (p1)
1656
    if (p1)
1578
	{
1657
    {
1579
	   char *buf = strdup (p1);
1658
        char *buf = strdup(p1);
1580
	   strcpy (str, buf);
1659
        strcpy(str, buf);
1581
	   free (buf);
1660
        free(buf);
1582
	}
1661
    }
1583
 
1662
 
1584
	return str;
1663
    return str;
1585
}
1664
}
1586
 
1665
 
1587
char *remove_string(char *str, char *search, char *ret)
1666
char *remove_string(char *str, char *search, char *ret)
1588
{
1667
{
1589
char *p;
1668
    char *p;
1590
 
1669
 
1591
	if (!strlen(str) || !strlen(search))
1670
    if (!strlen(str) || !strlen(search))
1592
	   return NULL;
1671
        return NULL;
1593
 
1672
 
1594
	if ((p = strstr(str, search)) != NULL)
1673
    if ((p = strstr(str, search)) != NULL)
1595
	{
1674
    {
1596
	int len = strlen(search);
1675
        int len = strlen(search);
1597
 
1676
 
1598
	   strncpy(ret, str, p - str + len);
1677
        strncpy(ret, str, p - str + len);
1599
	   ret[p - str + len] = 0;
1678
        ret[p - str + len] = 0;
1600
	   memmove(str, p + len, strlen(p+len));
1679
        memmove(str, p + len, strlen(p + len));
1601
	   str[strlen(p+len)] = 0;
1680
        str[strlen(p + len)] = 0;
1602
	   return ret;
1681
        return ret;
1603
	}
1682
    }
1604
 
1683
 
1605
	return NULL;
1684
    return NULL;
1606
}
1685
}