remove obsolete attribute info
[project/netifd.git] / proto-shell.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <glob.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7
8 #include <libubox/blobmsg_json.h>
9
10 #include "netifd.h"
11 #include "interface.h"
12 #include "interface-ip.h"
13 #include "proto.h"
14
15 static LIST_HEAD(handlers);
16 static int proto_fd, main_fd;
17
18 struct proto_shell_handler {
19 struct list_head list;
20 struct proto_handler proto;
21 };
22
23 #define DUMP_PREFIX "./"
24 #define DUMP_SUFFIX " dump"
25
26 static void proto_shell_add_handler(const char *script, struct json_object *obj)
27 {
28 if (json_object_get_type(obj) != json_type_object)
29 return;
30
31 fprintf(stderr, "Add handler for script %s: %s\n", script, json_object_to_json_string(obj));
32 }
33
34 static void proto_shell_add_script(const char *name)
35 {
36 struct json_tokener *tok = NULL;
37 struct json_object *obj;
38 static char buf[512];
39 char *start, *end, *cmd;
40 FILE *f;
41 int buflen, len;
42
43 cmd = alloca(strlen(name) + 1 + sizeof(DUMP_PREFIX) + sizeof(DUMP_SUFFIX));
44 sprintf(cmd, DUMP_PREFIX "%s" DUMP_SUFFIX, name);
45
46 f = popen(cmd, "r");
47 if (!f)
48 return;
49
50 do {
51 buflen = fread(buf, 1, sizeof(buf) - 1, f);
52 if (buflen <= 0)
53 continue;
54
55 start = buf;
56 len = buflen;
57 do {
58 end = memchr(start, '\n', len);
59 if (end)
60 len = end - start;
61
62 if (!tok)
63 tok = json_tokener_new();
64
65 obj = json_tokener_parse_ex(tok, start, len);
66 if (!is_error(obj)) {
67 proto_shell_add_handler(name, obj);
68 json_object_put(obj);
69 json_tokener_free(tok);
70 tok = NULL;
71 }
72
73 if (end) {
74 start = end + 1;
75 len = buflen - (start - buf);
76 }
77 } while (len > 0);
78 } while (!feof(f) && !ferror(f));
79
80 if (tok)
81 json_tokener_free(tok);
82
83 pclose(f);
84 }
85
86 void __init proto_shell_init(void)
87 {
88 glob_t g;
89 int i;
90
91 main_fd = open(".", O_RDONLY | O_DIRECTORY);
92 if (main_fd < 0)
93 return;
94
95 if (chdir(main_path)) {
96 perror("chdir(main path)");
97 goto close_cur;
98 }
99
100 if (chdir("./proto"))
101 goto close_cur;
102
103 proto_fd = open(".", O_RDONLY | O_DIRECTORY);
104 if (proto_fd < 0)
105 goto close_cur;
106
107 glob("*.sh", 0, NULL, &g);
108 for (i = 0; i < g.gl_pathc; i++)
109 proto_shell_add_script(g.gl_pathv[i]);
110
111 if (list_empty(&handlers))
112 close(proto_fd);
113
114 close_cur:
115 fchdir(main_fd);
116 if (list_empty(&handlers))
117 close(main_fd);
118 }