summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--CMakeLists.txt32
-rw-r--r--debug.c45
-rw-r--r--initd/early.c (renamed from early.c)19
-rw-r--r--initd/init.c115
-rw-r--r--initd/init.h23
-rw-r--r--initd/mkdev.c (renamed from mkdev.c)6
-rw-r--r--initd/preinit.c98
-rw-r--r--inittab.c10
-rw-r--r--libvalidate.h6
-rw-r--r--log.c135
-rw-r--r--log.h (renamed from syslog.h)41
-rw-r--r--logread.c369
-rw-r--r--measure.c99
-rw-r--r--plug/coldplug.c (renamed from coldplug.c)9
-rw-r--r--plug/hotplug.c (renamed from hotplug.c)36
-rw-r--r--plug/hotplug.h (renamed from hotplug.h)1
-rw-r--r--plug/udevtrigger.c (renamed from udevtrigger.c)0
-rw-r--r--preinit.c68
-rw-r--r--procd.c (renamed from main.c)31
-rw-r--r--procd.h33
-rw-r--r--rcS.c10
-rw-r--r--service/instance.c (renamed from instance.c)25
-rw-r--r--service/instance.h (renamed from instance.h)2
-rw-r--r--service/service.c (renamed from service.c)45
-rw-r--r--service/service.h (renamed from service.h)1
-rw-r--r--service/trigger.c (renamed from trigger.c)6
-rw-r--r--service/validate.c (renamed from service_validate.c)3
-rw-r--r--signal.c13
-rw-r--r--state.c15
-rw-r--r--syslog.c320
-rw-r--r--system.c6
-rw-r--r--ubus.c97
-rw-r--r--utils/askfirst.c (renamed from askfirst.c)0
-rw-r--r--utils/md5.c (renamed from md5.c)0
-rw-r--r--utils/md5.h (renamed from md5.h)0
-rw-r--r--utils/utils.c (renamed from utils.c)0
-rw-r--r--utils/utils.h (renamed from utils.h)0
-rw-r--r--validate.c1002
-rw-r--r--validate_data.c28
-rw-r--r--watchdog.c10
41 files changed, 420 insertions, 2344 deletions
diff --git a/.gitignore b/.gitignore
index 7d82eca..4bd7b28 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,10 @@
procd
-validate_data
-logread
askfirst
udevtrigger
+init
.*
-*.so
Makefile
CMakeCache.txt
CMakeFiles
*.cmake
install_manifest.txt
-
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a521ea7..d353801 100644
--- a/CMakeLists.txt
+++ b/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
)
diff --git a/debug.c b/debug.c
deleted file mode 100644
index fbf1e4f..0000000
--- a/debug.c
+++ /dev/null
@@ -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);
-}
diff --git a/early.c b/initd/early.c
index 7da1e4b..77ced77 100644
--- a/early.c
+++ b/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;
diff --git a/initd/init.c b/initd/init.c
new file mode 100644
index 0000000..d458f29
--- /dev/null
+++ b/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;
+}
diff --git a/initd/init.h b/initd/init.h
new file mode 100644
index 0000000..1321cf8
--- /dev/null
+++ b/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
diff --git a/mkdev.c b/initd/mkdev.c
index 0f55554..3471461 100644
--- a/mkdev.c
+++ b/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);
diff --git a/initd/preinit.c b/initd/preinit.c
new file mode 100644
index 0000000..eeadbeb
--- /dev/null
+++ b/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);
+}
diff --git a/inittab.c b/inittab.c
index d73e0b8..e935ece 100644
--- a/inittab.c
+++ b/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';
diff --git a/libvalidate.h b/libvalidate.h
deleted file mode 100644
index d3b8e05..0000000
--- a/libvalidate.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _VALIDATE_H__
-#define _VALIDATE_H__
-
-bool dt_parse(const char *code, const char *value);
-
-#endif
diff --git a/log.c b/log.c
deleted file mode 100644
index d367388..0000000
--- a/log.c
+++ /dev/null
@@ -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));
-}
diff --git a/syslog.h b/log.h
index fd78363..968c136 100644
--- a/syslog.h
+++ b/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
diff --git a/logread.c b/logread.c
deleted file mode 100644
index e8749f8..0000000
--- a/logread.c
+++ /dev/null
@@ -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;
-}
diff --git a/measure.c b/measure.c
deleted file mode 100644
index 9e21a66..0000000
--- a/measure.c
+++ /dev/null
@@ -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;
-}
diff --git a/coldplug.c b/plug/coldplug.c
index 71b09f0..466b759 100644
--- a/coldplug.c
+++ b/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);
}
diff --git a/hotplug.c b/plug/hotplug.c
index 422e849..ca1e823 100644
--- a/hotplug.c
+++ b/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);
diff --git a/hotplug.h b/plug/hotplug.h
index e33afcb..2a44442 100644
--- a/hotplug.h
+++ b/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);
diff --git a/udevtrigger.c b/plug/udevtrigger.c
index 5013189..5013189 100644
--- a/udevtrigger.c
+++ b/plug/udevtrigger.c
diff --git a/preinit.c b/preinit.c
deleted file mode 100644
index c015ebd..0000000
--- a/preinit.c
+++ /dev/null
@@ -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);
-}
diff --git a/main.c b/procd.c
index 49d85f4..a72912a 100644
--- a/main.c
+++ b/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;
diff --git a/procd.h b/procd.h
index a0c7a99..dff86f8 100644
--- a/procd.h
+++ b/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
diff --git a/rcS.c b/rcS.c
index f041f09..ae8f08e 100644
--- a/rcS.c
+++ b/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;
}
diff --git a/instance.c b/service/instance.c
index 05b0f99..5ac7d57 100644
--- a/instance.c
+++ b/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);
}
diff --git a/instance.h b/service/instance.h
index 6e69086..65b670e 100644
--- a/instance.h
+++ b/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)
diff --git a/service.c b/service/service.c
index c5f5bf3..aa393b9 100644
--- a/service.c
+++ b/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);
diff --git a/service.h b/service/service.h
index 6448e5e..46ba746 100644
--- a/service.h
+++ b/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);
diff --git a/trigger.c b/service/trigger.c
index d14101e..41fb55d 100644
--- a/trigger.c
+++ b/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);
diff --git a/service_validate.c b/service/validate.c
index 3522cde..ca9bb39 100644
--- a/service_validate.c
+++ b/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 {
diff --git a/signal.c b/signal.c
index ebaf7bc..74cabcb 100644
--- a/signal.c
+++ b/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);
-}
diff --git a/state.c b/state.c
index f83032c..9f3033b 100644
--- a/state.c
+++ b/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();
diff --git a/syslog.c b/syslog.c
deleted file mode 100644
index 7a2839e..0000000
--- a/syslog.c
+++ /dev/null
@@ -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);
-}
diff --git a/system.c b/system.c
index 54a84b4..be02621 100644
--- a/system.c
+++ b/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;
}
diff --git a/ubus.c b/ubus.c
index 54ead33..6166254 100644
--- a/ubus.c
+++ b/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;
-}
-
diff --git a/askfirst.c b/utils/askfirst.c
index 6ad77aa..6ad77aa 100644
--- a/askfirst.c
+++ b/utils/askfirst.c
diff --git a/md5.c b/utils/md5.c
index ec24dd2..ec24dd2 100644
--- a/md5.c
+++ b/utils/md5.c
diff --git a/md5.h b/utils/md5.h
index e1731ef..e1731ef 100644
--- a/md5.h
+++ b/utils/md5.h
diff --git a/utils.c b/utils/utils.c
index 59d02f1..59d02f1 100644
--- a/utils.c
+++ b/utils/utils.c
diff --git a/utils.h b/utils/utils.h
index 37fa216..37fa216 100644
--- a/utils.h
+++ b/utils/utils.h
diff --git a/validate.c b/validate.c
deleted file mode 100644
index f94a071..0000000
--- a/validate.c
+++ /dev/null
@@ -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);
-}
diff --git a/validate_data.c b/validate_data.c
deleted file mode 100644
index dc5e96b..0000000
--- a/validate_data.c
+++ /dev/null
@@ -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;
-}
diff --git a/watchdog.c b/watchdog.c
index d927c53..de9556c 100644
--- a/watchdog.c
+++ b/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));
}