2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
15 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
25 #include <libubox/list.h>
26 #include <libubox/blobmsg_json.h>
30 struct list_head list
;
41 static LIST_HEAD(initds
);
42 static regex_t pat_provides
, pat_require
, pat_start
, pat_stop
, pat_desc
, pat_exec
, pat_tpl
;
43 static struct ubus_context
*ctx
;
44 static struct blob_buf b
;
45 static uint32_t service
;
47 static void initd_free(struct initd
*i
)
59 static int initd_parse(const char *file
)
63 regmatch_t matches
[2];
67 fp
= fopen(file
, "r");
69 fprintf(stderr
, "failed to open %s\n", file
);
72 len
= fread(buffer
, 1, sizeof(buffer
) - 1, fp
);
76 fprintf(stderr
, "failed to read from %s\n", file
);
81 i
= calloc(1, sizeof(struct initd
));
83 fprintf(stderr
, "failed to alloc initd struct\n");
87 if (!regexec(&pat_provides
, buffer
, 2, matches
, 0))
88 i
->name
= strndup(buffer
+ matches
[1].rm_so
, (size_t)matches
[1].rm_eo
- matches
[1].rm_so
);
89 if (!regexec(&pat_exec
, buffer
, 2, matches
, 0))
90 i
->exec
= strndup(buffer
+ matches
[1].rm_so
, matches
[1].rm_eo
- matches
[1].rm_so
);
91 if (!regexec(&pat_desc
, buffer
, 2, matches
, 0))
92 i
->desc
= strndup(buffer
+ matches
[1].rm_so
, matches
[1].rm_eo
- matches
[1].rm_so
);
93 if (!regexec(&pat_tpl
, buffer
, 2, matches
, 0))
94 i
->tpl
= strndup(buffer
+ matches
[1].rm_so
, matches
[1].rm_eo
- matches
[1].rm_so
);
95 if (!regexec(&pat_start
, buffer
, 2, matches
, 0))
96 i
->start
+= atoi(buffer
+ matches
[1].rm_so
);
97 if (!regexec(&pat_stop
, buffer
, 2, matches
, 0))
98 i
->stop
+= atoi(buffer
+ matches
[1].rm_so
);
100 if (i
->name
&& i
->exec
)
101 list_add(&i
->list
, &initds
);
108 static void initd_init(void)
110 int gl_flags
= GLOB_NOESCAPE
| GLOB_MARK
;
113 regcomp(&pat_provides
, "# Provides:[ \t]*([a-zA-Z0-9]+)", REG_EXTENDED
);
114 regcomp(&pat_require
, "# Required-Start:[ \t]*([a-zA-Z0-9 ]+)", REG_EXTENDED
);
115 regcomp(&pat_start
, "# Default-Start:[ \t]*([0-9])", REG_EXTENDED
);
116 regcomp(&pat_stop
, "# Default-Stop:[ \t]*([0-9])", REG_EXTENDED
);
117 regcomp(&pat_desc
, "# Description:[ \t]*([a-zA-Z0-9 ]+)", REG_EXTENDED
);
118 regcomp(&pat_exec
, "# X-Exec:[ \t]*([a-zA-Z0-9/ ]+)", REG_EXTENDED
);
119 regcomp(&pat_tpl
, "# X-Template:[ \t]*([a-zA-Z0-9/.]+)", REG_EXTENDED
);
121 if (glob("/etc/rc.d/P*", gl_flags
, NULL
, &gl
) >= 0) {
123 for (j
= 0; j
< gl
.gl_pathc
; j
++)
124 initd_parse(gl
.gl_pathv
[j
]);
128 regfree(&pat_provides
);
129 regfree(&pat_require
);
137 static int init_services(void)
140 void *instances
, *instance
, *command
;
142 list_for_each_entry(i
, &initds
, list
) {
145 blob_buf_init(&b
, 0);
146 blobmsg_add_string(&b
, "name", i
->name
);
147 instances
= blobmsg_open_table(&b
, "instances");
148 instance
= blobmsg_open_table(&b
, "instance");
149 command
= blobmsg_open_array(&b
, "command");
150 t
= strtok(i
->exec
, " ");
152 blobmsg_add_string(&b
, NULL
, t
);
153 t
= strtok(NULL
, " ");
155 blobmsg_close_array(&b
, command
);
156 blobmsg_close_table(&b
, instance
);
157 blobmsg_close_table(&b
, instances
);
158 ubus_invoke(ctx
, service
, "add", b
.head
, NULL
, 0, 1000);
164 int main(int argc
, char **argv
)
170 if (list_empty(&initds
))
173 ctx
= ubus_connect(NULL
);
175 fprintf(stderr
, "Failed to connect to ubus\n");
179 ret
= ubus_lookup_id(ctx
, "service", &service
);
181 fprintf(stderr
, "Failed to find service object: %s\n", ubus_strerror(ret
));
185 return init_services();