bmsd/bms.c

changeset 0
033898178630
child 194
d202777ebae5
equal deleted inserted replaced
-1:000000000000 0:033898178630
1 /*****************************************************************************
2 * Copyright (C) 2017-2018
3 *
4 * Michiel Broek <mbroek at mbse dot eu>
5 *
6 * This file is part of the bms (Brewery Management System)
7 *
8 * This is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * bms is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with ThermFerm; see the file COPYING. If not, write to the Free
20 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *****************************************************************************/
22
23 #include "bms.h"
24 #include "xutil.h"
25 #include "rdconfig.h"
26 #include "lock.h"
27 #include "mqtt.h"
28 #include "mysql.h"
29
30
31 int my_shutdown = FALSE;
32 int debug = FALSE;
33 static pid_t pgrp, mypid;
34 char *Private_Path = NULL; /* Users data path */
35 //char *resource_path = NULL; /* Webserver root */
36
37 //extern struct lws_context *context;
38
39
40 void help(void)
41 {
42 fprintf(stdout, "bmsd v%s starting\n\n", VERSION);
43 fprintf(stdout, "Usage: bmsd [-d] [-h]\n");
44 fprintf(stdout, " -d --debug Debug and run in foreground\n");
45 fprintf(stdout, " -h --help Display this help\n");
46 }
47
48
49
50 void die(int onsig)
51 {
52 switch (onsig) {
53 case SIGHUP: syslog(LOG_NOTICE, "Got SIGHUP, shutting down");
54 break;
55 case SIGINT: syslog(LOG_NOTICE, "Keyboard interrupt, shutting down");
56 break;
57 case SIGTERM: syslog(LOG_NOTICE, "Got SIGTERM, shutting down");
58 break;
59 case SIGSEGV: syslog(LOG_NOTICE, "Got SIGSEGV, shutting down");
60 my_shutdown = TRUE;
61 exit(SIGSEGV);
62 break;
63 default: syslog(LOG_NOTICE, "die() on signal %d", onsig);
64 }
65 my_shutdown = TRUE;
66 }
67
68
69
70 int server(void) {
71 uid_t myuid;
72 struct passwd *mypwd;
73 int rc = 0;
74
75 myuid = getuid();
76 mypwd = getpwuid(myuid);
77 if (mypwd == NULL) {
78 fprintf(stderr, "[main] Could not find passwd entry\n");
79 return 1;
80 }
81
82 Private_Path = xstrcpy(mypwd->pw_dir);
83 Private_Path = xstrcat(Private_Path, (char *)"/.bms");
84
85 if (lockprog((char *)"bmsd")) {
86 syslog(LOG_NOTICE, "Can't lock");
87 return 1;
88 }
89
90 if (rdconfig()) {
91 rc = 2;
92 goto endit1;
93 }
94
95 if (bms_mysql_init()) {
96 rc = 3;
97 goto endit1;
98 }
99 if (mqtt_connect()) {
100 rc = 4;
101 goto endit2;
102 }
103
104 if (debug)
105 fprintf(stdout, "[main] Entering main loop\n");
106
107 while (my_shutdown == FALSE) {
108
109 usleep(100000);
110 }
111 if (debug)
112 fprintf(stdout, "[main] Exit from main loop\n");
113
114 /*
115 * Remove our topics and close MQTT connection.
116 */
117 mqtt_disconnect();
118
119 endit2:
120 bms_mysql_end();
121
122 endit1:
123
124 killconfig();
125
126 ulockprog((char *)"bmsd");
127
128 free(Private_Path);
129 Private_Path = NULL;
130
131 if (debug)
132 fprintf(stdout, "[main] Server shutdown complete\n");
133 return rc;
134 }
135
136
137
138 int main(int argc, char *argv[]) {
139 int rc, c, i;
140 pid_t frk;
141
142 while (1) {
143 int option_index = 0;
144 static struct option long_options[] = {
145 {"debug", 0, 0, 'c'},
146 {"help", 0, 0, 'h'},
147 {0, 0, 0, 0}
148 };
149
150 c = getopt_long(argc, argv, "dh", long_options, &option_index);
151 if (c == -1)
152 break;
153 switch (c) {
154 case 'd': debug = TRUE;
155 break;
156 case 'h': help();
157 return 1;
158 }
159 }
160
161 openlog("bmsd", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_USER);
162 syslog(LOG_NOTICE, "bmsd v%s starting", VERSION);
163 if (debug)
164 fprintf(stdout, "bmsd v%s starting\n", VERSION);
165
166
167 /*
168 * Catch all the signals we can, and ignore the rest. Note that SIGKILL can't be ignored
169 * but that's live. This daemon should only be stopped by SIGTERM.
170 * Don't catch SIGCHLD.
171 */
172 for (i = 0; i < NSIG; i++) {
173 if ((i != SIGCHLD) && (i != SIGKILL) && (i != SIGSTOP))
174 signal(i, (void (*))die);
175 }
176
177 if (debug) {
178 /*
179 * For debugging run in foreground.
180 */
181 rc = server();
182 } else {
183 /*
184 * Server initialization is complete. Now we can fork the
185 * daemon and return to the user. We need to do a setpgrp
186 * so that the daemon will no longer be assosiated with the
187 * users control terminal. This is done before the fork, so
188 * that the child will not be a process group leader. Otherwise,
189 * if the child were to open a terminal, it would become
190 * associated with that terminal as its control terminal.
191 */
192 if ((pgrp = setpgid(0, 0)) == -1) {
193 syslog(LOG_NOTICE, "setpgpid failed");
194 }
195
196 frk = fork();
197 switch (frk) {
198 case -1:
199 syslog(LOG_NOTICE, "Daemon fork failed: %s", strerror(errno));
200 exit(1);
201 case 0: /*
202 * Run the daemon
203 */
204 fclose(stdin);
205 if (open("/dev/null", O_RDONLY) != 0) {
206 syslog(LOG_NOTICE, "Reopen of stdin to /dev/null failed");
207 _exit(2);
208 }
209 fclose(stdout);
210 if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 1) {
211 syslog(LOG_NOTICE, "Reopen of stdout to /dev/null failed");
212 _exit(2);
213 }
214 fclose(stderr);
215 if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 2) {
216 syslog(LOG_NOTICE, "Reopen of stderr to /dev/null failed");
217 _exit(2);
218 }
219 mypid = getpid();
220 rc = server();
221 break;
222 /* Not reached */
223 default:
224 /*
225 * Here we detach this process and let the child
226 * run the deamon process.
227 */
228 syslog(LOG_NOTICE, "Starting daemon with pid %d", frk);
229 exit(0);
230 }
231 }
232
233 syslog(LOG_NOTICE, "Finished, rc=%d", rc);
234 return rc;
235 }
236
237

mercurial