diff -r 000000000000 -r 033898178630 bmsd/bms.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bmsd/bms.c Sat Aug 04 21:19:15 2018 +0200 @@ -0,0 +1,237 @@ +/***************************************************************************** + * Copyright (C) 2017-2018 + * + * Michiel Broek + * + * This file is part of the bms (Brewery Management System) + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * bms is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ThermFerm; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + *****************************************************************************/ + +#include "bms.h" +#include "xutil.h" +#include "rdconfig.h" +#include "lock.h" +#include "mqtt.h" +#include "mysql.h" + + +int my_shutdown = FALSE; +int debug = FALSE; +static pid_t pgrp, mypid; +char *Private_Path = NULL; /* Users data path */ +//char *resource_path = NULL; /* Webserver root */ + +//extern struct lws_context *context; + + +void help(void) +{ + fprintf(stdout, "bmsd v%s starting\n\n", VERSION); + fprintf(stdout, "Usage: bmsd [-d] [-h]\n"); + fprintf(stdout, " -d --debug Debug and run in foreground\n"); + fprintf(stdout, " -h --help Display this help\n"); +} + + + +void die(int onsig) +{ + switch (onsig) { + case SIGHUP: syslog(LOG_NOTICE, "Got SIGHUP, shutting down"); + break; + case SIGINT: syslog(LOG_NOTICE, "Keyboard interrupt, shutting down"); + break; + case SIGTERM: syslog(LOG_NOTICE, "Got SIGTERM, shutting down"); + break; + case SIGSEGV: syslog(LOG_NOTICE, "Got SIGSEGV, shutting down"); + my_shutdown = TRUE; + exit(SIGSEGV); + break; + default: syslog(LOG_NOTICE, "die() on signal %d", onsig); + } + my_shutdown = TRUE; +} + + + +int server(void) { + uid_t myuid; + struct passwd *mypwd; + int rc = 0; + + myuid = getuid(); + mypwd = getpwuid(myuid); + if (mypwd == NULL) { + fprintf(stderr, "[main] Could not find passwd entry\n"); + return 1; + } + + Private_Path = xstrcpy(mypwd->pw_dir); + Private_Path = xstrcat(Private_Path, (char *)"/.bms"); + + if (lockprog((char *)"bmsd")) { + syslog(LOG_NOTICE, "Can't lock"); + return 1; + } + + if (rdconfig()) { + rc = 2; + goto endit1; + } + + if (bms_mysql_init()) { + rc = 3; + goto endit1; + } + if (mqtt_connect()) { + rc = 4; + goto endit2; + } + + if (debug) + fprintf(stdout, "[main] Entering main loop\n"); + + while (my_shutdown == FALSE) { + + usleep(100000); + } + if (debug) + fprintf(stdout, "[main] Exit from main loop\n"); + + /* + * Remove our topics and close MQTT connection. + */ + mqtt_disconnect(); + +endit2: + bms_mysql_end(); + +endit1: + + killconfig(); + + ulockprog((char *)"bmsd"); + + free(Private_Path); + Private_Path = NULL; + + if (debug) + fprintf(stdout, "[main] Server shutdown complete\n"); + return rc; +} + + + +int main(int argc, char *argv[]) { + int rc, c, i; + pid_t frk; + + while (1) { + int option_index = 0; + static struct option long_options[] = { + {"debug", 0, 0, 'c'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "dh", long_options, &option_index); + if (c == -1) + break; + switch (c) { + case 'd': debug = TRUE; + break; + case 'h': help(); + return 1; + } + } + + openlog("bmsd", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_USER); + syslog(LOG_NOTICE, "bmsd v%s starting", VERSION); + if (debug) + fprintf(stdout, "bmsd v%s starting\n", VERSION); + + + /* + * Catch all the signals we can, and ignore the rest. Note that SIGKILL can't be ignored + * but that's live. This daemon should only be stopped by SIGTERM. + * Don't catch SIGCHLD. + */ + for (i = 0; i < NSIG; i++) { + if ((i != SIGCHLD) && (i != SIGKILL) && (i != SIGSTOP)) + signal(i, (void (*))die); + } + + if (debug) { + /* + * For debugging run in foreground. + */ + rc = server(); + } else { + /* + * Server initialization is complete. Now we can fork the + * daemon and return to the user. We need to do a setpgrp + * so that the daemon will no longer be assosiated with the + * users control terminal. This is done before the fork, so + * that the child will not be a process group leader. Otherwise, + * if the child were to open a terminal, it would become + * associated with that terminal as its control terminal. + */ + if ((pgrp = setpgid(0, 0)) == -1) { + syslog(LOG_NOTICE, "setpgpid failed"); + } + + frk = fork(); + switch (frk) { + case -1: + syslog(LOG_NOTICE, "Daemon fork failed: %s", strerror(errno)); + exit(1); + case 0: /* + * Run the daemon + */ + fclose(stdin); + if (open("/dev/null", O_RDONLY) != 0) { + syslog(LOG_NOTICE, "Reopen of stdin to /dev/null failed"); + _exit(2); + } + fclose(stdout); + if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 1) { + syslog(LOG_NOTICE, "Reopen of stdout to /dev/null failed"); + _exit(2); + } + fclose(stderr); + if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 2) { + syslog(LOG_NOTICE, "Reopen of stderr to /dev/null failed"); + _exit(2); + } + mypid = getpid(); + rc = server(); + break; + /* Not reached */ + default: + /* + * Here we detach this process and let the child + * run the deamon process. + */ + syslog(LOG_NOTICE, "Starting daemon with pid %d", frk); + exit(0); + } + } + + syslog(LOG_NOTICE, "Finished, rc=%d", rc); + return rc; +} + +