root/lm-sensors/trunk/prog/sensord/sensord.c @ 5718

Revision 5718, 4.8 KB (checked in by andy, 4 years ago)

sensord: Remove the hidden commandline interface.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * sensord
3 *
4 * A daemon that periodically logs sensor information to syslog.
5 *
6 * Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301 USA.
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <errno.h>
27#include <limits.h>
28#include <string.h>
29#include <signal.h>
30#include <syslog.h>
31#include <unistd.h>
32#include <time.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35
36#include "sensord.h"
37
38static int logOpened = 0;
39
40static volatile sig_atomic_t done = 0;
41static volatile sig_atomic_t reload = 0;
42
43#define LOG_BUFFER 4096
44
45#include <stdarg.h>
46
47void sensorLog(int priority, const char *fmt, ...)
48{
49        static char buffer[1 + LOG_BUFFER];
50        va_list ap;
51        va_start(ap, fmt);
52        vsnprintf(buffer, LOG_BUFFER, fmt, ap);
53        buffer[LOG_BUFFER] = '\0';
54        va_end(ap);
55        if (debug || (priority < LOG_DEBUG)) {
56                if (logOpened) {
57                        syslog(priority, "%s", buffer);
58                } else {
59                        fprintf(stderr, "%s\n", buffer);
60                        fflush(stderr);
61                }
62        }
63}
64
65static void signalHandler(int sig)
66{
67        signal(sig, signalHandler);
68        switch (sig) {
69        case SIGTERM:
70                done = 1;
71                break;
72        case SIGHUP:
73                reload = 1;
74                break;
75        }
76}
77
78static int sensord(void)
79{
80        int ret = 0;
81        int scanValue = 0, logValue = 0;
82        /*
83         * First RRD update at next RRD timeslot to prevent failures due
84         * one timeslot updated twice on restart for example.
85         */
86        int rrdValue = rrdTime - time(NULL) % rrdTime;
87
88        sensorLog(LOG_INFO, "sensord started");
89
90        while (!done) {
91                if (reload) {
92                        ret = reloadLib(sensorsCfgFile);
93                        if (ret)
94                                sensorLog(LOG_NOTICE,
95                                          "config reload error (%d)", ret);
96                        reload = 0;
97                }
98                if (scanTime && (scanValue <= 0)) {
99                        if ((ret = scanChips()))
100                                sensorLog(LOG_NOTICE,
101                                          "sensor scan error (%d)", ret);
102                        scanValue += scanTime;
103                }
104                if (logTime && (logValue <= 0)) {
105                        if ((ret = readChips()))
106                                sensorLog(LOG_NOTICE,
107                                          "sensor read error (%d)", ret);
108                        logValue += logTime;
109                }
110                if (rrdTime && rrdFile && (rrdValue <= 0)) {
111                        if ((ret = rrdUpdate()))
112                                sensorLog(LOG_NOTICE,
113                                          "rrd update error (%d)", ret);
114                        /*
115                         * The amount of time to wait is computed using the
116                         * same method as in RRD instead of simply adding the
117                         * interval.
118                         */
119                        rrdValue = rrdTime - time(NULL) % rrdTime;
120                }
121                if (!done) {
122                        int a = logTime ? logValue : INT_MAX;
123                        int b = scanTime ? scanValue : INT_MAX;
124                        int c = (rrdTime && rrdFile) ? rrdValue : INT_MAX;
125                        int sleepTime = (a < b) ? ((a < c) ? a : c) :
126                                ((b < c) ? b : c);
127                        sleep(sleepTime);
128                        scanValue -= sleepTime;
129                        logValue -= sleepTime;
130                        rrdValue -= sleepTime;
131                }
132        }
133
134        sensorLog(LOG_INFO, "sensord stopped");
135
136        return ret;
137}
138
139static void openLog(void)
140{
141        openlog("sensord", 0, syslogFacility);
142        logOpened = 1;
143}
144
145static void daemonize(void)
146{
147        int pid;
148        struct stat fileStat;
149        FILE *file;
150
151        if (chdir("/") < 0) {
152                perror("chdir()");
153                exit(EXIT_FAILURE);
154        }
155
156        if (!(stat(pidFile, &fileStat)) &&
157            ((!S_ISREG(fileStat.st_mode)) || (fileStat.st_size > 11))) {
158                fprintf(stderr,
159                        "Error: PID file `%s' already exists and looks suspicious.\n",
160                        pidFile);
161                exit(EXIT_FAILURE);
162        }
163
164        if (!(file = fopen(pidFile, "w"))) {
165                fprintf(stderr, "fopen(\"%s\"): %s\n", pidFile,
166                        strerror(errno));
167                exit(EXIT_FAILURE);
168        }
169
170        /* I should use sigaction but... */
171        if (signal(SIGTERM, signalHandler) == SIG_ERR ||
172            signal (SIGHUP, signalHandler) == SIG_ERR) {
173                perror("signal");
174                exit(EXIT_FAILURE);
175        }
176
177        if ((pid = fork()) == -1) {
178                perror("fork()");
179                exit(EXIT_FAILURE);
180        } else if (pid != 0) {
181                fprintf(file, "%d\n", pid);
182                fclose(file);
183                unloadLib();
184                exit(EXIT_SUCCESS);
185        }
186
187        if (setsid() < 0) {
188                perror("setsid()");
189                exit(EXIT_FAILURE);
190        }
191
192        fclose(file);
193        close(STDIN_FILENO);
194        close(STDOUT_FILENO);
195        close(STDERR_FILENO);
196}
197
198static void undaemonize(void)
199{
200        unlink(pidFile);
201        closelog();
202}
203
204int main(int argc, char **argv)
205{
206        int ret = 0;
207
208        if (parseArgs(argc, argv) ||
209            parseChips(argc, argv))
210                exit(EXIT_FAILURE);
211
212        if (loadLib(sensorsCfgFile))
213                exit(EXIT_FAILURE);
214
215        openLog();
216
217        if (rrdFile) {
218                ret = rrdInit();
219                if (ret)
220                        exit(EXIT_FAILURE);
221        }
222
223        if (doCGI) {
224                ret = rrdCGI();
225        } else {
226                daemonize();
227                ret = sensord();
228                undaemonize();
229        }
230
231        if (unloadLib())
232                exit(EXIT_FAILURE);
233
234        return ret;
235}
Note: See TracBrowser for help on using the browser.