remove script prefix
[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_SUFFIX     " dump"
24
25 static void proto_shell_add_handler(const char *script, struct json_object *obj)
26 {
27         if (json_object_get_type(obj) != json_type_object)
28                 return;
29
30         fprintf(stderr, "Add handler for script %s: %s\n", script, json_object_to_json_string(obj));
31 }
32
33 static void proto_shell_add_script(const char *name)
34 {
35         struct json_tokener *tok = NULL;
36         struct json_object *obj;
37         static char buf[512];
38         char *start, *end, *cmd;
39         FILE *f;
40         int buflen, len;
41
42         cmd = alloca(strlen(name) + 1 + sizeof(DUMP_SUFFIX));
43         sprintf(cmd, "%s" DUMP_SUFFIX, name);
44
45         f = popen(cmd, "r");
46         if (!f)
47                 return;
48
49         do {
50                 buflen = fread(buf, 1, sizeof(buf) - 1, f);
51                 if (buflen <= 0)
52                         continue;
53
54                 start = buf;
55                 len = buflen;
56                 do {
57                         end = memchr(start, '\n', len);
58                         if (end)
59                                 len = end - start;
60
61                         if (!tok)
62                                 tok = json_tokener_new();
63
64                         obj = json_tokener_parse_ex(tok, start, len);
65                         if (!is_error(obj)) {
66                                 proto_shell_add_handler(name, obj);
67                                 json_object_put(obj);
68                                 json_tokener_free(tok);
69                                 tok = NULL;
70                         }
71
72                         if (end) {
73                                 start = end + 1;
74                                 len = buflen - (start - buf);
75                         }
76                 } while (len > 0);
77         } while (!feof(f) && !ferror(f));
78
79         if (tok)
80                 json_tokener_free(tok);
81
82         pclose(f);
83 }
84
85 void __init proto_shell_init(void)
86 {
87         glob_t g;
88         int i;
89
90         main_fd = open(".", O_RDONLY | O_DIRECTORY);
91         if (main_fd < 0)
92                 return;
93
94         if (chdir(main_path)) {
95                 perror("chdir(main path)");
96                 goto close_cur;
97         }
98
99         if (chdir("./proto"))
100                 goto close_cur;
101
102         proto_fd = open(".", O_RDONLY | O_DIRECTORY);
103         if (proto_fd < 0)
104                 goto close_cur;
105
106         glob("./*.sh", 0, NULL, &g);
107         for (i = 0; i < g.gl_pathc; i++)
108                 proto_shell_add_script(g.gl_pathv[i]);
109
110         if (list_empty(&handlers))
111                 close(proto_fd);
112
113 close_cur:
114         fchdir(main_fd);
115         if (list_empty(&handlers))
116                 close(main_fd);
117 }