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 = malloc(sizeof(struct initd));
83 fprintf(stderr, "failed to alloc initd struct\n");
86 memset(i, 0, sizeof(*i));
88 if (!regexec(&pat_provides, buffer, 2, matches, 0))
89 i->name = strndup(buffer + matches[1].rm_so, (size_t)matches[1].rm_eo - matches[1].rm_so);
90 if (!regexec(&pat_exec, buffer, 2, matches, 0))
91 i->exec = strndup(buffer + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
92 if (!regexec(&pat_desc, buffer, 2, matches, 0))
93 i->desc = strndup(buffer + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
94 if (!regexec(&pat_tpl, buffer, 2, matches, 0))
95 i->tpl = strndup(buffer + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
96 if (!regexec(&pat_start, buffer, 2, matches, 0))
97 i->start += atoi(buffer + matches[1].rm_so);
98 if (!regexec(&pat_stop, buffer, 2, matches, 0))
99 i->stop += atoi(buffer + matches[1].rm_so);
101 if (i->name && i->exec)
102 list_add(&i->list, &initds);
109 static void initd_init(void)
111 int gl_flags = GLOB_NOESCAPE | GLOB_MARK;
114 regcomp(&pat_provides, "# Provides:[ \t]*([a-zA-Z0-9]+)", REG_EXTENDED);
115 regcomp(&pat_require, "# Required-Start:[ \t]*([a-zA-Z0-9 ]+)", REG_EXTENDED);
116 regcomp(&pat_start, "# Default-Start:[ \t]*([0-9])", REG_EXTENDED);
117 regcomp(&pat_stop, "# Default-Stop:[ \t]*([0-9])", REG_EXTENDED);
118 regcomp(&pat_desc, "# Description:[ \t]*([a-zA-Z0-9 ]+)", REG_EXTENDED);
119 regcomp(&pat_exec, "# X-Exec:[ \t]*([a-zA-Z0-9/ ]+)", REG_EXTENDED);
120 regcomp(&pat_tpl, "# X-Template:[ \t]*([a-zA-Z0-9/.]+)", REG_EXTENDED);
122 if (glob("/etc/rc.d/P*", gl_flags, NULL, &gl) >= 0) {
124 for (j = 0; j < gl.gl_pathc; j++)
125 initd_parse(gl.gl_pathv[j]);
129 regfree(&pat_provides);
130 regfree(&pat_require);
138 static int init_services(void)
141 void *instances, *instance, *command;
143 list_for_each_entry(i, &initds, list) {
146 blob_buf_init(&b, 0);
147 blobmsg_add_string(&b, "name", i->name);
148 instances = blobmsg_open_table(&b, "instances");
149 instance = blobmsg_open_table(&b, "instance");
150 command = blobmsg_open_array(&b, "command");
151 t = strtok(i->exec, " ");
153 blobmsg_add_string(&b, NULL, t);
154 t = strtok(NULL, " ");
156 blobmsg_close_array(&b, command);
157 blobmsg_close_table(&b, instance);
158 blobmsg_close_table(&b, instances);
159 ubus_invoke(ctx, service, "add", b.head, NULL, 0, 1000);
165 int main(int argc, char **argv)
171 if (list_empty(&initds))
174 ctx = ubus_connect(NULL);
176 fprintf(stderr, "Failed to connect to ubus\n");
180 ret = ubus_lookup_id(ctx, "service", &service);
182 fprintf(stderr, "Failed to find service object: %s\n", ubus_strerror(ret));
186 return init_services();