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 }