X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fprocd.git;a=blobdiff_plain;f=system.c;h=569a75d5b4df947c0166afe4b14855073a968188;hp=0b3c46629c567f2118fddcffae550bae91d0acb1;hb=3c771f9e4ba46d3e39334cb20eab98221043f1e2;hpb=03aab02afbfe00f4ee767d3fbc234ea348a34179 diff --git a/system.c b/system.c index 0b3c466..569a75d 100644 --- a/system.c +++ b/system.c @@ -13,21 +13,27 @@ */ #include +#ifdef linux #include +#endif #include #include #include #include #include #include +#include #include #include "procd.h" #include "watchdog.h" -#include "hotplug.h" static struct blob_buf b; +static int notify; +static struct ubus_context *_ctx; + +int upgrade_running = 0; static int system_board(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, @@ -35,7 +41,7 @@ static int system_board(struct ubus_context *ctx, struct ubus_object *obj, { void *c; char line[256]; - char *key, *val; + char *key, *val, *next; struct utsname utsname; FILE *f; @@ -61,15 +67,21 @@ static int system_board(struct ubus_context *ctx, struct ubus_object *obj, !strcasecmp(key, "processor") || !strcasecmp(key, "model name")) { - blobmsg_add_string(&b, "system", val + 2); - break; + strtoul(val + 2, &key, 0); + + if (key == (val + 2) || *key != 0) + { + blobmsg_add_string(&b, "system", val + 2); + break; + } } } fclose(f); } - if ((f = fopen("/tmp/sysinfo/model", "r")) != NULL) + if ((f = fopen("/tmp/sysinfo/model", "r")) != NULL || + (f = fopen("/proc/device-tree/model", "r")) != NULL) { if (fgets(line, sizeof(line), f)) { @@ -108,24 +120,58 @@ static int system_board(struct ubus_context *ctx, struct ubus_object *obj, while (fgets(line, sizeof(line), f)) { - key = strtok(line, "=\""); - val = strtok(NULL, "\"\n"); + char *dest; + char ch; - if (!key || !val) + key = line; + val = strchr(line, '='); + if (!val) continue; + *(val++) = 0; + if (!strcasecmp(key, "DISTRIB_ID")) - blobmsg_add_string(&b, "distribution", val); + key = "distribution"; else if (!strcasecmp(key, "DISTRIB_RELEASE")) - blobmsg_add_string(&b, "version", val); + key = "version"; else if (!strcasecmp(key, "DISTRIB_REVISION")) - blobmsg_add_string(&b, "revision", val); + key = "revision"; else if (!strcasecmp(key, "DISTRIB_CODENAME")) - blobmsg_add_string(&b, "codename", val); + key = "codename"; else if (!strcasecmp(key, "DISTRIB_TARGET")) - blobmsg_add_string(&b, "target", val); + key = "target"; else if (!strcasecmp(key, "DISTRIB_DESCRIPTION")) - blobmsg_add_string(&b, "description", val); + key = "description"; + else + continue; + + dest = blobmsg_alloc_string_buffer(&b, key, strlen(val)); + if (!dest) { + ERROR("Failed to allocate blob.\n"); + continue; + } + + while (val && (ch = *(val++)) != 0) { + switch (ch) { + case '\'': + case '"': + next = strchr(val, ch); + if (next) + *next = 0; + + strcpy(dest, val); + + if (next) + val = next + 1; + + dest += strlen(dest); + break; + case '\\': + *(dest++) = *(val++); + break; + } + } + blobmsg_add_string_buffer(&b); } blobmsg_close_array(&b, c); @@ -142,23 +188,27 @@ static int system_info(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { - void *c; time_t now; struct tm *tm; +#ifdef linux struct sysinfo info; + void *c; + + if (sysinfo(&info)) + return UBUS_STATUS_UNKNOWN_ERROR; +#endif now = time(NULL); if (!(tm = localtime(&now))) return UBUS_STATUS_UNKNOWN_ERROR; - if (sysinfo(&info)) - return UBUS_STATUS_UNKNOWN_ERROR; - blob_buf_init(&b, 0); + blobmsg_add_u32(&b, "localtime", now + tm->tm_gmtoff); + +#ifdef linux blobmsg_add_u32(&b, "uptime", info.uptime); - blobmsg_add_u32(&b, "localtime", mktime(tm)); c = blobmsg_open_array(&b, "load"); blobmsg_add_u32(&b, NULL, info.loads[0]); @@ -167,16 +217,17 @@ static int system_info(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_close_array(&b, c); c = blobmsg_open_table(&b, "memory"); - blobmsg_add_u32(&b, "total", info.mem_unit * info.totalram); - blobmsg_add_u32(&b, "free", info.mem_unit * info.freeram); - blobmsg_add_u32(&b, "shared", info.mem_unit * info.sharedram); - blobmsg_add_u32(&b, "buffered", info.mem_unit * info.bufferram); + blobmsg_add_u64(&b, "total", info.mem_unit * info.totalram); + blobmsg_add_u64(&b, "free", info.mem_unit * info.freeram); + blobmsg_add_u64(&b, "shared", info.mem_unit * info.sharedram); + blobmsg_add_u64(&b, "buffered", info.mem_unit * info.bufferram); blobmsg_close_table(&b, c); c = blobmsg_open_table(&b, "swap"); - blobmsg_add_u32(&b, "total", info.mem_unit * info.totalswap); - blobmsg_add_u32(&b, "free", info.mem_unit * info.freeswap); + blobmsg_add_u64(&b, "total", info.mem_unit * info.totalswap); + blobmsg_add_u64(&b, "free", info.mem_unit * info.freeswap); blobmsg_close_table(&b, c); +#endif ubus_send_reply(ctx, req, b.head); @@ -187,10 +238,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; } @@ -241,7 +289,7 @@ static int watchdog_set(struct ubus_context *ctx, struct ubus_object *obj, if (tb[WDT_STOP]) watchdog_set_stopped(blobmsg_get_bool(tb[WDT_STOP])); - if (watchdog_fd() < 0) + if (watchdog_fd() == NULL) status = "offline"; else if (watchdog_get_stopped()) status = "stopped"; @@ -263,7 +311,7 @@ enum { __SIGNAL_MAX }; -static const struct blobmsg_policy signal_policy[__WDT_MAX] = { +static const struct blobmsg_policy signal_policy[__SIGNAL_MAX] = { [SIGNAL_PID] = { .name = "pid", .type = BLOBMSG_TYPE_INT32 }, [SIGNAL_NUM] = { .name = "signum", .type = BLOBMSG_TYPE_INT32 }, }; @@ -286,12 +334,65 @@ static int proc_signal(struct ubus_context *ctx, struct ubus_object *obj, return 0; } +enum { + NAND_PATH, + __NAND_MAX +}; + +static const struct blobmsg_policy nand_policy[__NAND_MAX] = { + [NAND_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, +}; + +static void +procd_spawn_upgraded(char *path) +{ + char *wdt_fd = watchdog_fd(); + char *argv[] = { "/tmp/upgraded", NULL, NULL}; + + argv[1] = path; + + DEBUG(2, "Exec to upgraded now\n"); + if (wdt_fd) { + watchdog_no_cloexec(); + setenv("WDTFD", wdt_fd, 1); + } + execvp(argv[0], argv); +} + +static int nand_set(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__NAND_MAX]; + + if (!msg) + return UBUS_STATUS_INVALID_ARGUMENT; + + blobmsg_parse(nand_policy, __NAND_MAX, tb, blob_data(msg), blob_len(msg)); + if (!tb[NAND_PATH]) + return UBUS_STATUS_INVALID_ARGUMENT; + + procd_spawn_upgraded(blobmsg_get_string(tb[NAND_PATH])); + fprintf(stderr, "Yikees, something went wrong. no /sbin/upgraded ?\n"); + return 0; +} + +static void +procd_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj) +{ + notify = obj->has_subscribers; +} + + static const struct ubus_method system_methods[] = { UBUS_METHOD_NOARG("board", system_board), UBUS_METHOD_NOARG("info", system_info), UBUS_METHOD_NOARG("upgrade", system_upgrade), UBUS_METHOD("watchdog", watchdog_set, watchdog_policy), UBUS_METHOD("signal", proc_signal, signal_policy), + + /* must remain at the end as it ia not always loaded */ + UBUS_METHOD("nandupgrade", nand_set, nand_policy), }; static struct ubus_object_type system_object_type = @@ -302,12 +403,31 @@ static struct ubus_object system_object = { .type = &system_object_type, .methods = system_methods, .n_methods = ARRAY_SIZE(system_methods), + .subscribe_cb = procd_subscribe_cb, }; +void +procd_bcast_event(char *event, struct blob_attr *msg) +{ + int ret; + + if (!notify) + return; + + ret = ubus_notify(_ctx, &system_object, event, msg, -1); + if (ret) + fprintf(stderr, "Failed to notify log: %s\n", ubus_strerror(ret)); +} + void ubus_init_system(struct ubus_context *ctx) { + struct stat s; int ret; + if (stat("/sbin/upgraded", &s)) + system_object.n_methods -= 1; + + _ctx = ctx; ret = ubus_add_object(ctx, &system_object); if (ret) ERROR("Failed to add object: %s\n", ubus_strerror(ret));