#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #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; }