Browse Source

debloat and reorganize code
split app into procd and init binaries
remove log support, this is an external service now

Signed-off-by: John Crispin <blogic@openwrt.org>

John Crispin 10 years ago
parent
commit
916f95cb58
41 changed files with 420 additions and 2344 deletions
  1. 1 4
      .gitignore
  2. 10 22
      CMakeLists.txt
  3. 0 45
      debug.c
  4. 13 6
      initd/early.c
  5. 115 0
      initd/init.c
  6. 23 0
      initd/init.h
  7. 4 2
      initd/mkdev.c
  8. 98 0
      initd/preinit.c
  9. 5 5
      inittab.c
  10. 0 6
      libvalidate.h
  11. 0 135
      log.c
  12. 18 23
      log.h
  13. 0 369
      logread.c
  14. 0 99
      measure.c
  15. 5 4
      plug/coldplug.c
  16. 23 13
      plug/hotplug.c
  17. 1 0
      plug/hotplug.h
  18. 0 0
      plug/udevtrigger.c
  19. 0 68
      preinit.c
  20. 9 22
      procd.c
  21. 1 32
      procd.h
  22. 5 5
      rcS.c
  23. 7 18
      service/instance.c
  24. 1 1
      service/instance.h
  25. 38 7
      service/service.c
  26. 1 0
      service/service.h
  27. 3 3
      service/trigger.c
  28. 2 1
      service/validate.c
  29. 0 13
      signal.c
  30. 9 6
      state.c
  31. 0 320
      syslog.c
  32. 0 6
      system.c
  33. 23 74
      ubus.c
  34. 0 0
      utils/askfirst.c
  35. 0 0
      utils/md5.c
  36. 0 0
      utils/md5.h
  37. 0 0
      utils/utils.c
  38. 0 0
      utils/utils.h
  39. 0 1002
      validate.c
  40. 0 28
      validate_data.c
  41. 5 5
      watchdog.c

+ 1 - 4
.gitignore

@@ -1,13 +1,10 @@
 procd
-validate_data
-logread
 askfirst
 udevtrigger
+init
 .*
-*.so
 Makefile
 CMakeCache.txt
 CMakeFiles
 *.cmake
 install_manifest.txt
-

+ 10 - 22
CMakeLists.txt

@@ -10,7 +10,9 @@ IF(APPLE)
   LINK_DIRECTORIES(/opt/local/lib)
 ENDIF()
 
-SET(SOURCES main.c ubus.c service.c service_validate.c instance.c utils.c md5.c hotplug.c state.c mkdev.c early.c inittab.c preinit.c coldplug.c syslog.c log.c watchdog.c signal.c system.c debug.c rcS.c trigger.c measure.c)
+SET(SOURCES procd.c signal.c watchdog.c state.c	inittab.c rcS.c	ubus.c system.c
+	service/service.c service/instance.c service/validate.c service/trigger.c
+	plug/coldplug.c plug/hotplug.c utils/utils.c utils/md5.c)
 
 find_library(json NAMES json-c json)
 SET(LIBS ubox ubus ${json} blobmsg_json json_script)
@@ -19,42 +21,28 @@ IF(DEBUG)
   ADD_DEFINITIONS(-DDEBUG -g3)
 ENDIF()
 
-ADD_LIBRARY(validate SHARED validate.c)
-
-INSTALL(TARGETS validate
-	LIBRARY DESTINATION lib
-)
 
 ADD_EXECUTABLE(procd ${SOURCES})
-
-TARGET_LINK_LIBRARIES(procd ${LIBS} validate)
-
+TARGET_LINK_LIBRARIES(procd ${LIBS})
 INSTALL(TARGETS procd
 	RUNTIME DESTINATION sbin
 )
 
-ADD_EXECUTABLE(askfirst askfirst.c)
 
-INSTALL(TARGETS askfirst
+ADD_EXECUTABLE(init initd/init.c initd/early.c initd/preinit.c initd/mkdev.c watchdog.c)
+TARGET_LINK_LIBRARIES(init ${LIBS})
+INSTALL(TARGETS init
 	RUNTIME DESTINATION sbin
 )
 
-ADD_EXECUTABLE(udevtrigger udevtrigger.c)
 
+ADD_EXECUTABLE(udevtrigger plug/udevtrigger.c)
 INSTALL(TARGETS udevtrigger
 	RUNTIME DESTINATION sbin
 )
 
-ADD_EXECUTABLE(logread logread.c)
-TARGET_LINK_LIBRARIES(logread ${LIBS})
 
-INSTALL(TARGETS logread
-	RUNTIME DESTINATION sbin
-)
-
-ADD_EXECUTABLE(validate_data validate_data.c)
-TARGET_LINK_LIBRARIES(validate_data ${LIBS} validate)
-
-INSTALL(TARGETS validate_data
+ADD_EXECUTABLE(askfirst utils/askfirst.c)
+INSTALL(TARGETS askfirst
 	RUNTIME DESTINATION sbin
 )

+ 0 - 45
debug.c

@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <regex.h>
-#include <unistd.h>
-
-#include "procd.h"
-
-unsigned int debug = 0;
-
-void debug_init(void)
-{
-	char line[256];
-	int r, fd = open("/proc/cmdline", O_RDONLY);
-	regex_t pat_cmdline;
-	regmatch_t matches[2];
-
-	if (fd < 0)
-		return;
-
-	r = read(fd, line, sizeof(line) - 1);
-	line[r] = '\0';
-	close(fd);
-
-	regcomp(&pat_cmdline, "init_debug=([0-9]+)", REG_EXTENDED);
-	if (!regexec(&pat_cmdline, line, 2, matches, 0)) {
-		line[matches[1].rm_eo] = '\0';
-		debug = atoi(&line[matches[1].rm_so]);
-	}
-	regfree(&pat_cmdline);
-}

+ 13 - 6
early.c → initd/early.c

@@ -19,10 +19,13 @@
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <stdlib.h>
 
-#include "procd.h"
+#include "../log.h"
+#include "init.h"
 
-static void early_mounts(void)
+static void
+early_mounts(void)
 {
 	mount("proc", "/proc", "proc", MS_NOATIME, 0);
 	mount("sysfs", "/sys", "sysfs", MS_NOATIME, 0);
@@ -39,13 +42,15 @@ static void early_mounts(void)
 	mount("devpts", "/dev/pts", "devpts", MS_NOATIME, "mode=600");
 }
 
-static void early_dev(void)
+static void
+early_dev(void)
 {
 	mkdev("*", 0600);
 	mknod("/dev/null", 0666, makedev(1, 3));
 }
 
-static void early_console(const char *dev)
+static void
+early_console(const char *dev)
 {
 	struct stat s;
 	int dd;
@@ -69,12 +74,14 @@ static void early_console(const char *dev)
 		close(dd);
 }
 
-static void early_env(void)
+static void
+early_env(void)
 {
 	setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin", 1);
 }
 
-void procd_early(void)
+void
+early(void)
 {
 	if (getpid() != 1)
 		return;

+ 115 - 0
initd/init.c

@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/reboot.h>
+
+#include <libubox/uloop.h>
+#include <libubus.h>
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <regex.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "init.h"
+#include "../watchdog.h"
+
+unsigned int debug = 0;
+
+static void
+signal_shutdown(int signal, siginfo_t *siginfo, void *data)
+{
+	fprintf(stderr, "reboot\n");
+	fflush(stderr);
+	sync();
+	sleep(2);
+	reboot(RB_AUTOBOOT);
+	while (1)
+		;
+}
+
+static struct sigaction sa_shutdown = {
+	.sa_sigaction = signal_shutdown,
+	.sa_flags = SA_SIGINFO
+};
+
+static void
+cmdline(void)
+{
+	char line[256];
+	int r, fd = open("/proc/cmdline", O_RDONLY);
+	regex_t pat_cmdline;
+	regmatch_t matches[2];
+
+	if (fd < 0)
+		return;
+
+	r = read(fd, line, sizeof(line) - 1);
+	line[r] = '\0';
+	close(fd);
+
+	regcomp(&pat_cmdline, "init_debug=([0-9]+)", REG_EXTENDED);
+	if (!regexec(&pat_cmdline, line, 2, matches, 0)) {
+		line[matches[1].rm_eo] = '\0';
+		debug = atoi(&line[matches[1].rm_so]);
+	}
+	regfree(&pat_cmdline);
+}
+
+int
+main(int argc, char **argv)
+{
+	pid_t pid;
+
+	sigaction(SIGTERM, &sa_shutdown, NULL);
+	sigaction(SIGUSR1, &sa_shutdown, NULL);
+	sigaction(SIGUSR2, &sa_shutdown, NULL);
+
+	early();
+	cmdline();
+	watchdog_init(1);
+
+	pid = fork();
+	if (!pid) {
+		char *kmod[] = { "/sbin/kmodloader", "/etc/modules-boot.d/", NULL };
+
+		if (debug < 3) {
+			int fd = open("/dev/null", O_RDWR);
+
+			if (fd > -1) {
+				dup2(fd, STDIN_FILENO);
+				dup2(fd, STDOUT_FILENO);
+				dup2(fd, STDERR_FILENO);
+				if (fd > STDERR_FILENO)
+					close(fd);
+			}
+		}
+		execvp(kmod[0], kmod);
+		ERROR("Failed to start kmodloader\n");
+		exit(-1);
+	}
+	if (pid <= 0)
+		ERROR("Failed to start kmodloader instance\n");
+	uloop_init();
+	preinit();
+	uloop_run();
+
+	return 0;
+}

+ 23 - 0
initd/init.h

@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _INIT_H__
+#define _INIT_H__
+
+#include "../log.h"
+
+void preinit(void);
+void early(void);
+int mkdev(const char *progname, int progmode);
+
+#endif

+ 4 - 2
mkdev.c → initd/mkdev.c

@@ -26,7 +26,9 @@
 #include <limits.h>
 #include <fnmatch.h>
 
-#include "procd.h"
+#include "init.h"
+
+#include "../log.h"
 
 static char **patterns;
 static int n_patterns;
@@ -50,7 +52,7 @@ static void make_dev(const char *path, bool block, int major, int minor)
 	unsigned int oldumask = umask(0);
 	unsigned int _mode = mode | (block ? S_IFBLK : S_IFCHR);
 
-	DEBUG(2, "Creating %s device %s(%d,%d)\n",
+	DEBUG(4, "Creating %s device %s(%d,%d)\n",
 		block ? "block" : "character",
 		path, major, minor);
 

+ 98 - 0
initd/preinit.c

@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+
+#include <libubox/uloop.h>
+#include <libubox/utils.h>
+#include <libubus.h>
+
+#include <stdio.h>
+
+#include <unistd.h>
+
+#include "init.h"
+#include "../watchdog.h"
+
+static struct uloop_process preinit_proc;
+static struct uloop_process plugd_proc;
+
+static void
+spawn_procd(struct uloop_process *proc, int ret)
+{
+	char *wdt_fd = watchdog_fd();
+	char *argv[] = { "/sbin/procd", NULL };
+	struct stat s;
+
+	if (plugd_proc.pid > 0)
+		kill(plugd_proc.pid, SIGKILL);
+
+	if (!stat("/tmp/sysupgrade", &s))
+		while (true)
+			sleep(1);
+
+	unsetenv("INITRAMFS");
+	unsetenv("PREINIT");
+	DEBUG(2, "Exec to real procd now\n");
+	if (wdt_fd)
+		setenv("WDTFD", wdt_fd, 1);
+	execvp(argv[0], argv);
+}
+
+static void
+plugd_proc_cb(struct uloop_process *proc, int ret)
+{
+	proc->pid = 0;
+}
+
+void
+preinit(void)
+{
+	char *init[] = { "/bin/sh", "/etc/preinit", NULL };
+	char *plug[] = { "/sbin/procd", "-h", "/etc/hotplug-preinit.json", NULL };
+
+	LOG("- preinit -\n");
+
+	plugd_proc.cb = plugd_proc_cb;
+	plugd_proc.pid = fork();
+	if (!plugd_proc.pid) {
+		execvp(plug[0], plug);
+		ERROR("Failed to start plugd\n");
+		exit(-1);
+	}
+	if (plugd_proc.pid <= 0) {
+		ERROR("Failed to start new plugd instance\n");
+		return;
+	}
+	uloop_process_add(&plugd_proc);
+
+	setenv("PREINIT", "1", 1);
+
+	preinit_proc.cb = spawn_procd;
+	preinit_proc.pid = fork();
+	if (!preinit_proc.pid) {
+		execvp(init[0], init);
+		ERROR("Failed to start preinit\n");
+		exit(-1);
+	}
+	if (preinit_proc.pid <= 0) {
+		ERROR("Failed to start new preinit instance\n");
+		return;
+	}
+	uloop_process_add(&preinit_proc);
+
+	DEBUG(4, "Launched preinit instance, pid=%d\n", (int) preinit_proc.pid);
+}

+ 5 - 5
inittab.c

@@ -72,7 +72,7 @@ static void fork_worker(struct init_action *a)
 	}
 
 	if (a->proc.pid > 0) {
-		DEBUG(2, "Launched new %s action, pid=%d\n",
+		DEBUG(4, "Launched new %s action, pid=%d\n",
 					a->handler->name,
 					(int) a->proc.pid);
 		uloop_process_add(&a->proc);
@@ -83,7 +83,7 @@ static void child_exit(struct uloop_process *proc, int ret)
 {
 	struct init_action *a = container_of(proc, struct init_action, proc);
 
-	DEBUG(2, "pid:%d\n", proc->pid);
+	DEBUG(4, "pid:%d\n", proc->pid);
         uloop_timeout_set(&a->tout, a->respawn);
 }
 
@@ -116,7 +116,7 @@ static void askfirst(struct init_action *a)
 	i = stat(a->id, &s);
 	chdir("/");
 	if (i || (console && !strcmp(console, a->id))) {
-		DEBUG(2, "Skipping %s\n", a->id);
+		DEBUG(4, "Skipping %s\n", a->id);
 		return;
 	}
 
@@ -156,7 +156,7 @@ static void askconsole(struct init_action *a)
 	i = stat(tty, &s);
 	chdir("/");
 	if (i) {
-		DEBUG(2, "skipping %s\n", tty);
+		DEBUG(4, "skipping %s\n", tty);
 		goto err_out;
 	}
 	console = strdup(tty);
@@ -265,7 +265,7 @@ void procd_inittab(void)
 		if (regexec(&pat_inittab, line, 5, matches, 0))
 			continue;
 
-		DEBUG(2, "Parsing inittab - %s", line);
+		DEBUG(4, "Parsing inittab - %s", line);
 
 		for (i = TAG_ID; i <= TAG_PROCESS; i++) {
 			line[matches[i].rm_eo] = '\0';

+ 0 - 6
libvalidate.h

@@ -1,6 +0,0 @@
-#ifndef _VALIDATE_H__
-#define _VALIDATE_H__
-
-bool dt_parse(const char *code, const char *value);
-
-#endif

+ 0 - 135
log.c

@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/types.h>
-
-#include <libubox/uloop.h>
-#include <libubox/blobmsg_json.h>
-
-#include "procd.h"
-#include "syslog.h"
-
-static int notify;
-struct ubus_context *_ctx;
-static struct blob_buf b;
-
-static const struct blobmsg_policy read_policy =
-	{ .name = "lines", .type = BLOBMSG_TYPE_INT32 };
-
-static const struct blobmsg_policy write_policy =
-	{ .name = "event", .type = BLOBMSG_TYPE_STRING };
-
-static int read_log(struct ubus_context *ctx, struct ubus_object *obj,
-		struct ubus_request_data *req, const char *method,
-		struct blob_attr *msg)
-{
-	struct blob_attr *tb;
-	struct log_head *l;
-	void *lines, *entry;
-	int count = 0;
-
-	if (msg) {
-		blobmsg_parse(&read_policy, 1, &tb, blob_data(msg), blob_len(msg));
-		if (tb)
-			count = blobmsg_get_u32(tb);
-	}
-
-	blob_buf_init(&b, 0);
-	lines = blobmsg_open_array(&b, "lines");
-
-	l = log_list(count, NULL);
-
-	while (l) {
-		entry = blobmsg_open_table(&b, NULL);
-		blobmsg_add_string(&b, "msg", l->data);
-		blobmsg_add_u32(&b, "id", l->id);
-		blobmsg_add_u32(&b, "priority", l->priority);
-		blobmsg_add_u32(&b, "source", l->source);
-		blobmsg_add_u64(&b, "time", l->ts.tv_sec);
-		blobmsg_close_table(&b, entry);
-		l = log_list(count, l);
-	}
-	blobmsg_close_table(&b, lines);
-	ubus_send_reply(ctx, req, b.head);
-
-	return 0;
-}
-
-static int write_log(struct ubus_context *ctx, struct ubus_object *obj,
-		struct ubus_request_data *req, const char *method,
-		struct blob_attr *msg)
-{
-	struct blob_attr *tb;
-	char *event;
-
-	if (msg) {
-		blobmsg_parse(&write_policy, 1, &tb, blob_data(msg), blob_len(msg));
-		if (tb) {
-			event = blobmsg_get_string(tb);
-			log_add(event, strlen(event) + 1, SOURCE_SYSLOG);
-		}
-	}
-
-	return 0;
-}
-
-static void log_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
-{
-	notify = obj->has_subscribers;
-}
-
-static const struct ubus_method log_methods[] = {
-	{ .name = "read", .handler = read_log, .policy = &read_policy, .n_policy = 1 },
-	{ .name = "write", .handler = write_log, .policy = &write_policy, .n_policy = 1 },
-};
-
-static struct ubus_object_type log_object_type =
-	UBUS_OBJECT_TYPE("log", log_methods);
-
-static struct ubus_object log_object = {
-	.name = "log",
-	.type = &log_object_type,
-	.methods = log_methods,
-	.n_methods = ARRAY_SIZE(log_methods),
-	.subscribe_cb = log_subscribe_cb,
-};
-
-void ubus_notify_log(struct log_head *l)
-{
-	int ret;
-
-	if (!notify)
-		return;
-
-	blob_buf_init(&b, 0);
-	blobmsg_add_u32(&b, "id", l->id);
-	blobmsg_add_u32(&b, "priority", l->priority);
-	blobmsg_add_u32(&b, "source", l->source);
-	blobmsg_add_u64(&b, "time", (((__u64) l->ts.tv_sec) * 1000) + (l->ts.tv_nsec / 1000000));
-
-	ret = ubus_notify(_ctx, &log_object, l->data, b.head, -1);
-	if (ret)
-		ERROR("Failed to notify log: %s\n", ubus_strerror(ret));
-}
-
-void ubus_init_log(struct ubus_context *ctx)
-{
-	int ret;
-
-	_ctx = ctx;
-
-	ret = ubus_add_object(ctx, &log_object);
-	if (ret)
-		ERROR("Failed to add object: %s\n", ubus_strerror(ret));
-}

+ 18 - 23
syslog.h → log.h

@@ -12,32 +12,27 @@
  * GNU General Public License for more details.
  */
 
-#ifndef __SYSLOG_H
-#define __SYSLOG_H
+#ifndef __LOG_H
+#define __LOG_H
 
-enum {
-	SOURCE_KLOG = 0,
-	SOURCE_SYSLOG = 1,
-	SOURCE_INTERNAL = 2,
-	SOURCE_ANY = 0xff,
-};
+#include <syslog.h>
 
-struct log_head {
-	unsigned int size;
-	unsigned int id;
-	int priority;
-	int source;
-        struct timespec ts;
-	char data[];
-};
+#define DEBUG(level, fmt, ...) do { \
+	if (debug >= level) { \
+		syslog(0, fmt, ## __VA_ARGS__); \
+		fprintf(stderr, "procd: %s(%d): " fmt, __func__, __LINE__, ## __VA_ARGS__); \
+	} } while (0)
 
-void log_init(void);
-void log_shutdown(void);
+#define LOG(fmt, ...) do { \
+		syslog(0, fmt, ## __VA_ARGS__); \
+		fprintf(stderr, "procd: "fmt, ## __VA_ARGS__); \
+	} while (0)
 
-typedef void (*log_list_cb)(struct log_head *h);
-struct log_head* log_list(int count, struct log_head *h);
-int log_buffer_init(int size);
-void log_add(char *buf, int size, int source);
-void log_printf(char *fmt, ...);
+#define ERROR(fmt, ...) do { \
+		syslog(0, fmt, ## __VA_ARGS__); \
+		fprintf(stderr, "procd: "fmt, ## __VA_ARGS__); \
+	} while (0)
+
+extern unsigned int debug;
 
 #endif

+ 0 - 369
logread.c

@@ -1,369 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <fcntl.h>
-#include <time.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#define SYSLOG_NAMES
-#include <syslog.h>
-
-#include <libubox/blobmsg_json.h>
-#include <libubox/usock.h>
-#include <libubox/uloop.h>
-#include "libubus.h"
-#include "syslog.h"
-
-enum {
-	LOG_STDOUT,
-	LOG_FILE,
-	LOG_NET,
-};
-
-enum {
-	LOG_MSG,
-	LOG_ID,
-	LOG_PRIO,
-	LOG_SOURCE,
-	LOG_TIME,
-	__LOG_MAX
-};
-
-static const struct blobmsg_policy log_policy[] = {
-	[LOG_MSG] = { .name = "msg", .type = BLOBMSG_TYPE_STRING },
-	[LOG_ID] = { .name = "id", .type = BLOBMSG_TYPE_INT32 },
-	[LOG_PRIO] = { .name = "priority", .type = BLOBMSG_TYPE_INT32 },
-	[LOG_SOURCE] = { .name = "source", .type = BLOBMSG_TYPE_INT32 },
-	[LOG_TIME] = { .name = "time", .type = BLOBMSG_TYPE_INT64 },
-};
-
-static struct ubus_subscriber log_event;
-static struct uloop_timeout retry;
-static struct uloop_fd sender;
-static const char *log_file, *log_ip, *log_port, *log_prefix, *pid_file, *hostname;
-static int log_type = LOG_STDOUT;
-static int log_size, log_udp;
-
-static const char* getcodetext(int value, CODE *codetable) {
-	CODE *i;
-
-	if (value >= 0)
-		for (i = codetable; i->c_val != -1; i++)
-			if (i->c_val == value)
-				return (i->c_name);
-	return "<unknown>";
-};
-
-static void log_handle_reconnect(struct uloop_timeout *timeout)
-{
-	sender.fd = usock((log_udp) ? (USOCK_UDP) : (USOCK_TCP), log_ip, log_port);
-	if (sender.fd < 0) {
-		fprintf(stderr, "failed to connect: %s\n", strerror(errno));
-		uloop_timeout_set(&retry, 1000);
-	} else {
-		uloop_fd_add(&sender, ULOOP_READ);
-		syslog(0, "Logread connected to %s:%s\n", log_ip, log_port);
-	}
-}
-
-static void log_handle_remove(struct ubus_context *ctx, struct ubus_subscriber *s,
-			uint32_t id)
-{
-	fprintf(stderr, "Object %08x went away\n", id);
-}
-
-static void log_handle_fd(struct uloop_fd *u, unsigned int events)
-{
-	if (u->eof) {
-		uloop_fd_delete(u);
-		close(sender.fd);
-		sender.fd = -1;
-		uloop_timeout_set(&retry, 1000);
-	}
-}
-
-static int log_notify(struct ubus_context *ctx, struct ubus_object *obj,
-			struct ubus_request_data *req, const char *method,
-			struct blob_attr *msg)
-{
-	struct blob_attr *tb[__LOG_MAX];
-	struct stat s;
-	char buf[512];
-	uint32_t p;
-	char *str;
-	time_t t;
-	char *c;
-
-	if (sender.fd < 0)
-		return 0;
-
-	blobmsg_parse(log_policy, ARRAY_SIZE(log_policy), tb, blob_data(msg), blob_len(msg));
-	if (!tb[LOG_ID] || !tb[LOG_PRIO] || !tb[LOG_SOURCE] || !tb[LOG_TIME])
-		return 1;
-
-	if ((log_type == LOG_FILE) && log_size && (!stat(log_file, &s)) && (s.st_size > log_size)) {
-		char *old = malloc(strlen(log_file) + 5);
-
-		close(sender.fd);
-		if (old) {
-			sprintf(old, "%s.old", log_file);
-			rename(log_file, old);
-			free(old);
-		}
-		sender.fd = open(log_file, O_CREAT | O_WRONLY | O_APPEND, 0600);
-		if (sender.fd < 0) {
-//			fprintf(stderr, "failed to open %s: %s\n", log_file, strerror(errno));
-			exit(-1);
-		}
-	}
-
-	t = blobmsg_get_u64(tb[LOG_TIME]) / 1000;
-	c = ctime(&t);
-	p = blobmsg_get_u32(tb[LOG_PRIO]);
-	c[strlen(c) - 1] = '\0';
-	str = blobmsg_format_json(msg, true);
-	if (log_type == LOG_NET) {
-		int err;
-
-		*buf = '\0';
-		if (hostname)
-			snprintf(buf, sizeof(buf), "%s ", hostname);
-		if (log_prefix) {
-			strncat(buf, log_prefix, sizeof(buf));
-			strncat(buf, ": ", sizeof(buf));
-		}
-		if (blobmsg_get_u32(tb[LOG_SOURCE]) == SOURCE_KLOG)
-			strncat(buf, "kernel: ", sizeof(buf));
-		strncat(buf, method, sizeof(buf));
-		if (log_udp)
-			err = write(sender.fd, buf, strlen(buf));
-		else
-			err = send(sender.fd, buf, strlen(buf), 0);
-
-		if (err < 0) {
-			syslog(0, "failed to send log data to %s:%s via %s\n",
-				log_ip, log_port, (log_udp) ? ("udp") : ("tcp"));
-			uloop_fd_delete(&sender);
-			close(sender.fd);
-			sender.fd = -1;
-			uloop_timeout_set(&retry, 1000);
-		}
-	} else {
-		snprintf(buf, sizeof(buf), "%s %s.%s%s %s\n",
-			c, getcodetext(LOG_FAC(p) << 3, facilitynames), getcodetext(LOG_PRI(p), prioritynames),
-			(blobmsg_get_u32(tb[LOG_SOURCE])) ? ("") : (" kernel:"),
-			method);
-		write(sender.fd, buf, strlen(buf));
-	}
-
-	free(str);
-	if (log_type == LOG_FILE)
-		fsync(sender.fd);
-
-	return 0;
-}
-
-static void follow_log(struct ubus_context *ctx, int id)
-{
-	FILE *fp;
-	int ret;
-
-	signal(SIGPIPE, SIG_IGN);
-
-	if (pid_file) {
-		fp = fopen(pid_file, "w+");
-		if (fp) {
-			fprintf(fp, "%d", getpid());
-			fclose(fp);
-		}
-	}
-
-	uloop_init();
-	ubus_add_uloop(ctx);
-
-	log_event.remove_cb = log_handle_remove;
-	log_event.cb = log_notify;
-	ret = ubus_register_subscriber(ctx, &log_event);
-	if (ret)
-		fprintf(stderr, "Failed to add watch handler: %s\n", ubus_strerror(ret));
-
-	ret = ubus_subscribe(ctx, &log_event, id);
-	if (ret)
-		fprintf(stderr, "Failed to add watch handler: %s\n", ubus_strerror(ret));
-
-	if (log_ip && log_port) {
-		openlog("logread", LOG_PID, LOG_DAEMON);
-		log_type = LOG_NET;
-		sender.cb = log_handle_fd;
-		retry.cb = log_handle_reconnect;
-		uloop_timeout_set(&retry, 1000);
-	} else if (log_file) {
-		log_type = LOG_FILE;
-		sender.fd = open(log_file, O_CREAT | O_WRONLY| O_APPEND, 0600);
-		if (sender.fd < 0) {
-			fprintf(stderr, "failed to open %s: %s\n", log_file, strerror(errno));
-			exit(-1);
-		}
-	} else {
-		sender.fd = STDOUT_FILENO;
-	}
-
-	uloop_run();
-	ubus_free(ctx);
-	uloop_done();
-}
-
-enum {
-	READ_LINE,
-	__READ_MAX
-};
-
-
-
-static const struct blobmsg_policy read_policy[] = {
-	[READ_LINE] = { .name = "lines", .type = BLOBMSG_TYPE_ARRAY },
-};
-
-static void read_cb(struct ubus_request *req, int type, struct blob_attr *msg)
-{
-	struct blob_attr *cur;
-	struct blob_attr *_tb[__READ_MAX];
-	time_t t;
-	int rem;
-
-	if (!msg)
-		return;
-
-	blobmsg_parse(read_policy, ARRAY_SIZE(read_policy), _tb, blob_data(msg), blob_len(msg));
-	if (!_tb[READ_LINE])
-		return;
-	blobmsg_for_each_attr(cur, _tb[READ_LINE], rem) {
-		struct blob_attr *tb[__LOG_MAX];
-		uint32_t p;
-		char *c;
-
-		if (blobmsg_type(cur) != BLOBMSG_TYPE_TABLE)
-			continue;
-
-		blobmsg_parse(log_policy, ARRAY_SIZE(log_policy), tb, blobmsg_data(cur), blobmsg_data_len(cur));
-		if (!tb[LOG_MSG] || !tb[LOG_ID] || !tb[LOG_PRIO] || !tb[LOG_SOURCE] || !tb[LOG_TIME])
-			continue;
-
-		t = blobmsg_get_u64(tb[LOG_TIME]);
-		p = blobmsg_get_u32(tb[LOG_PRIO]);
-		c = ctime(&t);
-		c[strlen(c) - 1] = '\0';
-
-		printf("%s %s.%s%s %s\n",
-			c, getcodetext(LOG_FAC(p) << 3, facilitynames), getcodetext(LOG_PRI(p), prioritynames),
-			(blobmsg_get_u32(tb[LOG_SOURCE])) ? ("") : (" kernel:"),
-			blobmsg_get_string(tb[LOG_MSG]));
-	}
-}
-
-static int usage(const char *prog)
-{
-	fprintf(stderr, "Usage: %s [options]\n"
-		"Options:\n"
-		"    -s <path>		Path to ubus socket\n"
-		"    -l	<count>		Got only the last 'count' messages\n"
-		"    -r	<server> <port>	Stream message to a server\n"
-		"    -F	<file>		Log file\n"
-		"    -S	<bytes>		Log size\n"
-		"    -p	<file>		PID file\n"
-		"    -h	<hostname>	Add hostname to the message\n"
-		"    -P	<prefix>	Prefix custom text to streamed messages\n"
-		"    -f			Follow log messages\n"
-		"    -u			Use UDP as the protocol\n"
-		"\n", prog);
-	return 1;
-}
-
-int main(int argc, char **argv)
-{
-	struct ubus_context *ctx;
-	uint32_t id;
-	const char *ubus_socket = NULL;
-	int ch, ret, subscribe = 0, lines = 0;
-	static struct blob_buf b;
-
-	while ((ch = getopt(argc, argv, "ufcs:l:r:F:p:S:P:h:")) != -1) {
-		switch (ch) {
-		case 'u':
-			log_udp = 1;
-			break;
-		case 's':
-			ubus_socket = optarg;
-			break;
-		case 'r':
-			log_ip = optarg++;
-			log_port = argv[optind++];
-			break;
-		case 'F':
-			log_file = optarg;
-			break;
-		case 'p':
-			pid_file = optarg;
-			break;
-		case 'P':
-			log_prefix = optarg;
-			break;
-		case 'f':
-			subscribe = 1;
-			break;
-		case 'l':
-			lines = atoi(optarg);
-			break;
-		case 'S':
-			log_size = atoi(optarg);
-			if (log_size < 1)
-				log_size = 1;
-			log_size *= 1024;
-			break;
-		case 'h':
-			hostname = optarg;
-			break;
-		default:
-			return usage(*argv);
-		}
-	}
-
-	ctx = ubus_connect(ubus_socket);
-	if (!ctx) {
-		fprintf(stderr, "Failed to connect to ubus\n");
-		return -1;
-	}
-
-	ret = ubus_lookup_id(ctx, "log", &id);
-	if (ret)
-		fprintf(stderr, "Failed to find log object: %s\n", ubus_strerror(ret));
-
-	if (!subscribe || lines) {
-		blob_buf_init(&b, 0);
-		if (lines)
-			blobmsg_add_u32(&b, "lines", lines);
-		ubus_invoke(ctx, id, "read", b.head, read_cb, 0, 3000);
-	}
-
-	if (subscribe)
-		follow_log(ctx, id);
-
-	return 0;
-}

+ 0 - 99
measure.c

@@ -1,99 +0,0 @@
-/**
- *   Copyright (C) 2010 Steven Barth <steven@midlink.org>
- *   Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- *
- */
-
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <regex.h>
-#include <stdio.h>
-#include <string.h>
-#include <glob.h>
-#include <libgen.h>
-
-#include "procd.h"
-
-static regex_t pat_vmsize, pat_ppid, pat_state, pat_uid;
-
-static void __attribute__((constructor)) measure_init() {
-	regcomp(&pat_vmsize, "VmSize:[ \t]*([0-9]*) kB", REG_EXTENDED);
-	regcomp(&pat_uid, "Uid:[ \t]*([0-9]*).*", REG_EXTENDED);
-	regcomp(&pat_ppid, "PPid:[ \t]*([0-9]+)", REG_EXTENDED);
-	regcomp(&pat_state, "State:[ \t]*([A-Z])", REG_EXTENDED);
-}
-
-static void __attribute__((destructor)) measure_fini() {
-	regfree(&pat_vmsize);
-	regfree(&pat_ppid);
-	regfree(&pat_uid);
-	regfree(&pat_state);
-}
-
-int measure_process(pid_t pid, struct pid_info *pi) {
-	int fd;
-	char buffer[512] = "";
-	ssize_t rxed;
-	regmatch_t matches[2];
-	glob_t gl;
-	int i;
-
-	memset(pi, 0, sizeof(*pi));
-
-	snprintf(buffer, sizeof(buffer), "/proc/%i/fd/*", (int)pid);
-
-	if (glob(buffer, GLOB_NOESCAPE | GLOB_MARK, NULL, &gl)) {
-		fprintf(stderr, "glob failed on %s\n", buffer);
-		return -1;
-	}
-
-	for (i = 0; i < gl.gl_pathc; i++)
-		if (isdigit(basename(gl.gl_pathv[i])[0]))
-			pi->fdcount++;
-	globfree(&gl);
-
-	snprintf(buffer, sizeof(buffer), "/proc/%i/status", (int)pid);
-	fd = open(buffer, O_RDONLY);
-	if (fd == -1)
-		return -1;
-
-	rxed = read(fd, buffer, sizeof(buffer) - 1);
-	close(fd);
-	if (rxed == -1)
-		return -1;
-
-	buffer[rxed] = 0;
-
-	if (!regexec(&pat_state, buffer, 2, matches, 0))
-		pi->stat = buffer[matches[1].rm_so];
-
-	if (!regexec(&pat_ppid, buffer, 2, matches, 0))
-		pi->ppid = atoi(buffer + matches[1].rm_so);
-
-	if (!regexec(&pat_uid, buffer, 2, matches, 0))
-		pi->uid = atoi(buffer + matches[1].rm_so);
-
-	if (!regexec(&pat_vmsize, buffer, 2, matches, 0))
-		pi->vmsize = atoi(buffer + matches[1].rm_so) * 1024;
-
-	return 0;
-}

+ 5 - 4
coldplug.c → plug/coldplug.c

@@ -18,21 +18,22 @@
 
 #include <unistd.h>
 
-#include "procd.h"
+#include "../procd.h"
+
 #include "hotplug.h"
 
 static struct uloop_process udevtrigger;
 
 static void coldplug_complete(struct uloop_timeout *t)
 {
-	DEBUG(2, "Coldplug complete\n");
+	DEBUG(4, "Coldplug complete\n");
 	hotplug_last_event(NULL);
 	procd_state_next();
 }
 
 static void udevtrigger_complete(struct uloop_process *proc, int ret)
 {
-	DEBUG(2, "Finished udevtrigger\n");
+	DEBUG(4, "Finished udevtrigger\n");
 	hotplug_last_event(coldplug_complete);
 }
 
@@ -61,5 +62,5 @@ void procd_coldplug(void)
 
 	uloop_process_add(&udevtrigger);
 
-	DEBUG(2, "Launched coldplug instance, pid=%d\n", (int) udevtrigger.pid);
+	DEBUG(4, "Launched coldplug instance, pid=%d\n", (int) udevtrigger.pid);
 }

+ 23 - 13
hotplug.c → plug/hotplug.c

@@ -28,7 +28,8 @@
 #include <stdlib.h>
 #include <libgen.h>
 
-#include "procd.h"
+#include "../procd.h"
+
 #include "hotplug.h"
 
 #define HOTPLUG_WAIT	500
@@ -137,7 +138,7 @@ static void handle_exec(struct blob_attr *msg, struct blob_attr *data)
 			break;
 	}
 
-	if (debug < 2) {
+	if (debug < 3) {
 		fd = open("/dev/null", O_RDWR);
 		if (fd > -1) {
 			dup2(fd, STDIN_FILENO);
@@ -165,7 +166,7 @@ static void handle_firmware(struct blob_attr *msg, struct blob_attr *data)
 	char *path, loadpath[256], syspath[256];
 	int fw, load, sys, len;
 
-	DEBUG(1, "Firmware request for %s/%s\n", dir, file);
+	DEBUG(2, "Firmware request for %s/%s\n", dir, file);
 
 	if (!file || !dir || !dev) {
 		ERROR("Request for unknown firmware %s/%s\n", dir, file);
@@ -230,7 +231,7 @@ static void handle_firmware(struct blob_attr *msg, struct blob_attr *data)
 	write(load, "0", 1);
 	close(load);
 
-	DEBUG(1, "Done loading %s\n", path);
+	DEBUG(2, "Done loading %s\n", path);
 
 	exit(-1);
 }
@@ -283,12 +284,12 @@ static void queue_next(void)
 
 	uloop_process_add(&queue_proc);
 
-	DEBUG(2, "Launched hotplug exec instance, pid=%d\n", (int) queue_proc.pid);
+	DEBUG(4, "Launched hotplug exec instance, pid=%d\n", (int) queue_proc.pid);
 }
 
 static void queue_proc_cb(struct uloop_process *c, int ret)
 {
-	DEBUG(2, "Finished hotplug exec instance, pid=%d\n", (int) c->pid);
+	DEBUG(4, "Finished hotplug exec instance, pid=%d\n", (int) c->pid);
 
 	queue_next();
 }
@@ -356,16 +357,16 @@ static void rule_handle_command(struct json_script_ctx *ctx, const char *name,
 	struct blob_attr *cur;
 	int rem, i;
 
-	if (debug > 1) {
-		DEBUG(2, "Command: %s", name);
+	if (debug > 3) {
+		DEBUG(4, "Command: %s", name);
 		blobmsg_for_each_attr(cur, data, rem)
-			DEBUG(2, " %s", (char *) blobmsg_data(cur));
-		DEBUG(2, "\n");
+			DEBUG(4, " %s", (char *) blobmsg_data(cur));
+		DEBUG(4, "\n");
 
-		DEBUG(2, "Message:");
+		DEBUG(4, "Message:");
 		blobmsg_for_each_attr(cur, vars, rem)
-			DEBUG(2, " %s=%s", blobmsg_name(cur), (char *) blobmsg_data(cur));
-		DEBUG(2, "\n");
+			DEBUG(4, " %s=%s", blobmsg_name(cur), (char *) blobmsg_data(cur));
+		DEBUG(4, "\n");
 	}
 
 	for (i = 0; i < ARRAY_SIZE(handlers); i++)
@@ -461,6 +462,15 @@ void hotplug(char *rules)
 	uloop_fd_add(&hotplug_fd, ULOOP_READ);
 }
 
+int hotplug_run(char *rules)
+{
+	uloop_init();
+	hotplug(rules);
+	uloop_run();
+
+	return 0;
+}
+
 void hotplug_shutdown(void)
 {
 	uloop_fd_delete(&hotplug_fd);

+ 1 - 0
hotplug.h → plug/hotplug.h

@@ -18,6 +18,7 @@
 #include <libubox/uloop.h>
 
 void hotplug(char *rules);
+int hotplug_run(char *rules);
 void hotplug_shutdown(void);
 void hotplug_last_event(uloop_timeout_handler handler);
 

+ 0 - 0
udevtrigger.c → plug/udevtrigger.c


+ 0 - 68
preinit.c

@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-
-#include <unistd.h>
-#include <unistd.h>
-
-#include "procd.h"
-#include "hotplug.h"
-#include "watchdog.h"
-
-static struct uloop_process preinit;
-
-static void spawn_procd(struct uloop_process *proc, int ret)
-{
-	char *wdt_fd = watchdog_fd();
-	char *argv[] = { "/sbin/procd", NULL };
-	struct stat s;
-
-	if (!stat("/tmp/sysupgrade", &s))
-		while (true)
-			sleep(1);
-
-	unsetenv("INITRAMFS");
-	unsetenv("PREINIT");
-	DEBUG(1, "Exec to real procd now\n");
-	if (wdt_fd)
-		setenv("WDTFD", wdt_fd, 1);
-	execvp(argv[0], argv);
-}
-
-void procd_preinit(void)
-{
-	char *argv[] = { "/bin/sh", "/etc/preinit", NULL };
-
-	LOG("- preinit -\n");
-
-	setenv("PREINIT", "1", 1);
-	preinit.cb = spawn_procd;
-	preinit.pid = fork();
-	if (!preinit.pid) {
-		execvp(argv[0], argv);
-		ERROR("Failed to start preinit\n");
-		exit(-1);
-	}
-
-	if (preinit.pid <= 0) {
-		ERROR("Failed to start new preinit instance\n");
-		return;
-	}
-
-	uloop_process_add(&preinit);
-	DEBUG(2, "Launched preinit instance, pid=%d\n", (int) preinit.pid);
-}

+ 9 - 22
main.c → procd.c

@@ -21,43 +21,30 @@
 #include <libgen.h>
 
 #include "procd.h"
-#include "hotplug.h"
 #include "watchdog.h"
+#include "plug/hotplug.h"
+
+unsigned int debug;
 
 static int usage(const char *prog)
 {
 	ERROR("Usage: %s [options]\n"
 		"Options:\n"
-		"    -s <path>:		Path to ubus socket\n"
-		"    -d:		Enable debug messages\n"
+		"\t-s <path>\tPath to ubus socket\n"
+		"\t-h <path>\trun as hotplug daemon\n"
+		"\td\t\tEnable debug messages\n"
 		"\n", prog);
 	return 1;
 }
 
-
-static int main_procd_init(int argc, char **argv)
-{
-	procd_signal_preinit();
-	procd_early();
-	debug_init();
-	watchdog_init(1);
-	system("/sbin/kmodloader /etc/modules-boot.d/");
-	uloop_init();
-	hotplug("/etc/hotplug-preinit.json");
-	procd_preinit();
-	uloop_run();
-	return 0;
-}
-
 int main(int argc, char **argv)
 {
 	int ch;
 
-	if (!strcmp(basename(*argv), "init"))
-		return main_procd_init(argc, argv);
-
-	while ((ch = getopt(argc, argv, "ds:")) != -1) {
+	while ((ch = getopt(argc, argv, "ds:h:")) != -1) {
 		switch (ch) {
+		case 'h':
+			return hotplug_run(optarg);
 		case 's':
 			ubus_socket = optarg;
 			break;

+ 1 - 32
procd.h

@@ -22,37 +22,17 @@
 #include <stdio.h>
 #include <syslog.h>
 
-#include "syslog.h"
+#include "log.h"
 
 #define __init __attribute__((constructor))
 
-#define DEBUG(level, fmt, ...) do { \
-	if (debug >= level) \
-		fprintf(stderr, "procd: %s(%d): " fmt, __func__, __LINE__, ## __VA_ARGS__); \
-	} while (0)
-
-#define LOG(fmt, ...) do { \
-	log_printf(fmt, ## __VA_ARGS__); \
-	fprintf(stderr, "procd: "fmt, ## __VA_ARGS__); \
-	} while (0)
-
-#define ERROR(fmt, ...) do { \
-	log_printf(fmt, ## __VA_ARGS__); \
-	fprintf(stderr, "procd: "fmt, ## __VA_ARGS__); \
-	} while (0)
-
 extern char *ubus_socket;
 extern int upgrade_running;
 
-extern unsigned int debug;
-void debug_init(void);
-
 void procd_connect_ubus(void);
 void procd_reconnect_ubus(int reconnect);
 void ubus_init_service(struct ubus_context *ctx);
-void ubus_init_log(struct ubus_context *ctx);
 void ubus_init_system(struct ubus_context *ctx);
-void ubus_notify_log(struct log_head *l);
 
 void procd_state_next(void);
 void procd_shutdown(int event);
@@ -64,21 +44,10 @@ void procd_signal_preinit(void);
 void procd_inittab(void);
 void procd_inittab_run(const char *action);
 
-int mkdev(const char *progname, int progmode);
-
 struct trigger;
 void trigger_init(void);
 void trigger_event(char *type, struct blob_attr *data);
 void trigger_add(struct blob_attr *rule, void *id);
 void trigger_del(void *id);
 
-struct pid_info {
-	char stat;
-	uint32_t ppid;
-	uint32_t fdcount;
-	uint32_t vmsize;
-	uint16_t uid;
-};
-int measure_process(pid_t pid, struct pid_info *pi);
-
 #endif

+ 5 - 5
rcS.c

@@ -55,7 +55,7 @@ static void pipe_cb(struct ustream *s, int bytes)
 			break;
 		*newline = 0;
 		len = newline + 1 - str;
-		log_printf(buf->data);
+		syslog(0, buf->data);
 		ustream_consume(s, len);
 	} while (1);
 }
@@ -66,7 +66,7 @@ static void q_initd_run(struct runqueue *q, struct runqueue_task *t)
 	int pipefd[2];
 	pid_t pid;
 
-	DEBUG(1, "start %s %s \n", s->file, s->param);
+	DEBUG(2, "start %s %s \n", s->file, s->param);
 	if (pipe(pipefd) == -1) {
 		ERROR("Failed to create pipe\n");
 		return;
@@ -96,7 +96,7 @@ static void q_initd_complete(struct runqueue *q, struct runqueue_task *p)
 {
 	struct initd *s = container_of(p, struct initd, proc.task);
 
-	DEBUG(1, "stop %s %s \n", s->file, s->param);
+	DEBUG(2, "stop %s %s \n", s->file, s->param);
 	ustream_free(&s->fd.stream);
 	close(s->fd.fd.fd);
 	free(s);
@@ -126,10 +126,10 @@ static int _rc(struct runqueue *q, char *path, const char *file, char *pattern,
 	int j;
 
 
-	DEBUG(1, "running %s/%s%s %s\n", path, file, pattern, param);
+	DEBUG(2, "running %s/%s%s %s\n", path, file, pattern, param);
 	snprintf(dir, sizeof(dir), "%s/%s%s", path, file, pattern);
 	if (glob(dir, GLOB_NOESCAPE | GLOB_MARK, NULL, &gl)) {
-		printf("glob failed on %s\n", dir);
+		DEBUG(2, "glob failed on %s\n", dir);
 		return -1;
 	}
 

+ 7 - 18
instance.c → service/instance.c

@@ -20,10 +20,12 @@
 #include <stdint.h>
 #include <fcntl.h>
 
-#include "procd.h"
+#include "../procd.h"
+
 #include "service.h"
 #include "instance.h"
-#include "md5.h"
+
+#include "../utils/md5.h"
 
 enum {
 	INSTANCE_ATTR_COMMAND,
@@ -119,7 +121,7 @@ instance_start(struct service_instance *in)
 		return;
 	}
 
-	DEBUG(1, "Started instance %s::%s\n", in->srv->name, in->name);
+	DEBUG(2, "Started instance %s::%s\n", in->srv->name, in->name);
 	in->proc.pid = pid;
 	clock_gettime(CLOCK_MONOTONIC, &in->start);
 	uloop_process_add(&in->proc);
@@ -148,7 +150,7 @@ instance_exit(struct uloop_process *p, int ret)
 	clock_gettime(CLOCK_MONOTONIC, &tp);
 	runtime = tp.tv_sec - in->start.tv_sec;
 
-	DEBUG(1, "Instance %s::%s exit with error code %d after %ld seconds\n", in->srv->name, in->name, ret, runtime);
+	DEBUG(2, "Instance %s::%s exit with error code %d after %ld seconds\n", in->srv->name, in->name, ret, runtime);
 	if (upgrade_running)
 		return;
 
@@ -448,7 +450,6 @@ instance_init(struct service_instance *in, struct service *s, struct blob_attr *
 void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose)
 {
 	void *i;
-	struct pid_info pi;
 
 	i = blobmsg_open_table(b, in->name);
 	blobmsg_add_u8(b, "running", in->proc.pending);
@@ -474,18 +475,6 @@ void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose)
 
 	if (verbose && in->trigger)
 		blobmsg_add_blob(b, in->trigger);
-	if (!measure_process(in->proc.pid, &pi)) {
-		struct timespec tp;
-		long uptime;
-
-		clock_gettime(CLOCK_MONOTONIC, &tp);
-		uptime = tp.tv_sec - in->start.tv_sec;
-
-		blobmsg_add_u8(b, "ppid", pi.ppid);
-		blobmsg_add_u16(b, "uid", pi.uid);
-		blobmsg_add_u32(b, "fdcount", pi.fdcount);
-		blobmsg_add_u32(b, "vmsize", pi.vmsize);
-		blobmsg_add_u32(b, "uptime", uptime);
-	}
+
 	blobmsg_close_table(b, i);
 }

+ 1 - 1
instance.h → service/instance.h

@@ -17,7 +17,7 @@
 
 #include <libubox/vlist.h>
 #include <libubox/uloop.h>
-#include "utils.h"
+#include "../utils/utils.h"
 
 #define RESPAWN_ERROR	(5 * 60)
 

+ 38 - 7
service.c → service/service.c

@@ -14,10 +14,13 @@
 
 #include <libubox/blobmsg_json.h>
 #include <libubox/avl-cmp.h>
-#include "procd.h"
+
+#include "../procd.h"
+
 #include "service.h"
 #include "instance.h"
-#include "rcS.h"
+
+#include "../rcS.h"
 
 struct avl_tree services;
 static struct blob_buf b;
@@ -51,15 +54,15 @@ service_instance_update(struct vlist_tree *tree, struct vlist_node *node_new,
 		in_n = container_of(node_new, struct service_instance, node);
 
 	if (in_o && in_n) {
-		DEBUG(1, "Update instance %s::%s\n", in_o->srv->name, in_o->name);
+		DEBUG(2, "Update instance %s::%s\n", in_o->srv->name, in_o->name);
 		instance_update(in_o, in_n);
 		instance_free(in_n);
 	} else if (in_o) {
-		DEBUG(1, "Free instance %s::%s\n", in_o->srv->name, in_o->name);
+		DEBUG(2, "Free instance %s::%s\n", in_o->srv->name, in_o->name);
 		instance_stop(in_o);
 		instance_free(in_o);
 	} else if (in_n) {
-		DEBUG(1, "Create instance %s::%s\n", in_n->srv->name, in_n->name);
+		DEBUG(2, "Create instance %s::%s\n", in_n->srv->name, in_n->name);
 		instance_start(in_n);
 	}
 }
@@ -226,11 +229,11 @@ service_handle_set(struct ubus_context *ctx, struct ubus_object *obj,
 
 	s = avl_find_element(&services, name, s, avl);
 	if (s) {
-		DEBUG(1, "Update service %s\n", name);
+		DEBUG(2, "Update service %s\n", name);
 		return service_update(s, msg, tb, add);
 	}
 
-	DEBUG(1, "Create service %s\n", name);
+	DEBUG(2, "Create service %s\n", name);
 	s = service_alloc(name);
 	if (!s)
 		return UBUS_STATUS_UNKNOWN_ERROR;
@@ -425,6 +428,34 @@ static struct ubus_object main_object = {
 	.n_methods = ARRAY_SIZE(main_object_methods),
 };
 
+int
+service_start_early(char *name, char *cmdline)
+{
+	void *instances, *instance, *command, *respawn;
+	char *t;
+
+	blob_buf_init(&b, 0);
+	blobmsg_add_string(&b, "name", name);
+	instances = blobmsg_open_table(&b, "instances");
+	instance = blobmsg_open_table(&b, "instance1");
+	command = blobmsg_open_array(&b, "command");
+	t = strtok(cmdline, " ");
+	while (t) {
+		blobmsg_add_string(&b, NULL, t);
+		t = strtok(NULL, " ");
+	}
+	blobmsg_close_array(&b, command);
+	respawn = blobmsg_open_array(&b, "respawn");
+	blobmsg_add_string(&b, NULL, "1");
+	blobmsg_add_string(&b, NULL, "3600");
+	blobmsg_add_string(&b, NULL, "10");
+	blobmsg_close_array(&b, respawn);
+	blobmsg_close_table(&b, instance);
+	blobmsg_close_table(&b, instances);
+
+	return service_handle_set(NULL, NULL, NULL, "add", b.head);
+}
+
 void ubus_init_service(struct ubus_context *ctx)
 {
 	ubus_add_object(ctx, &main_object);

+ 1 - 0
service.h → service/service.h

@@ -49,6 +49,7 @@ struct service {
 void service_validate_add(struct service *s, struct blob_attr *attr);
 void service_validate_dump(struct blob_buf *b, struct service *s);
 void service_validate_dump_all(struct blob_buf *b, char *p, char *s);
+int service_start_early(char *name, char *cmdline);
 void service_validate_del(struct service *s);
 void service_validate_init(void);
 void service_init(void);

+ 3 - 3
trigger.c → service/trigger.c

@@ -30,7 +30,7 @@
 #include <stdlib.h>
 #include <libgen.h>
 
-#include "procd.h"
+#include "../procd.h"
 
 struct trigger {
 	struct list_head list;
@@ -84,7 +84,7 @@ static void q_job_run(struct runqueue *q, struct runqueue_task *t)
 {
 	struct job *j = container_of(t, struct job, proc.task);
 
-	DEBUG(2, "handle event %s\n", j->cmd->name);
+	DEBUG(4, "handle event %s\n", j->cmd->name);
 	j->cmd->handler(j, j->exec, j->env);
 }
 
@@ -150,7 +150,7 @@ static void handle_run_script(struct job *j, struct blob_attr *exec, struct blob
 		return;
 	}
 
-	if (debug < 2) {
+	if (debug < 3) {
 		close(STDIN_FILENO);
 		close(STDOUT_FILENO);
 		close(STDERR_FILENO);

+ 2 - 1
service_validate.c → service/validate.c

@@ -14,7 +14,8 @@
 #include <libubox/blobmsg_json.h>
 #include <libubox/avl-cmp.h>
 
-#include "procd.h"
+#include "../procd.h"
+
 #include "service.h"
 
 enum {

+ 0 - 13
signal.c

@@ -19,8 +19,6 @@
 
 #include "procd.h"
 
-static int preinit;
-
 static void do_reboot(void)
 {
 	LOG("reboot\n");
@@ -37,9 +35,6 @@ static void signal_shutdown(int signal, siginfo_t *siginfo, void *data)
 	int event = 0;
 	char *msg = NULL;
 
-	if (preinit)
-		do_reboot();
-
 	switch(signal) {
 	case SIGTERM:
 		event = RB_AUTOBOOT;
@@ -97,11 +92,3 @@ void procd_signal(void)
 	sigaction(SIGKILL, &sa_dummy, NULL);
 	sigaction(SIGSTOP, &sa_dummy, NULL);
 }
-
-void procd_signal_preinit(void)
-{
-	preinit = 1;
-	sigaction(SIGTERM, &sa_shutdown, NULL);
-	sigaction(SIGUSR1, &sa_shutdown, NULL);
-	sigaction(SIGUSR2, &sa_shutdown, NULL);
-}

+ 9 - 6
state.c

@@ -18,9 +18,9 @@
 
 #include "procd.h"
 #include "syslog.h"
-#include "hotplug.h"
+#include "plug/hotplug.h"
 #include "watchdog.h"
-#include "service.h"
+#include "service/service.h"
 
 enum {
 	STATE_NONE = 0,
@@ -49,10 +49,13 @@ static void state_enter(void)
 	case STATE_INIT:
 		// try to reopen incase the wdt was not available before coldplug
 		watchdog_init(0);
-		LOG("- init -\n");
-		log_init();
+		LOG("- ubus -\n");
 		procd_connect_ubus();
+
+		LOG("- init -\n");
 		service_init();
+		service_start_early("ubus", "/sbin/ubusd");
+
 		procd_inittab();
 		procd_inittab_run("respawn");
 		procd_inittab_run("askconsole");
@@ -83,14 +86,14 @@ static void state_enter(void)
 
 void procd_state_next(void)
 {
-	DEBUG(2, "Change state %d -> %d\n", state, state + 1);
+	DEBUG(4, "Change state %d -> %d\n", state, state + 1);
 	state++;
 	state_enter();
 }
 
 void procd_shutdown(int event)
 {
-	DEBUG(1, "Shutting down system with event %x\n", event);
+	DEBUG(2, "Shutting down system with event %x\n", event);
 	reboot_event = event;
 	state = STATE_SHUTDOWN;
 	state_enter();

+ 0 - 320
syslog.c

@@ -1,320 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/un.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-
-#include <fcntl.h>
-#include <regex.h>
-#include <time.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <libubox/uloop.h>
-#include <libubox/usock.h>
-#include <libubox/ustream.h>
-
-#include "procd.h"
-#include "syslog.h"
-
-#define LOG_DEFAULT_SIZE	(16 * 1024)
-#define LOG_DEFAULT_SOCKET	"/dev/log"
-#define LOG_LINE_LEN		256
-#define SYSLOG_PADDING		16
-
-#define KLOG_DEFAULT_PROC	"/proc/kmsg"
-
-#define PAD(x) (x % 4) ? (((x) - (x % 4)) + 4) : (x)
-
-static char *log_dev = LOG_DEFAULT_SOCKET;
-static int log_size = LOG_DEFAULT_SIZE;
-static struct log_head *log, *log_end, *oldest, *newest;
-static int current_id = 0;
-static regex_t pat_prio;
-static regex_t pat_tstamp;
-
-static struct log_head *log_next(struct log_head *h, int size)
-{
-	struct log_head *n = (struct log_head *) &h->data[PAD(sizeof(struct log_head) + size)];
-
-	return (n >= log_end) ? (log) : (n);
-}
-
-void log_add(char *buf, int size, int source)
-{
-	regmatch_t matches[4];
-	struct log_head *next;
-	int priority = 0;
-	int ret;
-
-	/* bounce out if we don't have init'ed yet (regmatch etc will blow) */
-	if (!log) {
-		fprintf(stderr, buf);
-		return;
-	}
-
-	/* strip trailing newline */
-	if (buf[size - 2] == '\n') {
-		buf[size - 2] = '\0';
-		size -= 1;
-	}
-
-	/* strip the priority */
-	ret = regexec(&pat_prio, buf, 3, matches, 0);
-	if (!ret) {
-		priority = atoi(&buf[matches[1].rm_so]);
-		size -= matches[2].rm_so;
-		buf += matches[2].rm_so;
-	}
-
-#if 0
-	/* strip kernel timestamp */
-	ret = regexec(&pat_tstamp,buf, 4, matches, 0);
-	if ((source == SOURCE_KLOG) && !ret) {
-		size -= matches[3].rm_so;
-		buf += matches[3].rm_so;
-	}
-#endif
-
-	/* strip syslog timestamp */
-	if ((source == SOURCE_SYSLOG) && (size > SYSLOG_PADDING) && (buf[SYSLOG_PADDING - 1] == ' ')) {
-		size -= SYSLOG_PADDING;
-		buf += SYSLOG_PADDING;
-	}
-
-	DEBUG(2, "-> %d - %s\n", priority, buf);
-
-	/* find new oldest entry */
-	next = log_next(newest, size);
-	if (next > newest) {
-		while ((oldest > newest) && (oldest <= next) && (oldest != log))
-			oldest = log_next(oldest, oldest->size);
-	} else {
-		DEBUG(2, "Log wrap\n");
-		newest->size = 0;
-		next = log_next(log, size);
-		for (oldest = log; oldest <= next; oldest = log_next(oldest, oldest->size))
-			;
-		newest = log;
-	}
-
-	/* add the log message */
-	newest->size = size;
-	newest->id = current_id++;
-	newest->priority = priority;
-	newest->source = source;
-	clock_gettime(CLOCK_REALTIME, &newest->ts);
-	strcpy(newest->data, buf);
-
-	ubus_notify_log(newest);
-
-	newest = next;
-}
-
-void log_printf(char *fmt, ...)
-{
-	static int buffer_len = 128;
-	static char *buffer;
-	va_list ap;
-	int n = 0;
-
-	do {
-		if (n)
-			buffer_len = n + 1;
-		if (!buffer)
-			buffer = malloc(buffer_len);
-		if (!buffer)
-			return;
-		va_start(ap, fmt);
-		n = vsnprintf(buffer, buffer_len, fmt, ap);
-		va_end(ap);
-		if (n < 1)
-			return;
-		if (n >= buffer_len) {
-			free(buffer);
-			buffer = NULL;
-		}
-	} while (n >= buffer_len);
-
-	log_add(buffer, n, SOURCE_INTERNAL);
-}
-
-static void slog_cb(struct ustream *s, int bytes)
-{
-	struct ustream_buf *buf = s->r.head;
-	char *str;
-	int len;
-
-	do {
-		str = ustream_get_read_buf(s, NULL);
-		if (!str)
-			break;
-		len = strlen(buf->data);
-		if (!len) {
-			bytes -= 1;
-			ustream_consume(s, 1);
-			continue;
-		}
-		log_add(buf->data, len + 1, SOURCE_SYSLOG);
-		ustream_consume(s, len);
-		bytes -= len;
-	} while (bytes > 0);
-}
-
-static void klog_cb(struct ustream *s, int bytes)
-{
-	struct ustream_buf *buf = s->r.head;
-	char *newline, *str;
-	int len;
-
-	do {
-		str = ustream_get_read_buf(s, NULL);
-		if (!str)
-			break;
-		newline = strchr(buf->data, '\n');
-		if (!newline)
-			break;
-		*newline = 0;
-		len = newline + 1 - str;
-		log_add(buf->data, len, SOURCE_KLOG);
-		ustream_consume(s, len);
-	} while (1);
-}
-
-struct ustream_fd slog = {
-	.stream.string_data = true,
-	.stream.notify_read = slog_cb,
-};
-
-struct ustream_fd klog = {
-	.stream.string_data = true,
-	.stream.notify_read = klog_cb,
-};
-
-static int klog_open(void)
-{
-	int fd;
-
-	DEBUG(1, "Opening %s\n", KLOG_DEFAULT_PROC);
-	fd = open(KLOG_DEFAULT_PROC, O_RDONLY | O_NONBLOCK);
-	if (fd < 0) {
-		ERROR("Failed to open %s\n", KLOG_DEFAULT_PROC);
-		return -1;
-	}
-	fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
-	ustream_fd_init(&klog, fd);
-	return 0;
-}
-
-static int syslog_open(void)
-{
-	int fd;
-
-	DEBUG(1, "Opening %s\n", log_dev);
-	unlink(log_dev);
-	fd = usock(USOCK_UNIX | USOCK_UDP |  USOCK_SERVER | USOCK_NONBLOCK, log_dev, NULL);
-	if (fd < 0) {
-		ERROR("Failed to open %s\n", log_dev);
-		return -1;
-	}
-	chmod(log_dev, 0666);
-	ustream_fd_init(&slog, fd);
-	return 0;
-}
-
-struct log_head* log_list(int count, struct log_head *h)
-{
-	unsigned int min = count;
-
-	if (count)
-		min = (count < current_id) ? (current_id - count) : (0);
-	if (!h && oldest->id >= min)
-		return oldest;
-	if (!h)
-		h = oldest;
-
-	while (h != newest) {
-		h = log_next(h, h->size);
-		if (!h->size && (h > newest))
-			h = log;
-		if (h->id >= min && (h != newest))
-			return h;
-	}
-
-	return NULL;
-}
-
-int log_buffer_init(int size)
-{
-	struct log_head *_log = malloc(size);
-
-	if (!_log) {
-		ERROR("Failed to initialize log buffer with size %d\n", log_size);
-		return -1;
-	}
-
-	memset(_log, 0, size);
-
-	if (log && ((log_size + sizeof(struct log_head)) < size)) {
-		struct log_head *start = _log;
-		struct log_head *end = ((void*) _log) + size;
-		struct log_head *l;
-
-		l = log_list(0, NULL);
-		while ((start < end) && l && l->size) {
-			memcpy(start, l, PAD(sizeof(struct log_head) + l->size));
-			start = (struct log_head *) &l->data[PAD(l->size)];
-			l = log_list(0, l);
-		}
-		free(log);
-		newest = start;
-		newest->size = 0;
-		oldest = log = _log;
-		log_end = ((void*) log) + size;
-	} else {
-		oldest = newest = log = _log;
-		log_end = ((void*) log) + size;
-	}
-	log_size = size;
-
-	return 0;
-}
-
-void log_init(void)
-{
-	regcomp(&pat_prio, "^<([0-9]*)>(.*)", REG_EXTENDED);
-	regcomp(&pat_tstamp, "^\[[ 0]*([0-9]*).([0-9]*)] (.*)", REG_EXTENDED);
-
-	if (log_buffer_init(log_size)) {
-		ERROR("Failed to allocate log memory\n");
-		exit(-1);
-	}
-
-	syslog_open();
-	klog_open();
-	openlog("sysinit", LOG_CONS, LOG_DAEMON);
-}
-
-void log_shutdown(void)
-{
-	ustream_free(&slog.stream);
-	ustream_free(&klog.stream);
-	close(slog.fd.fd);
-	close(klog.fd.fd);
-}

+ 0 - 6
system.c

@@ -25,7 +25,6 @@
 
 #include "procd.h"
 #include "watchdog.h"
-#include "hotplug.h"
 
 static struct blob_buf b;
 
@@ -189,12 +188,7 @@ static int system_upgrade(struct ubus_context *ctx, struct ubus_object *obj,
 			struct ubus_request_data *req, const char *method,
 			struct blob_attr *msg)
 {
-	procd_reconnect_ubus(0);
-	log_shutdown();
-	hotplug_shutdown();
-
 	upgrade_running = 1;
-
 	return 0;
 }
 

+ 23 - 74
ubus.c

@@ -21,97 +21,46 @@
 
 char *ubus_socket = NULL;
 static struct ubus_context *ctx;
-static struct uloop_process ubus_proc;
-static bool ubus_connected = false;
-static struct uloop_timeout retry;
-static int reconnect = 1;
+static struct uloop_timeout ubus_timer;
 
-static void procd_ubus_connection_lost(struct ubus_context *old_ctx);
-
-static void ubus_proc_cb(struct uloop_process *proc, int ret)
+static void
+ubus_reconnect_cb(struct uloop_timeout *timeout)
 {
-	/* nothing to do here */
+	if (!ubus_reconnect(ctx, ubus_socket))
+		ubus_add_uloop(ctx);
+	else
+		uloop_timeout_set(timeout, 2000);
 }
 
-static void procd_restart_ubus(void)
+static void
+ubus_disconnect_cb(struct ubus_context *ctx)
 {
-	char *argv[] = { "ubusd", NULL, ubus_socket, NULL };
-
-	if (ubus_proc.pending) {
-		ERROR("Killing existing ubus instance, pid=%d\n", (int) ubus_proc.pid);
-		kill(ubus_proc.pid, SIGKILL);
-		uloop_process_delete(&ubus_proc);
-	}
-
-	if (ubus_socket)
-		argv[1] = "-s";
-
-	ubus_proc.pid = fork();
-	if (!ubus_proc.pid) {
-		setpriority(PRIO_PROCESS, 0, -20);
-		execvp(argv[0], argv);
-		exit(-1);
-	}
-
-	if (ubus_proc.pid <= 0) {
-		ERROR("Failed to start new ubus instance\n");
-		return;
-	}
-
-	DEBUG(1, "Launched new ubus instance, pid=%d\n", (int) ubus_proc.pid);
-	uloop_process_add(&ubus_proc);
+	ubus_timer.cb = ubus_reconnect_cb;
+	uloop_timeout_set(&ubus_timer, 2000);
 }
 
-static void procd_ubus_try_connect(void)
+static void
+ubus_connect_cb(struct uloop_timeout *timeout)
 {
-	if (ctx) {
-		ubus_connected = !ubus_reconnect(ctx, ubus_socket);
-		return;
-	}
 	ctx = ubus_connect(ubus_socket);
+
 	if (!ctx) {
-		ubus_connected = false;
-		DEBUG(2, "Connection to ubus failed\n");
+		DEBUG(4, "Connection to ubus failed\n");
+		uloop_timeout_set(&ubus_timer, 1000);
 		return;
 	}
 
-	ctx->connection_lost = procd_ubus_connection_lost;
-	ubus_connected = true;
+	ctx->connection_lost = ubus_disconnect_cb;
 	ubus_init_service(ctx);
 	ubus_init_system(ctx);
-	if (getpid() == 1)
-		ubus_init_log(ctx);
-}
-
-static void
-procd_ubus_reconnect_timer(struct uloop_timeout *timeout)
-{
-	procd_ubus_try_connect();
-	if (ubus_connected) {
-		DEBUG(1, "Connected to ubus, id=%08x\n", ctx->local_id);
-		ubus_add_uloop(ctx);
-		return;
-	}
 
-	uloop_timeout_set(&retry, 1000);
-	procd_restart_ubus();
+	DEBUG(2, "Connected to ubus, id=%08x\n", ctx->local_id);
+	ubus_add_uloop(ctx);
 }
 
-static void procd_ubus_connection_lost(struct ubus_context *old_ctx)
+void
+procd_connect_ubus(void)
 {
-	retry.cb = procd_ubus_reconnect_timer;
-	procd_restart_ubus();
-	uloop_timeout_set(&retry, 1000);
+	ubus_timer.cb = ubus_connect_cb;
+	uloop_timeout_set(&ubus_timer, 1000);
 }
-
-void procd_connect_ubus(void)
-{
-	ubus_proc.cb = ubus_proc_cb;
-	procd_ubus_connection_lost(NULL);
-}
-
-void procd_reconnect_ubus(int _reconnect)
-{
-	reconnect = _reconnect;
-}
-

+ 0 - 0
askfirst.c → utils/askfirst.c


+ 0 - 0
md5.c → utils/md5.c


+ 0 - 0
md5.h → utils/md5.h


+ 0 - 0
utils.c → utils/utils.c


+ 0 - 0
utils.h → utils/utils.h


+ 0 - 1002
validate.c

@@ -1,1002 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <ctype.h>
-
-#include <arpa/inet.h>
-#include <netinet/ether.h>
-#include <sys/stat.h>
-
-#include "libvalidate.h"
-
-enum dt_optype {
-	OP_UNKNOWN,
-	OP_BOOL,
-	OP_NUMBER,
-	OP_STRING,
-	OP_FUNCTION
-};
-
-struct dt_fun;
-
-struct dt_op {
-	enum dt_optype type;
-	const char *next;
-	int length;
-	int nextop;
-	union {
-		bool boolean;
-		double number;
-		const char *string;
-		struct dt_fun *function;
-	} value;
-};
-
-struct dt_state {
-	int pos;
-	int depth;
-	const char *value;
-	struct dt_op stack[32];
-};
-
-struct dt_fun {
-	const char *name;
-	bool (*call)(struct dt_state *s, int nargs);
-};
-
-static bool
-dt_test_number(double number, const char *value)
-{
-	char *e;
-	double n;
-
-	n = strtod(value, &e);
-
-	return (e > value && *e == 0 && n == number);
-}
-
-static bool
-dt_test_string(const char *s, const char *end, const char *value)
-{
-	bool esc = false;
-
-	while (*value)
-	{
-		if (s > end)
-			return false;
-
-		if (!esc && *s == '\\')
-		{
-			s++;
-
-			if (s >= end)
-				break;
-
-			esc = true;
-			continue;
-		}
-
-		if (*s != *value)
-			return false;
-
-		esc = false;
-		value++;
-		s++;
-	}
-
-	return (*s == *value || (s > end && *value == 0));
-}
-
-static bool
-dt_step(struct dt_state *s);
-
-static bool
-dt_call(struct dt_state *s);
-
-static bool
-dt_type_or(struct dt_state *s, int nargs)
-{
-	while (nargs--)
-		if (dt_step(s))
-			return true;
-
-	return false;
-}
-
-static bool
-dt_type_and(struct dt_state *s, int nargs)
-{
-	while (nargs--)
-		if (!dt_step(s))
-			return false;
-
-	return true;
-}
-
-static bool
-dt_type_not(struct dt_state *s, int nargs)
-{
-	if (!nargs)
-		return false;
-
-	return !dt_step(s);
-}
-
-static bool
-dt_type_neg(struct dt_state *s, int nargs)
-{
-	bool rv;
-	const char *value = s->value;
-
-	if (!nargs)
-		return false;
-
-	if (*s->value == '!')
-		while (isspace(*++s->value));
-
-	rv = dt_step(s);
-	s->value = value;
-
-	return rv;
-}
-
-static bool
-dt_type_list(struct dt_state *s, int nargs)
-{
-	bool rv = true;
-	int pos = s->pos;
-	char *p, *str = strdup(s->value);
-	const char *value = s->value;
-
-	if (!str || !nargs)
-		return false;
-
-	for (p = strtok(str, " \t"); p; p = strtok(NULL, " \t"))
-	{
-		s->value = p;
-
-		if (!dt_step(s))
-		{
-			rv = false;
-			break;
-		}
-
-		s->pos = pos;
-	}
-
-	s->value = value;
-	free(str);
-
-	return rv;
-}
-
-static bool
-dt_type_min(struct dt_state *s, int nargs)
-{
-	int n;
-	char *e;
-
-	if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
-	{
-		n = strtol(s->value, &e, 0);
-
-		return (e > s->value && *e == 0 &&
-		        n >= s->stack[s->pos].value.number);
-	}
-
-	return false;
-}
-
-static bool
-dt_type_max(struct dt_state *s, int nargs)
-{
-	int n;
-	char *e;
-
-	if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
-	{
-		n = strtol(s->value, &e, 0);
-
-		return (e > s->value && *e == 0 &&
-		        n <= s->stack[s->pos].value.number);
-	}
-
-	return false;
-}
-
-static bool
-dt_type_range(struct dt_state *s, int nargs)
-{
-	int n;
-	char *e;
-
-	if (nargs >= 2 &&
-	    s->stack[s->pos].type == OP_NUMBER &&
-	    s->stack[s->pos + 1].type == OP_NUMBER)
-	{
-		n = strtol(s->value, &e, 0);
-
-		return (e > s->value && *e == 0 &&
-		        n >= s->stack[s->pos].value.number &&
-		        n <= s->stack[s->pos + 1].value.number);
-	}
-
-	return false;
-}
-
-static bool
-dt_type_minlen(struct dt_state *s, int nargs)
-{
-	if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
-		return (strlen(s->value) >= s->stack[s->pos].value.number);
-
-	return false;
-}
-
-static bool
-dt_type_maxlen(struct dt_state *s, int nargs)
-{
-	if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
-		return (strlen(s->value) <= s->stack[s->pos].value.number);
-
-	return false;
-}
-
-static bool
-dt_type_rangelen(struct dt_state *s, int nargs)
-{
-	if (nargs >= 2 &&
-	    s->stack[s->pos].type == OP_NUMBER &&
-	    s->stack[s->pos + 1].type == OP_NUMBER)
-		return (strlen(s->value) >= s->stack[s->pos].value.number &&
-				strlen(s->value) <= s->stack[s->pos + 1].value.number);
-
-	return false;
-}
-
-static bool
-dt_type_int(struct dt_state *s, int nargs)
-{
-	char *e;
-
-	strtol(s->value, &e, 0);
-
-	return (e > s->value && *e == 0);
-}
-
-static bool
-dt_type_uint(struct dt_state *s, int nargs)
-{
-	int n;
-	char *e;
-
-	n = strtol(s->value, &e, 0);
-
-	return (e > s->value && *e == 0 && n >= 0);
-}
-
-static bool
-dt_type_float(struct dt_state *s, int nargs)
-{
-	char *e;
-
-	strtod(s->value, &e);
-
-	return (e > s->value && *e == 0);
-}
-
-static bool
-dt_type_ufloat(struct dt_state *s, int nargs)
-{
-	int n;
-	char *e;
-
-	n = strtod(s->value, &e);
-
-	return (e > s->value && *e == 0 && n >= 0.0);
-}
-
-static bool
-dt_type_bool(struct dt_state *s, int nargs)
-{
-	int i;
-	const char *values[] = {
-		"0", "off", "false", "no",
-		"1", "on", "true", "yes"
-	};
-
-	for (i = 0; i < sizeof(values) / sizeof(values[0]); i++)
-		if (!strcasecmp(values[i], s->value))
-			return true;
-
-	return false;
-}
-
-static bool
-dt_type_string(struct dt_state *s, int nargs)
-{
-	return true;
-}
-
-static bool
-dt_type_ip4addr(struct dt_state *s, int nargs)
-{
-	struct in6_addr a;
-	return inet_pton(AF_INET, s->value, &a);
-}
-
-static bool
-dt_type_ip6addr(struct dt_state *s, int nargs)
-{
-	struct in6_addr a;
-	return inet_pton(AF_INET6, s->value, &a);
-}
-
-static bool
-dt_type_ipaddr(struct dt_state *s, int nargs)
-{
-	return (dt_type_ip4addr(s, 0) || dt_type_ip6addr(s, 0));
-}
-
-static bool
-dt_type_netmask4(struct dt_state *s, int nargs)
-{
-	int i;
-	struct in_addr a;
-
-	if (!inet_pton(AF_INET, s->value, &a))
-		return false;
-
-	if (a.s_addr == 0)
-		return true;
-
-	a.s_addr = ntohl(a.s_addr);
-
-	for (i = 0; (i < 32) && !(a.s_addr & (1 << i)); i++);
-
-	return ((uint32_t)(~((1 << i) - 1)) == a.s_addr);
-}
-
-static bool
-dt_type_netmask6(struct dt_state *s, int nargs)
-{
-	int i;
-	struct in6_addr a;
-
-	if (!inet_pton(AF_INET6, s->value, &a))
-		return false;
-
-	for (i = 0; (i < 16) && (a.s6_addr[i] == 0xFF); i++);
-
-	if (i == 16)
-		return true;
-
-	if ((a.s6_addr[i] != 255) && (a.s6_addr[i] != 254) &&
-		(a.s6_addr[i] != 252) && (a.s6_addr[i] != 248) &&
-		(a.s6_addr[i] != 240) && (a.s6_addr[i] != 224) &&
-		(a.s6_addr[i] != 192) && (a.s6_addr[i] != 128) &&
-		(a.s6_addr[i] != 0))
-		return false;
-
-	for (; (i < 16) && (a.s6_addr[i] == 0); i++);
-
-	return (i == 16);
-}
-
-static bool
-dt_type_cidr4(struct dt_state *s, int nargs)
-{
-	int n;
-	struct in_addr a;
-	char *p, buf[sizeof("255.255.255.255/32\0")];
-
-	if (strlen(s->value) >= sizeof(buf))
-		return false;
-
-	strcpy(buf, s->value);
-	p = strchr(buf, '/');
-
-	if (p)
-	{
-		*p++ = 0;
-
-		n = strtoul(p, &p, 10);
-
-		if ((*p != 0) || (n > 32))
-			return false;
-	}
-
-	return inet_pton(AF_INET, buf, &a);
-}
-
-static bool
-dt_type_cidr6(struct dt_state *s, int nargs)
-{
-	int n;
-	struct in6_addr a;
-	char *p, buf[sizeof("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255/128\0")];
-
-	if (strlen(s->value) >= sizeof(buf))
-		return false;
-
-	strcpy(buf, s->value);
-	p = strchr(buf, '/');
-
-	if (p)
-	{
-		*p++ = 0;
-
-		n = strtoul(p, &p, 10);
-
-		if ((*p != 0) || (n > 128))
-			return false;
-	}
-
-	return inet_pton(AF_INET6, buf, &a);
-}
-
-static bool
-dt_type_cidr(struct dt_state *s, int nargs)
-{
-	return (dt_type_cidr4(s, 0) || dt_type_cidr6(s, 0));
-}
-
-static bool
-dt_type_ipmask4(struct dt_state *s, int nargs)
-{
-	bool rv;
-	struct in_addr a;
-	const char *value;
-	char *p, buf[sizeof("255.255.255.255/255.255.255.255\0")];
-
-	if (strlen(s->value) >= sizeof(buf))
-		return false;
-
-	strcpy(buf, s->value);
-	p = strchr(buf, '/');
-
-	if (p)
-	{
-		*p++ = 0;
-
-		value = s->value;
-		s->value = p;
-		rv = dt_type_netmask4(s, 0);
-		s->value = value;
-
-		if (!rv)
-			return false;
-	}
-
-	return inet_pton(AF_INET, buf, &a);
-}
-
-static bool
-dt_type_ipmask6(struct dt_state *s, int nargs)
-{
-	bool rv;
-	struct in6_addr a;
-	const char *value;
-	char *p, buf[sizeof("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255/"
-	                    "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255\0")];
-
-	if (strlen(s->value) >= sizeof(buf))
-		return false;
-
-	strcpy(buf, s->value);
-	p = strchr(buf, '/');
-
-	if (p)
-	{
-		*p++ = 0;
-
-		value = s->value;
-		s->value = p;
-		rv = dt_type_netmask6(s, 0);
-		s->value = value;
-
-		if (!rv)
-			return false;
-	}
-
-	return inet_pton(AF_INET6, buf, &a);
-}
-
-static bool
-dt_type_ipmask(struct dt_state *s, int nargs)
-{
-	return (dt_type_ipmask4(s, 0) || dt_type_ipmask6(s, 0));
-}
-
-static bool
-dt_type_port(struct dt_state *s, int nargs)
-{
-	int n;
-	char *e;
-
-	n = strtoul(s->value, &e, 10);
-
-	return (e > s->value && *e == 0 && n <= 65535);
-}
-
-static bool
-dt_type_portrange(struct dt_state *s, int nargs)
-{
-	int n, m;
-	char *e;
-
-	n = strtoul(s->value, &e, 10);
-
-	if (e == s->value || *e != '-')
-		return false;
-
-	m = strtoul(e + 1, &e, 10);
-
-	return (*e == 0 && n <= 65535 && m <= 65535 && n <= m);
-}
-
-static bool
-dt_type_macaddr(struct dt_state *s, int nargs)
-{
-	return !!ether_aton(s->value);
-}
-
-static bool
-dt_type_uciname(struct dt_state *s, int nargs)
-{
-	const char *p;
-
-	for (p = s->value;
-	     *p && ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') ||
-	            (*p >= '0' && *p <= '9') || (*p == '_'));
-		 p++);
-
-	return (*p == 0);
-}
-
-static bool
-dt_type_wpakey(struct dt_state *s, int nargs)
-{
-	int len = strlen(s->value);
-	const char *p = s->value;
-
-	if (len == 64)
-	{
-		while (isxdigit(*p))
-			p++;
-
-		return (*p == 0);
-	}
-
-	return (len >= 8 && len <= 63);
-}
-
-static bool
-dt_type_wepkey(struct dt_state *s, int nargs)
-{
-	int len = strlen(s->value);
-	const char *p = s->value;
-
-	if (!strncmp(p, "s:", 2))
-	{
-		len -= 2;
-		p += 2;
-	}
-
-	if (len == 10 || len == 26)
-	{
-		while (isxdigit(*p))
-			p++;
-
-		return (*p == 0);
-	}
-
-	return (len == 5 || len == 13);
-}
-
-static bool
-dt_type_hostname(struct dt_state *s, int nargs)
-{
-	const char *p, *last;
-
-	for (p = last = s->value; *p; p++)
-	{
-		if (*p == '.')
-		{
-			if ((p - last) == 0 || (p - last) > 63)
-				return false;
-
-			last = p + 1;
-			continue;
-		}
-		else if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') ||
-		         (*p >= '0' && *p <= '9') || (*p == '_') || (*p == '-'))
-		{
-			continue;
-		}
-
-		return false;
-	}
-
-	return ((p - last) > 0 && (p - last) <= 255);
-}
-
-static bool
-dt_type_host(struct dt_state *s, int nargs)
-{
-	return (dt_type_hostname(s, 0) || dt_type_ipaddr(s, 0));
-}
-
-static bool
-dt_type_network(struct dt_state *s, int nargs)
-{
-	return (dt_type_uciname(s, 0) || dt_type_host(s, 0));
-}
-
-static bool
-dt_type_phonedigit(struct dt_state *s, int nargs)
-{
-	const char *p;
-
-	for (p = s->value;
-	     *p && ((*p >= '0' && *p <= '9') || (*p == '*') || (*p == '#') ||
-	            (*p == '!') || (*p == '.'));
-		 p++);
-
-	return (*p == 0);
-}
-
-static bool
-dt_type_directory(struct dt_state *s, int nargs)
-{
-	struct stat st;
-	return (!stat(s->value, &st) && S_ISDIR(st.st_mode));
-}
-
-
-static bool
-dt_type_device(struct dt_state *s, int nargs)
-{
-	struct stat st;
-	return (!stat(s->value, &st) &&
-	        (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)));
-}
-
-static bool
-dt_type_file(struct dt_state *s, int nargs)
-{
-	struct stat st;
-	return (!stat(s->value, &st) && S_ISREG(st.st_mode));
-}
-
-
-static struct dt_fun dt_types[] = {
-	{ "or",				dt_type_or			},
-	{ "and",			dt_type_and			},
-	{ "not",			dt_type_not			},
-	{ "neg",			dt_type_neg			},
-	{ "list",			dt_type_list		},
-	{ "min",			dt_type_min			},
-	{ "max",			dt_type_max			},
-	{ "range",			dt_type_range		},
-	{ "minlength",		dt_type_minlen		},
-	{ "maxlength",		dt_type_maxlen		},
-	{ "rangelength",	dt_type_rangelen	},
-	{ "integer",		dt_type_int			},
-	{ "uinteger",		dt_type_uint		},
-	{ "float",			dt_type_float		},
-	{ "ufloat",			dt_type_ufloat		},
-	{ "bool",			dt_type_bool		},
-	{ "string",			dt_type_string		},
-	{ "ip4addr",		dt_type_ip4addr		},
-	{ "ip6addr",		dt_type_ip6addr		},
-	{ "ipaddr",			dt_type_ipaddr		},
-	{ "cidr4",			dt_type_cidr4		},
-	{ "cidr6",			dt_type_cidr6		},
-	{ "cidr",			dt_type_cidr		},
-	{ "netmask4",		dt_type_netmask4	},
-	{ "netmask6",		dt_type_netmask6	},
-	{ "ipmask4",		dt_type_ipmask4		},
-	{ "ipmask6",		dt_type_ipmask6		},
-	{ "ipmask",			dt_type_ipmask		},
-	{ "port",			dt_type_port		},
-	{ "portrange",		dt_type_portrange	},
-	{ "macaddr",		dt_type_macaddr		},
-	{ "uciname",        dt_type_uciname		},
-	{ "wpakey",			dt_type_wpakey		},
-	{ "wepkey",			dt_type_wepkey		},
-	{ "hostname",		dt_type_hostname	},
-	{ "host",			dt_type_host		},
-	{ "network",		dt_type_network		},
-	{ "phonedigit",		dt_type_phonedigit	},
-	{ "directory",		dt_type_directory	},
-	{ "device",			dt_type_device		},
-	{ "file",			dt_type_file		},
-
-	{ }
-};
-
-static struct dt_fun *
-dt_lookup_function(const char *s, const char *e)
-{
-	struct dt_fun *fun = dt_types;
-
-	while (fun->name)
-	{
-		if (!strncmp(fun->name, s, e - s) && *(fun->name + (e - s)) == '\0')
-			return fun;
-
-		fun++;
-	}
-
-	return NULL;
-}
-
-static bool
-dt_parse_atom(struct dt_state *s, const char *label, const char *end)
-{
-	char q, *e;
-	const char *p;
-	bool esc;
-	double dval;
-	struct dt_fun *func;
-	struct dt_op *op = &s->stack[s->depth];
-
-	if ((s->depth + 1) >= (sizeof(s->stack) / sizeof(s->stack[0])))
-	{
-		printf("Syntax error, expression too long\n");
-		return false;
-	}
-
-	while (isspace(*label))
-		label++;
-
-	/* test whether label is a float */
-	dval = strtod(label, &e);
-
-	if (e > label)
-	{
-		op->next = e;
-		op->type = OP_NUMBER;
-		op->value.number = dval;
-		op->nextop = ++s->depth;
-
-		return true;
-	}
-	else if ((*label == '"') || (*label == '\''))
-	{
-		for (p = label + 1, q = *label, esc = false; p <= end; p++)
-		{
-			if (esc)
-			{
-				esc = false;
-				continue;
-			}
-			else if (*p == '\\')
-			{
-				esc = true;
-				continue;
-			}
-			else if (*p == q)
-			{
-				op->next = p + 1;
-				op->type = OP_STRING;
-				op->length = (p - label) - 2;
-				op->value.string = label + 1;
-				op->nextop = ++s->depth;
-
-				return true;
-			}
-		}
-
-		printf("Syntax error, unterminated string\n");
-		return false;
-	}
-	else if (*label)
-	{
-		for (p = label;
-		     p <= end && ((*p >= 'A' && *p <= 'Z') ||
-		                  (*p >= 'a' && *p <= 'z') ||
-		                  (*p >= '0' && *p <= '9') ||
-		                  (*p == '_'));
-		     p++);
-
-		func = dt_lookup_function(label, p);
-
-		if (!func)
-		{
-			printf("Syntax error, unrecognized function\n");
-			return false;
-		}
-
-		op->next = p;
-		op->type = OP_FUNCTION;
-		op->value.function = func;
-		op->nextop = ++s->depth;
-
-		return true;
-	}
-
-	printf("Syntax error, unexpected EOF\n");
-	return false;
-}
-
-static bool
-dt_parse_list(struct dt_state *s, const char *code, const char *end);
-
-static bool
-dt_parse_expr(const char *code, const char *end, struct dt_state *s)
-{
-	struct dt_op *tok;
-
-	if (!dt_parse_atom(s, code, end))
-		return false;
-
-	tok = &s->stack[s->depth - 1];
-
-	while (isspace(*tok->next))
-		tok->next++;
-
-	if (tok->type == OP_FUNCTION)
-	{
-		if (*tok->next == '(')
-		{
-			end--;
-
-			while (isspace(*end) && end > tok->next + 1)
-				end--;
-
-			return dt_parse_list(s, tok->next + 1, end);
-		}
-		else if (tok->next == end)
-		{
-			return dt_parse_list(s, tok->next, tok->next);
-		}
-
-		printf("Syntax error, expected '(' or EOF after function label\n");
-		return false;
-	}
-	else if (tok->next == end)
-	{
-		return true;
-	}
-
-	printf("Syntax error, expected ',' after literal\n");
-	return false;
-}
-
-static bool
-dt_parse_list(struct dt_state *s, const char *code, const char *end)
-{
-	char c;
-	bool esc;
-	int nest;
-	const char *p, *last;
-	struct dt_op *fptr;
-
-	if (!code)
-		return false;
-
-	fptr = &s->stack[s->depth - 1];
-
-	for (nest = 0, p = last = code, esc = false, c = *p;
-	     p <= end;
-	     p++, c = (p < end) ? *p : '\0')
-	{
-		if (esc)
-		{
-			esc = false;
-			continue;
-		}
-
-		switch (c)
-		{
-		case '\\':
-			esc = true;
-			break;
-
-		case '(':
-			nest++;
-			break;
-
-		case ')':
-			nest--;
-			break;
-
-		case ',':
-		case '\0':
-			if (nest <= 0)
-			{
-				if (p > last)
-				{
-					if (!dt_parse_expr(last, p, s))
-						return false;
-
-					fptr->length++;
-				}
-
-				last = p + 1;
-			}
-
-			break;
-		}
-	}
-
-	fptr->nextop = s->depth;
-	return true;
-}
-
-static bool
-dt_step(struct dt_state *s)
-{
-	bool rv;
-	struct dt_op *op = &s->stack[s->pos];
-
-	switch (op->type)
-	{
-	case OP_BOOL:
-		rv = op->value.boolean;
-		break;
-
-	case OP_NUMBER:
-		rv = dt_test_number(op->value.number, s->value);
-		break;
-
-	case OP_STRING:
-		rv = dt_test_string(op->value.string, op->value.string + op->length, s->value);
-		break;
-
-	case OP_FUNCTION:
-		rv = dt_call(s);
-		break;
-
-	default:
-		rv = false;
-		break;
-	}
-
-	s->pos = op->nextop;
-	return rv;
-}
-
-static bool
-dt_call(struct dt_state *s)
-{
-	bool rv;
-	struct dt_op *fptr = &s->stack[s->pos];
-	struct dt_fun *func = fptr->value.function;
-
-	s->pos++;
-
-	rv = func->call(s, fptr->length);
-
-	s->pos = fptr->nextop;
-
-	return rv;
-}
-
-bool
-dt_parse(const char *code, const char *value)
-{
-	struct dt_state s = {
-		.depth = 1,
-		.stack = {
-			{
-				.type = OP_FUNCTION,
-				.value.function = &dt_types[0],
-				.next = code
-			}
-		}
-	};
-
-	if (!value || !*value)
-		return false;
-
-	if (!dt_parse_list(&s, code, code + strlen(code)))
-		return false;
-
-	s.value = value;
-
-	return dt_call(&s);
-}

+ 0 - 28
validate_data.c

@@ -1,28 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <ctype.h>
-
-#include <arpa/inet.h>
-#include <netinet/ether.h>
-#include <sys/stat.h>
-
-#include "libvalidate.h"
-
-int main(int argc, char **argv)
-{
-	bool rv;
-
-	if (argc == 3) {
-		rv = dt_parse(argv[1], argv[2]);
-
-		printf("%s - %s = %s\n", argv[1], argv[2], rv ? "true" : "false");
-
-		return rv ? 0 : 1;
-	} else if (argc > 3) {
-
-	}
-
-	return 0;
-}

+ 5 - 5
watchdog.c

@@ -34,7 +34,7 @@ static int wdt_frequency = 5;
 
 static void watchdog_timeout_cb(struct uloop_timeout *t)
 {
-	DEBUG(2, "Ping\n");
+	DEBUG(4, "Ping\n");
 	if (write(wdt_fd, "X", 1) < 0)
 		ERROR("WDT failed to write: %s\n", strerror(errno));
 	uloop_timeout_set(t, wdt_frequency * 1000);
@@ -59,7 +59,7 @@ int watchdog_timeout(int timeout)
 		return 0;
 
 	if (timeout) {
-		DEBUG(2, "Set watchdog timeout: %ds\n", timeout);
+		DEBUG(4, "Set watchdog timeout: %ds\n", timeout);
 		ioctl(wdt_fd, WDIOC_SETTIMEOUT, &timeout);
 	}
 	ioctl(wdt_fd, WDIOC_GETTIMEOUT, &timeout);
@@ -73,7 +73,7 @@ int watchdog_frequency(int frequency)
 		return 0;
 
 	if (frequency) {
-		DEBUG(2, "Set watchdog frequency: %ds\n", frequency);
+		DEBUG(4, "Set watchdog frequency: %ds\n", frequency);
 		wdt_frequency = frequency;
 	}
 
@@ -100,7 +100,7 @@ void watchdog_init(int preinit)
 
 	wdt_timeout.cb = watchdog_timeout_cb;
 	if (env) {
-		DEBUG(1, "Watchdog handover: fd=%s\n", env);
+		DEBUG(2, "Watchdog handover: fd=%s\n", env);
 		wdt_fd = atoi(env);
 		unsetenv("WDTFD");
 	} else {
@@ -117,5 +117,5 @@ void watchdog_init(int preinit)
 	watchdog_timeout(30);
 	watchdog_timeout_cb(&wdt_timeout);
 
-	DEBUG(2, "Opened watchdog with timeout %ds\n", watchdog_timeout(0));
+	DEBUG(4, "Opened watchdog with timeout %ds\n", watchdog_timeout(0));
 }