ucode: pass-through `ubus_rpc_session` argument
[project/rpcd.git] / main.c
diff --git a/main.c b/main.c
index 9bebd3e4fe18768b543a2bbf291c959ff4a96576..d77a814cdbf611f2c5fbdc55b00f1c89e100bd88 100644 (file)
--- a/main.c
+++ b/main.c
@@ -2,7 +2,7 @@
  * rpcd - UBUS RPC server
  *
  *   Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- *   Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
+ *   Copyright (C) 2013-2014 Jo-Philipp Wich <jow@openwrt.org>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  */
 
 #include <unistd.h>
+#include <stdlib.h>
 
 #include <libubox/blobmsg_json.h>
 #include <libubus.h>
 #include <signal.h>
+#include <sys/stat.h>
 
+#include <rpcd/exec.h>
+#include <rpcd/plugin.h>
+#include <rpcd/rc.h>
 #include <rpcd/session.h>
 #include <rpcd/uci.h>
-#include <rpcd/plugin.h>
-#include <rpcd/exec.h>
 
 static struct ubus_context *ctx;
 static bool respawn = false;
 
+int rpc_exec_timeout = RPC_EXEC_DEFAULT_TIMEOUT;
+
 static void
 handle_signal(int sig)
 {
@@ -43,33 +48,56 @@ static void
 exec_self(int argc, char **argv)
 {
        int i;
-       const char *cmd = rpc_exec_lookup(argv[0]);
-       char **args = calloc(argc + 1, sizeof(char *));
+       const char *cmd;
+       char **args;
+
+       cmd = rpc_exec_lookup(argv[0]);
+       if (!cmd)
+               return;
 
-       if (!cmd || !args)
+       args = calloc(argc + 1, sizeof(char *));
+       if (!args)
                return;
 
        for (i = 0; i < argc; i++)
                args[i] = argv[i];
 
+       setenv("RPC_HANGUP", "1", 1);
        execv(cmd, (char * const *)args);
 }
 
 int main(int argc, char **argv)
 {
+       struct stat s;
+       const char *hangup;
        const char *ubus_socket = NULL;
        int ch;
 
-       while ((ch = getopt(argc, argv, "s:")) != -1) {
+       while ((ch = getopt(argc, argv, "s:t:")) != -1) {
                switch (ch) {
                case 's':
                        ubus_socket = optarg;
                        break;
+
+               case 't':
+                       rpc_exec_timeout = 1000 * strtol(optarg, NULL, 0);
+                       break;
+
                default:
                        break;
                }
        }
 
+       if (rpc_exec_timeout < 1000 || rpc_exec_timeout > 600000) {
+               fprintf(stderr, "Invalid execution timeout specified\n");
+               return -1;
+       }
+
+       if (stat(RPC_UCI_DIR_PREFIX, &s))
+               mkdir(RPC_UCI_DIR_PREFIX, 0700);
+
+       umask(0077);
+
        signal(SIGPIPE, SIG_IGN);
        signal(SIGHUP,  handle_signal);
        signal(SIGUSR1, handle_signal);
@@ -86,9 +114,15 @@ int main(int argc, char **argv)
 
        rpc_session_api_init(ctx);
        rpc_uci_api_init(ctx);
+       rpc_rc_api_init(ctx);
        rpc_plugin_api_init(ctx);
 
-       rpc_session_thaw();
+       hangup = getenv("RPC_HANGUP");
+
+       if (!hangup || strcmp(hangup, "1"))
+               rpc_uci_purge_savedirs();
+       else
+               rpc_session_thaw();
 
        uloop_run();
        ubus_free(ctx);