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();