|
@@ -17,15 +17,20 @@
|
|
|
#include "watchdog.h"
|
|
|
#include "sysupgrade.h"
|
|
|
|
|
|
+#include <ctype.h>
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <unistd.h>
|
|
|
|
|
|
+#include <libubox/blobmsg.h>
|
|
|
|
|
|
-void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command)
|
|
|
+void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command,
|
|
|
+ struct blob_attr *options)
|
|
|
{
|
|
|
char *wdt_fd = watchdog_fd();
|
|
|
char *argv[] = { "/sbin/upgraded", NULL, NULL, NULL};
|
|
|
+ struct blob_attr *option;
|
|
|
+ int rem;
|
|
|
int ret;
|
|
|
|
|
|
ret = chroot(prefix);
|
|
@@ -41,6 +46,55 @@ void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command)
|
|
|
watchdog_set_cloexec(false);
|
|
|
setenv("WDTFD", wdt_fd, 1);
|
|
|
}
|
|
|
+
|
|
|
+ blobmsg_for_each_attr(option, options, rem) {
|
|
|
+ const char *prefix = "UPGRADE_OPT_";
|
|
|
+ char value[11];
|
|
|
+ char *name;
|
|
|
+ char *c;
|
|
|
+ int tmp;
|
|
|
+
|
|
|
+ if (asprintf(&name, "%s%s", prefix, blobmsg_name(option)) <= 0)
|
|
|
+ continue;
|
|
|
+ for (c = name + strlen(prefix); *c; c++) {
|
|
|
+ if (isalnum(*c) || *c == '_') {
|
|
|
+ *c = toupper(*c);
|
|
|
+ } else {
|
|
|
+ c = NULL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!c) {
|
|
|
+ fprintf(stderr, "Option \"%s\" contains invalid characters\n",
|
|
|
+ blobmsg_name(option));
|
|
|
+ free(name);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (blobmsg_type(option)) {
|
|
|
+ case BLOBMSG_TYPE_INT32:
|
|
|
+ tmp = blobmsg_get_u32(option);
|
|
|
+ break;
|
|
|
+ case BLOBMSG_TYPE_INT16:
|
|
|
+ tmp = blobmsg_get_u16(option);
|
|
|
+ break;
|
|
|
+ case BLOBMSG_TYPE_INT8:
|
|
|
+ tmp = blobmsg_get_u8(option);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ fprintf(stderr, "Option \"%s\" has unsupported type: %d\n",
|
|
|
+ blobmsg_name(option), blobmsg_type(option));
|
|
|
+ free(name);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ snprintf(value, sizeof(value), "%u", tmp);
|
|
|
+
|
|
|
+ setenv(name, value, 1);
|
|
|
+
|
|
|
+ free(name);
|
|
|
+ }
|
|
|
+
|
|
|
execvp(argv[0], argv);
|
|
|
|
|
|
/* Cleanup on failure */
|