+static void
+proto_shell_add_handler(const char *script, const char *name, json_object *obj)
+{
+ struct proto_shell_handler *handler;
+ struct proto_handler *proto;
+ json_object *config, *tmp;
+ char *proto_name, *script_name;
+
+ handler = calloc_a(sizeof(*handler),
+ &proto_name, strlen(name) + 1,
+ &script_name, strlen(script) + 1);
+ if (!handler)
+ return;
+
+ handler->script_name = strcpy(script_name, script);
+
+ proto = &handler->proto;
+ proto->name = strcpy(proto_name, name);
+ proto->config_params = &handler->config;
+ proto->attach = proto_shell_attach;
+
+ tmp = json_get_field(obj, "no-device", json_type_boolean);
+ if (tmp && json_object_get_boolean(tmp))
+ handler->proto.flags |= PROTO_FLAG_NODEV;
+
+ tmp = json_get_field(obj, "no-proto-task", json_type_boolean);
+ handler->no_proto_task = tmp && json_object_get_boolean(tmp);
+
+ tmp = json_get_field(obj, "available", json_type_boolean);
+ if (tmp && json_object_get_boolean(tmp))
+ handler->proto.flags |= PROTO_FLAG_INIT_AVAILABLE;
+
+ tmp = json_get_field(obj, "renew-handler", json_type_boolean);
+ if (tmp && json_object_get_boolean(tmp))
+ handler->proto.flags |= PROTO_FLAG_RENEW_AVAILABLE;
+
+ tmp = json_get_field(obj, "lasterror", json_type_boolean);
+ if (tmp && json_object_get_boolean(tmp))
+ handler->proto.flags |= PROTO_FLAG_LASTERROR;
+
+ config = json_get_field(obj, "config", json_type_array);
+ if (config)
+ handler->config_buf = netifd_handler_parse_config(&handler->config, config);
+
+ DPRINTF("Add handler for script %s: %s\n", script, proto->name);
+ add_proto_handler(proto);
+}
+
+void proto_shell_init(void)
+{
+ proto_fd = netifd_open_subdir("proto");
+ if (proto_fd < 0)
+ return;