• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ubox/lsbloader.c

  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