diff options
Diffstat (limited to 'addons/deviceatlas/dadwsch.c')
-rw-r--r-- | addons/deviceatlas/dadwsch.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/addons/deviceatlas/dadwsch.c b/addons/deviceatlas/dadwsch.c new file mode 100644 index 0000000..e35566a --- /dev/null +++ b/addons/deviceatlas/dadwsch.c @@ -0,0 +1,195 @@ +#define _GNU_SOURCE +#include <dac.h> +#include <dadwcurl.h> +#include <dadwarc.h> +#include <getopt.h> +#include <stdlib.h> +#include <signal.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/mman.h> + +#define ATLASTOKSZ PATH_MAX +#define ATLASMAPNM "/hapdeviceatlas" + +const char *__pgname; + +static struct { + da_dwatlas_t o; + int ofd; + void* atlasmap; +} global_deviceatlassch = { + .ofd = -1, + .atlasmap = NULL +}; + + +void usage(void) +{ + fprintf(stderr, "%s -u download URL [-d hour (in H:M:S format) current hour by default] [-p path for the downloaded file, /tmp by default]\n", __pgname); + exit(EXIT_FAILURE); +} + +static size_t jsonread(void *ctx, size_t count, char *buf) +{ + return fread(buf, 1, count, ctx); +} + +static da_status_t jsonseek(void *ctx, off_t pos) +{ + return fseek(ctx, pos, SEEK_SET) != -1 ? DA_OK : DA_SYS; +} + +static void dadwlog(dw_config_t cfg, const char* msg) +{ + time_t now = time(NULL); + char buf[26] = {0}; + ctime_r(&now, buf); + buf[24] = 0; + fprintf(stderr, "%s: %s\n", buf, msg); +} + +static dw_status_t dadwnot(void *a, dw_config_t *cfg) +{ + da_dwatlas_t *o = (da_dwatlas_t *)a; + if (!o) + return DW_ERR; + char *e; + char jsondbuf[26] = {0}, buf[26] = {0}, atlasp[ATLASTOKSZ] = {0}; + time_t now = time(NULL); + time_t jsond; + int fd = -1; + (void)a; + jsond = da_getdatacreation(&o->atlas); + dwgetfinalp(o->dcfg.info, atlasp, sizeof(atlasp)); + ctime_r(&jsond, jsondbuf); + ctime_r(&now, buf); + jsondbuf[24] = 0; + buf[24] = 0; + + printf("%s: data file generated on `%s`\n", buf, jsondbuf); + int val = 1; + unsigned char *ptr = (unsigned char *)global_deviceatlassch.atlasmap; + memset(ptr, 0, sizeof(atlasp)); + strcpy(ptr, atlasp); + return DW_OK; +} + +static da_status_t dadwinit(void) +{ + if ((global_deviceatlassch.ofd = shm_open(ATLASMAPNM, O_RDWR | O_CREAT, 0660)) == -1) { + fprintf(stderr, "%s\n", strerror(errno)); + return DA_SYS; + } + + if (ftruncate(global_deviceatlassch.ofd, ATLASTOKSZ) == -1) { + close(global_deviceatlassch.ofd); + return DA_SYS; + } + lseek(global_deviceatlassch.ofd, 0, SEEK_SET); + global_deviceatlassch.atlasmap = mmap(0, ATLASTOKSZ, PROT_READ | PROT_WRITE, MAP_SHARED, global_deviceatlassch.ofd, 0); + if (global_deviceatlassch.atlasmap == MAP_FAILED) { + fprintf(stderr, "%s\n", strerror(errno)); + return DA_SYS; + } else { + memset(global_deviceatlassch.atlasmap, 0, ATLASTOKSZ); + return DA_OK; + } +} + +static void dadwexit(int sig __attribute__((unused)), siginfo_t *s __attribute__((unused)), void *ctx __attribute__((unused))) +{ + ssize_t w; + + fprintf(stderr, "%s: exit\n", __pgname); + dw_daatlas_close(&global_deviceatlassch.o); + da_fini(); + munmap(global_deviceatlassch.atlasmap, ATLASTOKSZ); + close(global_deviceatlassch.ofd); + shm_unlink(ATLASMAPNM); + exit(EXIT_SUCCESS); +} + +int main(int argc, char **argv) +{ + const char *opts = "u:p:d:h"; + bool dset = false; + size_t i; + int ch; + + da_property_decl_t extraprops[1] = { + { 0, 0 } + }; + + __pgname = argv[0]; + + dw_df_dainit_fn = curldwinit; + dw_df_dacleanup_fn = curldwcleanup; + + da_init(); + memset(&global_deviceatlassch.o.dcfg, 0, sizeof(global_deviceatlassch.o.dcfg)); + while ((ch = getopt(argc, argv, opts)) != -1) { + switch (ch) { + case 'u': + global_deviceatlassch.o.dcfg.info.url = strdup(optarg); + break; + case 'p': + global_deviceatlassch.o.dcfg.info.path = strdup(optarg); + break; + case 'd': + if (strptime(optarg, "%H:%M:%S", &global_deviceatlassch.o.dcfg.info.rtm) != NULL) + dset = true; + else + usage(); + break; + case 'h': + default: + usage(); + } + } + + if (!dset) { + time_t now = time(NULL); + struct tm *cnow = gmtime(&now); + memcpy(&global_deviceatlassch.o.dcfg.info.rtm, cnow, offsetof(struct tm, tm_mday)); + } + + if (!global_deviceatlassch.o.dcfg.info.url) + usage(); + + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_SIGINFO | SA_RESTART; + sa.sa_sigaction = dadwexit; + + global_deviceatlassch.o.dcfg.info.datatm = 1; + global_deviceatlassch.o.dcfg.info.chksum = 1; + global_deviceatlassch.o.dcfg.info.reload = 1; + global_deviceatlassch.o.dcfg.info.tobin = 1; + global_deviceatlassch.o.dcfg.ep = extraprops; + global_deviceatlassch.o.dcfg.dwproc = curldwproc; + global_deviceatlassch.o.dcfg.dwextract = dadwextract; + global_deviceatlassch.o.dcfg.lptr = (void *)stderr; + global_deviceatlassch.o.dcfg.dwlog = &dadwlog; + global_deviceatlassch.o.dcfg.dwnotify_n = &dadwnot; + global_deviceatlassch.o.rfn = jsonread; + global_deviceatlassch.o.posfn = jsonseek; + + if (dadwinit() != DA_OK) { + fprintf(stderr, "%s init failed\n", __pgname); + exit(EXIT_FAILURE); + } + + if (da_atlas_open_schedule(&global_deviceatlassch.o) != DA_OK) { + fprintf(stderr, "%s scheduling failed\n", __pgname); + exit(EXIT_FAILURE); + } + + sigaction(SIGINT, &sa, NULL); + sigaction(SIGQUIT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + + while (true) sleep(1); + + return 0; +} |