• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/netifd/handler.c

  1 /*
  2  * netifd - network interface daemon
  3  * Copyright (C) 2012-2013 Felix Fietkau <nbd@openwrt.org>
  4  *
  5  * This program is free software; you can redistribute it and/or modify
  6  * it under the terms of the GNU General Public License version 2
  7  * as published by the Free Software Foundation
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12  * GNU General Public License for more details.
 13  */
 14 
 15 #define _GNU_SOURCE
 16 #include <glob.h>
 17 #include <fcntl.h>
 18 #include <stdio.h>
 19 
 20 #include "netifd.h"
 21 #include "system.h"
 22 #include "handler.h"
 23 
 24 static int
 25 netifd_dir_push(int fd)
 26 {
 27         int prev_fd = open(".", O_RDONLY | O_DIRECTORY);
 28         system_fd_set_cloexec(prev_fd);
 29         if (fd >= 0)
 30                 if (fchdir(fd)) {}
 31         return prev_fd;
 32 }
 33 
 34 static void
 35 netifd_dir_pop(int prev_fd)
 36 {
 37         if (prev_fd < 0)
 38                 return;
 39 
 40         if (fchdir(prev_fd)) {}
 41         close(prev_fd);
 42 }
 43 
 44 int netifd_open_subdir(const char *name)
 45 {
 46         int prev_dir;
 47         int ret = -1;
 48 
 49         prev_dir = netifd_dir_push(-1);
 50         if (chdir(main_path)) {
 51                 perror("chdir(main path)");
 52                 goto out;
 53         }
 54 
 55         ret = open(name, O_RDONLY | O_DIRECTORY);
 56         if (ret >= 0)
 57                 system_fd_set_cloexec(ret);
 58 
 59 out:
 60         netifd_dir_pop(prev_dir);
 61         return ret;
 62 }
 63 
 64 static void
 65 netifd_init_script_handler(const char *script, json_object *obj, script_dump_cb cb)
 66 {
 67         json_object *tmp;
 68         const char *name;
 69 
 70         if (!json_check_type(obj, json_type_object))
 71                 return;
 72 
 73         tmp = json_get_field(obj, "name", json_type_string);
 74         if (!tmp)
 75                 return;
 76 
 77         name = json_object_get_string(tmp);
 78         cb(script, name, obj);
 79 }
 80 
 81 static void
 82 netifd_parse_script_handler(const char *name, script_dump_cb cb)
 83 {
 84         struct json_tokener *tok = NULL;
 85         json_object *obj;
 86         static char buf[512];
 87         char *start, *cmd;
 88         FILE *f;
 89         int len;
 90 
 91 #define DUMP_SUFFIX     " '' dump"
 92 
 93         cmd = alloca(strlen(name) + 1 + sizeof(DUMP_SUFFIX));
 94         sprintf(cmd, "%s" DUMP_SUFFIX, name);
 95 
 96         f = popen(cmd, "r");
 97         if (!f)
 98                 return;
 99 
100         do {
101                 start = fgets(buf, sizeof(buf), f);
102                 if (!start)
103                         continue;
104 
105                 len = strlen(start);
106 
107                 if (!tok)
108                         tok = json_tokener_new();
109 
110                 obj = json_tokener_parse_ex(tok, start, len);
111                 if (obj) {
112                         netifd_init_script_handler(name, obj, cb);
113                         json_object_put(obj);
114                         json_tokener_free(tok);
115                         tok = NULL;
116                 } else if (start[len - 1] == '\n') {
117                         json_tokener_free(tok);
118                         tok = NULL;
119                 }
120         } while (!feof(f) && !ferror(f));
121 
122         if (tok)
123                 json_tokener_free(tok);
124 
125         pclose(f);
126 }
127 
128 void netifd_init_script_handlers(int dir_fd, script_dump_cb cb)
129 {
130         glob_t g;
131         int i, prev_fd;
132 
133         prev_fd = netifd_dir_push(dir_fd);
134         if (glob("./*.sh", 0, NULL, &g)) {
135                 netifd_dir_pop(prev_fd);
136                 return;
137         }
138 
139         for (i = 0; i < g.gl_pathc; i++)
140                 netifd_parse_script_handler(g.gl_pathv[i], cb);
141         netifd_dir_pop(prev_fd);
142 
143         globfree(&g);
144 }
145 
146 char *
147 netifd_handler_parse_config(struct uci_blob_param_list *config, json_object *obj)
148 {
149         struct blobmsg_policy *attrs;
150         char *str_buf, *str_cur;
151         char const **validate;
152         int str_len = 0;
153         int i;
154 
155         config->n_params = json_object_array_length(obj);
156         attrs = calloc(1, sizeof(*attrs) * config->n_params);
157         if (!attrs)
158                 return NULL;
159 
160         validate = calloc(1, sizeof(char*) * config->n_params);
161         if (!validate)
162                 goto error;
163 
164         config->params = attrs;
165         config->validate = validate;
166         for (i = 0; i < config->n_params; i++) {
167                 json_object *cur, *name, *type;
168 
169                 cur = json_check_type(json_object_array_get_idx(obj, i), json_type_array);
170                 if (!cur)
171                         goto error;
172 
173                 name = json_check_type(json_object_array_get_idx(cur, 0), json_type_string);
174                 if (!name)
175                         goto error;
176 
177                 type = json_check_type(json_object_array_get_idx(cur, 1), json_type_int);
178                 if (!type)
179                         goto error;
180 
181                 attrs[i].name = json_object_get_string(name);
182                 attrs[i].type = json_object_get_int(type);
183                 if (attrs[i].type > BLOBMSG_TYPE_LAST)
184                         goto error;
185 
186                 str_len += strlen(attrs[i].name) + 1;
187         }
188 
189         str_buf = malloc(str_len);
190         if (!str_buf)
191                 goto error;
192 
193         str_cur = str_buf;
194         for (i = 0; i < config->n_params; i++) {
195                 const char *name = attrs[i].name;
196                 char *delim;
197 
198                 attrs[i].name = str_cur;
199                 str_cur += sprintf(str_cur, "%s", name) + 1;
200                 delim = strchr(attrs[i].name, ':');
201                 if (delim) {
202                         *delim = '\0';
203                         validate[i] = ++delim;
204                 } else {
205                         validate[i] = NULL;
206                 }
207         }
208 
209         return str_buf;
210 
211 error:
212         free(attrs);
213         if (validate)
214                 free(validate);
215         config->n_params = 0;
216         return NULL;
217 }
218 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt