/*------------------------------------------------------------------------- * main.c * * Copyright (c) 2016, Teodor Sigaev * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *------------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include static char* dbdir = NULL; static int period = (300); /* in seconds */ static char* pidfile = NULL; static char* logfile = NULL; static bool daemonize = false; static bool workaround = false; static char tfile[MAXPATHLEN], ofile[MAXPATHLEN]; static const double coefficient = (248e-6 / 2637.0); static void usage(const char *errmsg) { puts("trinketd - collecting info from AtomPro"); puts("Copyright (c) 2016, Teodor Sigaev "); puts("trinketd [-d] [-l logfile] [-p pidfile] [-P period] [-D datadir] [-w]"); if (errmsg) { puts(""); puts(errmsg); } exit(1); } static void main_loop() { double prevDose, curDose; restart: prevDose = -1; if (trinketOpen() != ERR_OK) { fprintf(stderr, "trinketOpen fails\n"); sleep(1); goto restart; } while(42) { if (workaround) trinketPing(); if (trinketGetCumDose(&curDose) != ERR_OK) { fprintf(stderr, "trinketGetCumDose fails\n"); trinketClose(); sleep(1); goto restart; } if (prevDose >= 0.0) { double counts = curDose - prevDose; double radlevel = 1e6 * coefficient * counts * 3600.0 / (double)period; FILE *fh = stdout; bool successOpen = true; if (daemonize) { if ((fh = fopen(tfile, "w")) == NULL) { fprintf(stderr, "fopen fails\n"); successOpen = false; } } if (successOpen) { fprintf(fh, "total: %lld\n", (long long)curDose); fprintf(fh, "counts: %lld\n", (long long)counts); fprintf(fh, "radlevel: %.02f\n", radlevel); } if (fh && fh != stdout) { fflush(fh); fclose(fh); rename(tfile, ofile); } } prevDose = curDose; sleep(period); } trinketClose(); } extern char *optarg; extern int opterr, optind; int main(int argn, char* argv[]) { int i; int pidfd, logfd; opterr = 0; while((i=getopt(argn,argv,"dD:l:p:P:wh")) != EOF) { switch(i) { case 'd': daemonize = true; break; case 'D': dbdir = strdup(optarg); break; case 'l': logfile = strdup(optarg); break; case 'p': pidfile = strdup(optarg); break; case 'P': period = atoi(optarg); break; case 'w': workaround = true; break; case 'h': default: usage(NULL); } } if (opterr || optind != argn) usage("argument err"); if (period <= 0) usage("Collecting period could not be zero nor negative"); if (daemonize && !dbdir) usage("trinketd: it is useless to use -d without -D"); if (dbdir && strlen(dbdir) > MAXPATHLEN - 32) usage("datadir is too long"); if (pidfile) { pidfd = open(pidfile, O_CREAT | O_WRONLY | O_TRUNC, 0666); if (pidfd < 0) usage("could not write pidfile"); } if (logfile) { logfd = open(logfile, O_CREAT | O_WRONLY | O_APPEND, 0666); if (logfd < 0) usage("could not write logfile"); } if (daemonize) { if (daemon(0, 0) == -1) usage("could not daemonize"); } if (pidfile) { char pid[64]; snprintf(pid, sizeof(pid), "%lld", (long long)getpid()); if (write(pidfd, pid, strlen(pid)) != strlen(pid)) usage("could not write pid"); close(pidfd); } if (logfile) { dup2(logfd, fileno(stderr)); close(logfd); } if (hid_init() < 0) { fprintf(stderr, "hid_init fails\n"); exit(1); } if (dbdir) { snprintf(tfile, MAXPATHLEN, "%s/trinket.tmp", dbdir); snprintf(ofile, MAXPATHLEN, "%s/trinket.dat", dbdir); } main_loop(); hid_exit(); return 0; }