Hi here the first patch of the patchset for the DeviceAtlas addon
concerning the
new download/scheduler service.

Thanks in advance.
From eae56a44d3bf51f8e92f66baef25f2a417f837ce Mon Sep 17 00:00:00 2001
From: David Carlier <[email protected]>
Date: Fri, 21 Jan 2022 20:46:40 +0000
Subject: [PATCH 1/3] MEDIUM: deviceatlas new optional data file download
 scheduler service.

New specialized service to daily handle the update of download file without
interruption of service and to be preemptively started before HAProxy.

Signed-off-by: David Carlier <[email protected]>
---
 addons/deviceatlas/Makefile  |  49 +++++++++
 addons/deviceatlas/dadwsch.c | 195 +++++++++++++++++++++++++++++++++++
 2 files changed, 244 insertions(+)
 create mode 100644 addons/deviceatlas/Makefile
 create mode 100644 addons/deviceatlas/dadwsch.c

diff --git a/addons/deviceatlas/Makefile b/addons/deviceatlas/Makefile
new file mode 100644
index 000000000..33dd9434e
--- /dev/null
+++ b/addons/deviceatlas/Makefile
@@ -0,0 +1,49 @@
+# DEVICEATLAS_SRC     : DeviceAtlas API source root path 
+
+
+OS              := $(shell uname -s)
+OBJS            := dadwsch.o
+CFLAGS          := -g -O2
+LDFLAGS         :=
+
+CURL_CONFIG     := curl-config
+CURLDIR         := $(shell $(CURL_CONFIG) --prefix 2>/dev/null || echo /usr/local)
+CURL_INC        := $(CURLDIR)/include
+CURL_LIB        := $(CURLDIR)/lib
+CURL_LDFLAGS    := $(shell $(CURL_CONFIG) --libs 2>/dev/null || echo -L /usr/local/lib -lcurl)
+
+PCRE2_CONFIG    := pcre2-config
+PCRE2DIR        := $(shell $(PCRE2_CONFIG) --prefix 2>/dev/null || echo /usr/local)
+PCRE2_INC       := $(PCRE2DIR)/include
+PCRE2_LIB       := $(PCRE2DIR)/lib
+PCRE2_LDFLAGS   := $(shell $(PCRE2_CONFIG) --libs8 2>/dev/null || echo /usr/local)
+
+ifeq ($(DEVICEATLAS_SRC),)
+dadwsch:    dadwsch.c
+	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
+
+LDFLAGS         += -lda
+else
+DEVICEATLAS_INC = $(DEVICEATLAS_SRC)
+DEVICEATLAS_LIB = $(DEVICEATLAS_SRC)
+CFLAGS          += -DDA_REGEX_HDR=\"dac_pcre2.c\" -DDA_REGEX_TAG=2
+CFLAGS          += -DMOBI_CURL -DMOBI_CURLSSET -DMOBI_GZ -DMOBI_ZIP
+CFLAGS          += -I$(DEVICEATLAS_INC) -I$(CURL_INC) -I$(PCRE2DIR)
+LDFLAGS         += $(CURL_LDFLAGS) $(PCRE2_LDFLAGS) -lz -lzip -lpthread
+
+dadwsch:    dadwsch.c $(DEVICEATLAS_SRC)/dac.c $(DEVICEATLAS_SRC)/dasch.c $(DEVICEATLAS_SRC)/dadwarc.c $(DEVICEATLAS_SRC)/dadwcom.c $(DEVICEATLAS_SRC)/dadwcurl.c $(DEVICEATLAS_SRC)/json.c $(DEVICEATLAS_SRC)/Os/daunix.c
+	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
+endif
+
+ifeq ($(OS), Linux)
+LDFLAGS         += -lrt
+endif
+ifeq ($(OS), SunOS)
+LDFLAGS         += -lrt
+endif
+
+clean:
+		rm -f *.o
+		rm -f $(DEVICEATLAS_LIB)*.o
+		rm -f dadwsch
+
diff --git a/addons/deviceatlas/dadwsch.c b/addons/deviceatlas/dadwsch.c
new file mode 100644
index 000000000..e35566a3f
--- /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;
+}
-- 
2.30.2

Reply via email to