summaryrefslogtreecommitdiffstats
path: root/addons/deviceatlas/dadwsch.c
diff options
context:
space:
mode:
Diffstat (limited to 'addons/deviceatlas/dadwsch.c')
-rw-r--r--addons/deviceatlas/dadwsch.c195
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;
+}