1 /* 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 5 * 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. 10 * 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. 14 * 15 * Copyright (C) 2012 John Crispin <blogic@openwrt.org> 16 */ 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 #define __USE_GNU 21 #include <string.h> 22 #include <regex.h> 23 #include <glob.h> 24 25 #include <libubox/list.h> 26 #include <libubox/blobmsg_json.h> 27 #include "libubus.h" 28 29 struct initd { 30 struct list_head list; 31 32 char *name; 33 char *exec; 34 char *desc; 35 char *tpl; 36 char **deps; 37 int start; 38 int stop; 39 }; 40 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; 46 47 static void initd_free(struct initd *i) 48 { 49 if (i->name) 50 free(i->name); 51 if (i->exec) 52 free(i->exec); 53 if (i->desc) 54 free(i->desc); 55 if (i->tpl) 56 free(i->tpl); 57 } 58 59 static int initd_parse(const char *file) 60 { 61 FILE *fp; 62 struct initd *i; 63 regmatch_t matches[2]; 64 char buffer[1024]; 65 ssize_t len; 66 67 fp = fopen(file, "r"); 68 if (!fp) { 69 fprintf(stderr, "failed to open %s\n", file); 70 return -1; 71 } 72 len = fread(buffer, 1, sizeof(buffer) - 1, fp); 73 fclose(fp); 74 75 if (len < 1) { 76 fprintf(stderr, "failed to read from %s\n", file); 77 return -1; 78 } 79 buffer[len] = '\0'; 80 81 i = calloc(1, sizeof(struct initd)); 82 if (!i) { 83 fprintf(stderr, "failed to alloc initd struct\n"); 84 return -1; 85 } 86 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); 99 100 if (i->name && i->exec) 101 list_add(&i->list, &initds); 102 else 103 initd_free(i); 104 105 return 0; 106 } 107 108 static void initd_init(void) 109 { 110 int gl_flags = GLOB_NOESCAPE | GLOB_MARK; 111 glob_t gl; 112 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); 120 121 if (glob("/etc/rc.d/P*", gl_flags, NULL, &gl) >= 0) { 122 int j; 123 for (j = 0; j < gl.gl_pathc; j++) 124 initd_parse(gl.gl_pathv[j]); 125 } 126 globfree(&gl); 127 128 regfree(&pat_provides); 129 regfree(&pat_require); 130 regfree(&pat_start); 131 regfree(&pat_stop); 132 regfree(&pat_desc); 133 regfree(&pat_exec); 134 regfree(&pat_tpl); 135 } 136 137 static int init_services(void) 138 { 139 struct initd *i; 140 void *instances, *instance, *command; 141 142 list_for_each_entry(i, &initds, list) { 143 char *t; 144 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, " "); 151 while (t) { 152 blobmsg_add_string(&b, NULL, t); 153 t = strtok(NULL, " "); 154 } 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); 159 } 160 161 return 0; 162 } 163 164 int main(int argc, char **argv) 165 { 166 int ret; 167 168 initd_init(); 169 170 if (list_empty(&initds)) 171 return 0; 172 173 ctx = ubus_connect(NULL); 174 if (!ctx) { 175 fprintf(stderr, "Failed to connect to ubus\n"); 176 return -1; 177 } 178 179 ret = ubus_lookup_id(ctx, "service", &service); 180 if (ret) { 181 fprintf(stderr, "Failed to find service object: %s\n", ubus_strerror(ret)); 182 return -1; 183 } 184 185 return init_services(); 186 } 187
This page was automatically generated by LXR 0.3.1. • OpenWrt