X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=handler.c;h=78fc9a01efca416f63d9d95af8ab8b6d5ddc9952;hb=HEAD;hp=0c4627f1ca549429c63a3e3809a47d5bf4429b7e;hpb=cf9033dd5ac75cb3c8c2fd55011f3ec5cd4c2371;p=project%2Fnetifd.git diff --git a/handler.c b/handler.c index 0c4627f..78fc9a0 100644 --- a/handler.c +++ b/handler.c @@ -34,6 +34,9 @@ netifd_dir_push(int fd) static void netifd_dir_pop(int prev_fd) { + if (prev_fd < 0) + return; + if (fchdir(prev_fd)) {} close(prev_fd); } @@ -75,6 +78,65 @@ netifd_init_script_handler(const char *script, json_object *obj, script_dump_cb cb(script, name, obj); } +static void +netifd_init_extdev_handler(const char *config_file, json_object *obj, + create_extdev_handler_cb cb) +{ + json_object *tmp, *cfg, *info, *stats; + const char *name, *ubus_name, *br_prefix = NULL; + bool bridge_support = true; + char *err_missing; + + if (!json_check_type(obj, json_type_object)) + return; + + tmp = json_get_field(obj, "name", json_type_string); + if (!tmp) { + err_missing = "name"; + goto field_missing; + } + + name = json_object_get_string(tmp); + + tmp = json_get_field(obj, "ubus_name", json_type_string); + if (!tmp) { + err_missing = "ubus_name"; + goto field_missing; + } + + ubus_name = json_object_get_string(tmp); + + tmp = json_get_field(obj, "bridge", json_type_string); + if (!tmp || !strcmp(json_object_get_string(tmp), "0")) + bridge_support = false; + + if (bridge_support) { + tmp = json_get_field(obj, "br-prefix", json_type_string); + if (!tmp) + br_prefix = name; + else + br_prefix = json_object_get_string(tmp); + } + + tmp = json_get_field(obj, "config", json_type_array); + if (!tmp) { + err_missing = "config"; + goto field_missing; + } + + cfg = tmp; + + info = json_get_field(obj, "info", json_type_array); + stats = json_get_field(obj, "stats", json_type_array); + + cb(config_file, name, ubus_name, bridge_support, br_prefix, cfg, info, stats); + return; + +field_missing: + netifd_log_message(L_WARNING, "external device handler description '%s' is" + "missing field '%s'\n", config_file, err_missing); +} + static void netifd_parse_script_handler(const char *name, script_dump_cb cb) { @@ -105,7 +167,7 @@ netifd_parse_script_handler(const char *name, script_dump_cb cb) tok = json_tokener_new(); obj = json_tokener_parse_ex(tok, start, len); - if (!is_error(obj)) { + if (obj) { netifd_init_script_handler(name, obj, cb); json_object_put(obj); json_tokener_free(tok); @@ -122,14 +184,59 @@ netifd_parse_script_handler(const char *name, script_dump_cb cb) pclose(f); } +static void +netifd_parse_extdev_handler(const char *path_to_file, create_extdev_handler_cb cb) +{ + struct json_tokener *tok = NULL; + json_object *obj; + FILE *file; + int len; + char buf[512], *start; + + file = fopen(path_to_file, "r"); + if (!file) + return; + + do { + start = fgets(buf, sizeof(buf), file); + if (!start) + continue; + + len = strlen(start); + + if (!tok) + tok = json_tokener_new(); + + obj = json_tokener_parse_ex(tok, start, len); + + if (obj) { + netifd_init_extdev_handler(path_to_file, obj, cb); + json_object_put(obj); + json_tokener_free(tok); + tok = NULL; + } else if (start[len - 1] == '\n') { + json_tokener_free(tok); + tok = NULL; + } + } while (!feof(file) && !ferror(file)); + + if (tok) + json_tokener_free(tok); + + fclose(file); +} + void netifd_init_script_handlers(int dir_fd, script_dump_cb cb) { glob_t g; - int i, prev_fd; + int prev_fd; + size_t i; prev_fd = netifd_dir_push(dir_fd); - if (glob("./*.sh", 0, NULL, &g)) + if (glob("./*.sh", 0, NULL, &g)) { + netifd_dir_pop(prev_fd); return; + } for (i = 0; i < g.gl_pathc; i++) netifd_parse_script_handler(g.gl_pathv[i], cb); @@ -138,6 +245,19 @@ void netifd_init_script_handlers(int dir_fd, script_dump_cb cb) globfree(&g); } +void +netifd_init_extdev_handlers(int dir_fd, create_extdev_handler_cb cb) +{ + glob_t g; + int prev_fd; + + prev_fd = netifd_dir_push(dir_fd); + glob("*.json", 0, NULL, &g); + for (size_t i = 0; i < g.gl_pathc; i++) + netifd_parse_extdev_handler(g.gl_pathv[i], cb); + netifd_dir_pop(prev_fd); +} + char * netifd_handler_parse_config(struct uci_blob_param_list *config, json_object *obj) {