luci2: initialize package pointers to NULL
[project/luci2/ui.git] / luci2 / src / rpcd / luci2.c
index 121219da143d199e2bf248e8f04dff5f5cb6433e..7c37144b595340ee8edc3da0cf8398cfbd2fd539 100644 (file)
@@ -217,7 +217,7 @@ rpc_luci2_system_log(struct ubus_context *ctx, struct ubus_object *obj,
        int logsize = 0;
        const char *logfile = NULL;
        struct stat st;
-       struct uci_package *p;
+       struct uci_package *p = NULL;
        struct uci_element *e;
        struct uci_section *s;
        struct uci_ptr ptr = { .package = "system" };
@@ -1235,7 +1235,7 @@ static FILE *
 dnsmasq_leasefile(void)
 {
        FILE *leases = NULL;
-       struct uci_package *p;
+       struct uci_package *p = NULL;
        struct uci_element *e;
        struct uci_section *s;
        struct uci_ptr ptr = {
@@ -2195,6 +2195,106 @@ rpc_luci2_network_ifdown(struct ubus_context *ctx, struct ubus_object *obj,
        return network_ifupdown(ctx, req, msg, false);
 }
 
+static int
+rpc_luci2_network_dev_list(struct ubus_context *ctx, struct ubus_object *obj,
+                           struct ubus_request_data *req, const char *method,
+                           struct blob_attr *msg)
+{
+       char path[PATH_MAX];
+       struct dirent *e;
+       struct stat s;
+       void *c, *t;
+       bool wireless, bridge, tuntap;
+       int type, flags;
+       DIR *d;
+       FILE *f;
+
+       if (!(d = opendir("/sys/class/net")))
+               return rpc_errno_status();
+
+       blob_buf_init(&buf, 0);
+       c = blobmsg_open_array(&buf, "devices");
+
+       while ((e = readdir(d)) != NULL)
+       {
+               snprintf(path, sizeof(path) - 1, "/sys/class/net/%s/type", e->d_name);
+
+               if (stat(path, &s) || !S_ISREG(s.st_mode) || !(f = fopen(path, "r")))
+                       continue;
+
+               type = 1;
+               memset(path, 0, sizeof(path));
+
+               if (fread(path, 1, sizeof(path) - 1, f) > 0)
+                       type = atoi(path);
+
+               fclose(f);
+
+               snprintf(path, sizeof(path) - 1, "/sys/class/net/%s/flags", e->d_name);
+
+               if (stat(path, &s) || !S_ISREG(s.st_mode) || !(f = fopen(path, "r")))
+                       continue;
+
+               flags = 0;
+               memset(path, 0, sizeof(path));
+
+               if (fread(path, 1, sizeof(path) - 1, f) > 0)
+                       flags = strtoul(path, NULL, 16);
+
+               fclose(f);
+
+               snprintf(path, sizeof(path) - 1,
+                        "/sys/class/net/%s/wireless", e->d_name);
+
+               wireless = (!stat(path, &s) && S_ISDIR(s.st_mode));
+
+               snprintf(path, sizeof(path) - 1,
+                        "/sys/class/net/%s/phy80211", e->d_name);
+
+               wireless = (wireless || (!stat(path, &s) && S_ISLNK(s.st_mode)));
+
+               snprintf(path, sizeof(path) - 1,
+                        "/sys/class/net/%s/bridge", e->d_name);
+
+               bridge = (!stat(path, &s) && S_ISDIR(s.st_mode));
+
+               snprintf(path, sizeof(path) - 1,
+                        "/sys/class/net/%s/tun_flags", e->d_name);
+
+               tuntap = (!stat(path, &s) && S_ISREG(s.st_mode));
+
+               t = blobmsg_open_table(&buf, NULL);
+
+               blobmsg_add_string(&buf, "device", e->d_name);
+               blobmsg_add_u32(&buf, "type", type);
+               blobmsg_add_u8(&buf, "is_up", flags & 1);
+               blobmsg_add_u8(&buf, "is_bridge", bridge);
+               blobmsg_add_u8(&buf, "is_tuntap", tuntap);
+               blobmsg_add_u8(&buf, "is_wireless", wireless);
+
+               blobmsg_close_table(&buf, t);
+       }
+
+       blobmsg_close_array(&buf, c);
+
+       closedir(d);
+
+       ubus_send_reply(ctx, req, buf.head);
+       return 0;
+}
+
+static int
+rpc_luci2_network_eap_support(struct ubus_context *ctx, struct ubus_object *obj,
+                              struct ubus_request_data *req, const char *method,
+                              struct blob_attr *msg)
+{
+       blob_buf_init(&buf, 0);
+       blobmsg_add_u8(&buf, "master", !system("/usr/sbin/hostapd -veap"));
+       blobmsg_add_u8(&buf, "client", !system("/usr/sbin/wpa_supplicant -veap"));
+       ubus_send_reply(ctx, req, buf.head);
+       return 0;
+}
+
 
 struct opkg_state {
        int cur_offset;
@@ -2474,6 +2574,30 @@ menu_access(struct blob_attr *sid, struct blob_attr *acls, struct blob_buf *e)
        return rv;
 }
 
+static bool
+menu_files(struct blob_attr *files)
+{
+       int rem;
+       bool empty = true;
+       struct stat s;
+       struct blob_attr *file;
+
+       blobmsg_for_each_attr(file, files, rem)
+       {
+               empty = false;
+
+               if (blobmsg_type(file) != BLOBMSG_TYPE_STRING)
+                       continue;
+
+               if (stat(blobmsg_get_string(file), &s) || !S_ISREG(s.st_mode))
+                       continue;
+
+               return true;
+       }
+
+       return empty;
+}
+
 static int
 rpc_luci2_ui_menu(struct ubus_context *ctx, struct ubus_object *obj,
                   struct ubus_request_data *req, const char *method,
@@ -2485,7 +2609,7 @@ rpc_luci2_ui_menu(struct ubus_context *ctx, struct ubus_object *obj,
        struct blob_buf item = { 0 };
        struct blob_attr *entry, *attr;
        struct blob_attr *tb[__RPC_MENU_MAX];
-       bool access;
+       bool access, files;
        void *c, *d;
 
        blobmsg_parse(rpc_menu_policy, __RPC_MENU_MAX, tb,
@@ -2509,7 +2633,7 @@ rpc_luci2_ui_menu(struct ubus_context *ctx, struct ubus_object *obj,
 
                        blob_for_each_attr(entry, menu.head, rem)
                        {
-                               access = true;
+                               access = files = true;
 
                                blob_buf_init(&item, 0);
                                d = blobmsg_open_table(&item, blobmsg_name(entry));
@@ -2519,13 +2643,16 @@ rpc_luci2_ui_menu(struct ubus_context *ctx, struct ubus_object *obj,
                                        if (blob_id(attr) == BLOBMSG_TYPE_ARRAY &&
                                            !strcmp(blobmsg_name(attr), "acls"))
                                                access = menu_access(tb[RPC_MENU_SESSION], attr, &item);
+                                       else if (blob_id(attr) == BLOBMSG_TYPE_ARRAY &&
+                                                !strcmp(blobmsg_name(attr), "files"))
+                                               files = menu_files(attr);
                                        else
                                                blobmsg_add_blob(&item, attr);
                                }
 
                                blobmsg_close_table(&item, d);
 
-                               if (access)
+                               if (access && files)
                                        blob_for_each_attr(attr, item.head, rem2)
                                                blobmsg_add_blob(&buf, attr);
 
@@ -2698,7 +2825,9 @@ rpc_luci2_api_init(const struct rpc_daemon_ops *o, struct ubus_context *ctx)
                UBUS_METHOD("ifup",                  rpc_luci2_network_ifup,
                                                     rpc_data_policy),
                UBUS_METHOD("ifdown",                rpc_luci2_network_ifdown,
-                                                    rpc_data_policy)
+                                                    rpc_data_policy),
+               UBUS_METHOD_NOARG("device_list",     rpc_luci2_network_dev_list),
+               UBUS_METHOD_NOARG("eap_support",     rpc_luci2_network_eap_support)
        };
 
        static struct ubus_object_type luci2_network_type =
@@ -2772,6 +2901,6 @@ rpc_luci2_api_init(const struct rpc_daemon_ops *o, struct ubus_context *ctx)
        return rv;
 }
 
-const struct rpc_plugin rpc_plugin = {
+struct rpc_plugin rpc_plugin = {
        .init = rpc_luci2_api_init
 };