parser.c revision ca7648ddfb46347c60014a849b0150a74df4e1d2
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h>
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdarg.h>
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stddef.h>
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h>
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "init.h"
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "property_service.h"
12ca7648ddfb46347c60014a849b0150a74df4e1d2Colin Cross#include "parser.h"
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
144e221f0077373b37ca70e862eface2987557295bSan Mehat#include <cutils/iosched_policy.h>
154e221f0077373b37ca70e862eface2987557295bSan Mehat
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/_system_properties.h>
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic list_declare(service_list);
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic list_declare(action_list);
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic list_declare(action_queue);
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define RAW(x...) log_write(6, x)
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid DUMP(void)
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct service *svc;
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct action *act;
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct command *cmd;
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node;
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node2;
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct socketinfo *si;
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int n;
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &service_list) {
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc = node_to_item(node, struct service, slist);
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("service %s\n", svc->name);
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("  class '%s'\n", svc->classname);
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("  exec");
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (n = 0; n < svc->nargs; n++) {
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            RAW(" '%s'", svc->args[n]);
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("\n");
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (si = svc->sockets; si; si = si->next) {
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            RAW("  socket %s %s 0%o\n", si->name, si->type, si->perm);
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &action_list) {
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        act = node_to_item(node, struct action, alist);
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("on %s\n", act->name);
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        list_for_each(node2, &act->commands) {
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            cmd = node_to_item(node2, struct command, clist);
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            RAW("  %p", cmd->func);
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            for (n = 0; n < cmd->nargs; n++) {
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                RAW(" %s", cmd->args[n]);
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            RAW("\n");
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("\n");
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define T_EOF 0
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define T_TEXT 1
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define T_NEWLINE 2
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct parse_state
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *ptr;
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *text;
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int line;
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int nexttoken;
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void *context;
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void (*parse_line)(struct parse_state *state, int nargs, char **args);
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *filename;
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *parse_service(struct parse_state *state, int nargs, char **args);
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void parse_line_service(struct parse_state *state, int nargs, char **args);
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *parse_action(struct parse_state *state, int nargs, char **args);
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void parse_line_action(struct parse_state *state, int nargs, char **args);
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid parse_error(struct parse_state *state, const char *fmt, ...)
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_list ap;
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[128];
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int off;
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(buf, 128, "%s: %d: ", state->filename, state->line);
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buf[127] = 0;
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    off = strlen(buf);
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_start(ap, fmt);
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    vsnprintf(buf + off, 128 - off, fmt, ap);
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_end(ap);
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buf[127] = 0;
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ERROR("%s", buf);
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SECTION 0x01
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define COMMAND 0x02
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OPTION  0x04
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "keywords.h"
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define KEYWORD(symbol, flags, nargs, func) \
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    [ K_##symbol ] = { #symbol, func, nargs + 1, flags, },
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct {
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *name;
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int (*func)(int nargs, char **args);
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned char nargs;
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned char flags;
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} keyword_info[KEYWORD_COUNT] = {
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    [ K_UNKNOWN ] = { "unknown", 0, 0, 0 },
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "keywords.h"
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef KEYWORD
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define kw_is(kw, type) (keyword_info[kw].flags & (type))
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define kw_name(kw) (keyword_info[kw].name)
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define kw_func(kw) (keyword_info[kw].func)
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define kw_nargs(kw) (keyword_info[kw].nargs)
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint lookup_keyword(const char *s)
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (*s++) {
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'c':
1337c44fe5925b6dd51166f73d30de0a2f22d66373eSan Mehat	if (!strcmp(s, "opy")) return K_copy;
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "apability")) return K_capability;
135e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik)        if (!strcmp(s, "hdir")) return K_chdir;
136e7cb137f32fbc7caf97b80fac152b4bd3ac242cdJay Freeman (saurik)        if (!strcmp(s, "hroot")) return K_chroot;
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "lass")) return K_class;
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "lass_start")) return K_class_start;
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "lass_stop")) return K_class_stop;
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "onsole")) return K_console;
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "hown")) return K_chown;
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "hmod")) return K_chmod;
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "ritical")) return K_critical;
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'd':
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "isabled")) return K_disabled;
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "omainname")) return K_domainname;
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "evice")) return K_device;
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'e':
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "xec")) return K_exec;
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "xport")) return K_export;
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'g':
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "roup")) return K_group;
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'h':
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "ostname")) return K_hostname;
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'i':
1614e221f0077373b37ca70e862eface2987557295bSan Mehat        if (!strcmp(s, "oprio")) return K_ioprio;
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "fup")) return K_ifup;
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "nsmod")) return K_insmod;
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "mport")) return K_import;
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'k':
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "eycodes")) return K_keycodes;
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'l':
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "oglevel")) return K_loglevel;
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'm':
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "kdir")) return K_mkdir;
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "ount")) return K_mount;
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'o':
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "n")) return K_on;
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "neshot")) return K_oneshot;
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "nrestart")) return K_onrestart;
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'r':
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "estart")) return K_restart;
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 's':
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "ervice")) return K_service;
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "etenv")) return K_setenv;
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "etkey")) return K_setkey;
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "etprop")) return K_setprop;
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "etrlimit")) return K_setrlimit;
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "ocket")) return K_socket;
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "tart")) return K_start;
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "top")) return K_stop;
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "ymlink")) return K_symlink;
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "ysclktz")) return K_sysclktz;
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 't':
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "rigger")) return K_trigger;
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'u':
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "ser")) return K_user;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'w':
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(s, "rite")) return K_write;
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return K_UNKNOWN;
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid parse_line_no_op(struct parse_state *state, int nargs, char **args)
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint next_token(struct parse_state *state)
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *x = state->ptr;
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *s;
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (state->nexttoken) {
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int t = state->nexttoken;
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        state->nexttoken = 0;
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return t;
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (;;) {
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch (*x) {
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 0:
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state->ptr = x;
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return T_EOF;
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\n':
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state->line++;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state->ptr = x;
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return T_NEWLINE;
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case ' ':
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\t':
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\r':
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '#':
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            while (*x && (*x != '\n')) x++;
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state->line++;
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state->ptr = x;
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return T_NEWLINE;
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        default:
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto text;
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttextdone:
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    state->ptr = x;
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *s = 0;
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return T_TEXT;
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttext:
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    state->text = s = x;
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttextresume:
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (;;) {
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch (*x) {
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 0:
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto textdone;
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case ' ':
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\t':
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\r':
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto textdone;
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\n':
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state->nexttoken = T_NEWLINE;
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto textdone;
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '"':
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            for (;;) {
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                switch (*x) {
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                case 0:
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        /* unterminated quoted thing */
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    state->ptr = x;
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    return T_EOF;
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                case '"':
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    x++;
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    goto textresume;
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                default:
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    *s++ = *x++;
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\\':
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            switch (*x) {
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 0:
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                goto textdone;
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 'n':
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *s++ = '\n';
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                break;
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 'r':
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *s++ = '\r';
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                break;
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 't':
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *s++ = '\t';
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                break;
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case '\\':
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *s++ = '\\';
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                break;
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case '\r':
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* \ <cr> <lf> -> line continuation */
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (x[1] != '\n') {
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    x++;
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    continue;
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case '\n':
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* \ <lf> -> line continuation */
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                state->line++;
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                x++;
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* eat any extra whitespace */
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                while((*x == ' ') || (*x == '\t')) x++;
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                continue;
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            default:
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* unknown escape -- just copy */
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *s++ = *x++;
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        default:
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            *s++ = *x++;
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return T_EOF;
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid parse_line(int nargs, char **args)
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int n;
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int id = lookup_keyword(args[0]);
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("%s(%d)", args[0], id);
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (n = 1; n < nargs; n++) {
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf(" '%s'", args[n]);
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("\n");
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid parse_new_section(struct parse_state *state, int kw,
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                       int nargs, char **args)
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("[ %s %s ]\n", args[0],
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project           nargs > 1 ? args[1] : "");
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch(kw) {
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_service:
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        state->context = parse_service(state, nargs, args);
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (state->context) {
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state->parse_line = parse_line_service;
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return;
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_on:
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        state->context = parse_action(state, nargs, args);
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (state->context) {
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state->parse_line = parse_line_action;
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return;
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    state->parse_line = parse_line_no_op;
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void parse_config(const char *fn, char *s)
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct parse_state state;
365f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat    char *args[SVC_MAXARGS];
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int nargs;
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nargs = 0;
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    state.filename = fn;
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    state.line = 1;
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    state.ptr = s;
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    state.nexttoken = 0;
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    state.parse_line = parse_line_no_op;
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (;;) {
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch (next_token(&state)) {
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case T_EOF:
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state.parse_line(&state, 0, 0);
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return;
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case T_NEWLINE:
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (nargs) {
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                int kw = lookup_keyword(args[0]);
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (kw_is(kw, SECTION)) {
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    state.parse_line(&state, 0, 0);
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    parse_new_section(&state, kw, nargs, args);
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                } else {
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    state.parse_line(&state, nargs, args);
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                nargs = 0;
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case T_TEXT:
392f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat            if (nargs < SVC_MAXARGS) {
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                args[nargs++] = state.text;
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint parse_config_file(const char *fn)
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *data;
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    data = read_file(fn, 0);
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!data) return -1;
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    parse_config(fn, data);
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DUMP();
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int valid_name(const char *name)
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (strlen(name) > 16) {
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (*name) {
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!isalnum(*name) && (*name != '_') && (*name != '-')) {
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        name++;
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 1;
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct service *service_find_by_name(const char *name)
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node;
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct service *svc;
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &service_list) {
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc = node_to_item(node, struct service, slist);
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(svc->name, name)) {
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return svc;
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct service *service_find_by_pid(pid_t pid)
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node;
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct service *svc;
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &service_list) {
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc = node_to_item(node, struct service, slist);
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (svc->pid == pid) {
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return svc;
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct service *service_find_by_keychord(int keychord_id)
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node;
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct service *svc;
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &service_list) {
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc = node_to_item(node, struct service, slist);
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (svc->keychord_id == keychord_id) {
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return svc;
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid service_for_each(void (*func)(struct service *svc))
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node;
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct service *svc;
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &service_list) {
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc = node_to_item(node, struct service, slist);
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        func(svc);
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid service_for_each_class(const char *classname,
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            void (*func)(struct service *svc))
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node;
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct service *svc;
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &service_list) {
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc = node_to_item(node, struct service, slist);
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(svc->classname, classname)) {
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            func(svc);
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid service_for_each_flags(unsigned matchflags,
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            void (*func)(struct service *svc))
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node;
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct service *svc;
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &service_list) {
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc = node_to_item(node, struct service, slist);
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (svc->flags & matchflags) {
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            func(svc);
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid action_for_each_trigger(const char *trigger,
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                             void (*func)(struct action *act))
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node;
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct action *act;
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &action_list) {
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        act = node_to_item(node, struct action, alist);
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strcmp(act->name, trigger)) {
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            func(act);
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid queue_property_triggers(const char *name, const char *value)
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node;
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct action *act;
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &action_list) {
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        act = node_to_item(node, struct action, alist);
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strncmp(act->name, "property:", strlen("property:"))) {
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            const char *test = act->name + strlen("property:");
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int name_length = strlen(name);
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!strncmp(name, test, name_length) &&
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    test[name_length] == '=' &&
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    !strcmp(test + name_length + 1, value)) {
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                action_add_queue_tail(act);
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid queue_all_property_triggers()
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node;
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct action *act;
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &action_list) {
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        act = node_to_item(node, struct action, alist);
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strncmp(act->name, "property:", strlen("property:"))) {
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* parse property name and value
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project               syntax is property:<name>=<value> */
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            const char* name = act->name + strlen("property:");
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            const char* equals = strchr(name, '=');
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (equals) {
544b3779558dcfbe99f0b9c1ef796e3728edad25672Mike Lockwood                char prop_name[PROP_NAME_MAX + 1];
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                const char* value;
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                int length = equals - name;
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (length > PROP_NAME_MAX) {
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    ERROR("property name too long in trigger %s", act->name);
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                } else {
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    memcpy(prop_name, name, length);
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    prop_name[length] = 0;
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* does the property exist, and match the trigger value? */
554b3779558dcfbe99f0b9c1ef796e3728edad25672Mike Lockwood                    value = property_get(prop_name);
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    if (value && !strcmp(equals + 1, value)) {
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        action_add_queue_tail(act);
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    }
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid action_add_queue_tail(struct action *act)
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_add_tail(&action_queue, &act->qlist);
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct action *action_remove_queue_head(void)
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (list_empty(&action_queue)) {
572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        struct listnode *node = list_head(&action_queue);
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        struct action *act = node_to_item(node, struct action, qlist);
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        list_remove(node);
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return act;
578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *parse_service(struct parse_state *state, int nargs, char **args)
582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct service *svc;
584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (nargs < 3) {
585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parse_error(state, "services must have a name and a program\n");
586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!valid_name(args[1])) {
589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parse_error(state, "invalid service name '%s'\n", args[1]);
590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    svc = service_find_by_name(args[1]);
594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (svc) {
595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parse_error(state, "ignored duplicate definition of service '%s'\n", args[1]);
596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nargs -= 2;
600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs);
601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!svc) {
602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parse_error(state, "out of memory\n");
603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    svc->name = args[1];
606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    svc->classname = "default";
607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memcpy(svc->args, args + 2, sizeof(char*) * nargs);
608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    svc->args[nargs] = 0;
609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    svc->nargs = nargs;
610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    svc->onrestart.name = "onrestart";
611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_init(&svc->onrestart.commands);
612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_add_tail(&service_list, &svc->slist);
613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return svc;
614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void parse_line_service(struct parse_state *state, int nargs, char **args)
617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct service *svc = state->context;
619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct command *cmd;
620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i, kw, kw_nargs;
621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (nargs == 0) {
623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
6264e221f0077373b37ca70e862eface2987557295bSan Mehat    svc->ioprio_class = IoSchedClass_NONE;
6274e221f0077373b37ca70e862eface2987557295bSan Mehat
628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    kw = lookup_keyword(args[0]);
629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (kw) {
630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_capability:
631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_class:
633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (nargs != 2) {
634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "class option requires a classname\n");
635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            svc->classname = args[1];
637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_console:
640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc->flags |= SVC_CONSOLE;
641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_disabled:
643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc->flags |= SVC_DISABLED;
644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
6454e221f0077373b37ca70e862eface2987557295bSan Mehat    case K_ioprio:
6464e221f0077373b37ca70e862eface2987557295bSan Mehat        if (nargs != 3) {
6474e221f0077373b37ca70e862eface2987557295bSan Mehat            parse_error(state, "ioprio optin usage: ioprio <rt|be|idle> <ioprio 0-7>\n");
6484e221f0077373b37ca70e862eface2987557295bSan Mehat        } else {
6494e221f0077373b37ca70e862eface2987557295bSan Mehat            svc->ioprio_pri = strtoul(args[2], 0, 8);
6504e221f0077373b37ca70e862eface2987557295bSan Mehat
6514e221f0077373b37ca70e862eface2987557295bSan Mehat            if (svc->ioprio_pri < 0 || svc->ioprio_pri > 7) {
6524e221f0077373b37ca70e862eface2987557295bSan Mehat                parse_error(state, "priority value must be range 0 - 7\n");
6534e221f0077373b37ca70e862eface2987557295bSan Mehat                break;
6544e221f0077373b37ca70e862eface2987557295bSan Mehat            }
6554e221f0077373b37ca70e862eface2987557295bSan Mehat
6564e221f0077373b37ca70e862eface2987557295bSan Mehat            if (!strcmp(args[1], "rt")) {
6574e221f0077373b37ca70e862eface2987557295bSan Mehat                svc->ioprio_class = IoSchedClass_RT;
6584e221f0077373b37ca70e862eface2987557295bSan Mehat            } else if (!strcmp(args[1], "be")) {
6594e221f0077373b37ca70e862eface2987557295bSan Mehat                svc->ioprio_class = IoSchedClass_BE;
6604e221f0077373b37ca70e862eface2987557295bSan Mehat            } else if (!strcmp(args[1], "idle")) {
6614e221f0077373b37ca70e862eface2987557295bSan Mehat                svc->ioprio_class = IoSchedClass_IDLE;
6624e221f0077373b37ca70e862eface2987557295bSan Mehat            } else {
6634e221f0077373b37ca70e862eface2987557295bSan Mehat                parse_error(state, "ioprio option usage: ioprio <rt|be|idle> <0-7>\n");
6644e221f0077373b37ca70e862eface2987557295bSan Mehat            }
6654e221f0077373b37ca70e862eface2987557295bSan Mehat        }
6664e221f0077373b37ca70e862eface2987557295bSan Mehat        break;
667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_group:
668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (nargs < 2) {
669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "group option requires a group id\n");
670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (nargs > NR_SVC_SUPP_GIDS + 2) {
671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "group option accepts at most %d supp. groups\n",
672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        NR_SVC_SUPP_GIDS);
673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int n;
675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            svc->gid = decode_uid(args[1]);
676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            for (n = 2; n < nargs; n++) {
677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                svc->supp_gids[n-2] = decode_uid(args[n]);
678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            svc->nr_supp_gids = n - 2;
680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_keycodes:
683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (nargs < 2) {
684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "keycodes option requires atleast one keycode\n");
685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            svc->keycodes = malloc((nargs - 1) * sizeof(svc->keycodes[0]));
687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!svc->keycodes) {
688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                parse_error(state, "could not allocate keycodes\n");
689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                svc->nkeycodes = nargs - 1;
691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                for (i = 1; i < nargs; i++) {
692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    svc->keycodes[i - 1] = atoi(args[i]);
693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_oneshot:
698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc->flags |= SVC_ONESHOT;
699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_onrestart:
701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        nargs--;
702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        args++;
703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        kw = lookup_keyword(args[0]);
704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!kw_is(kw, COMMAND)) {
705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "invalid command '%s'\n", args[0]);
706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        kw_nargs = kw_nargs(kw);
709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (nargs < kw_nargs) {
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "%s requires %d %s\n", args[0], kw_nargs - 1,
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                kw_nargs > 2 ? "arguments" : "argument");
712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs);
716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cmd->func = kw_func(kw);
717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cmd->nargs = nargs;
718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memcpy(cmd->args, args, sizeof(char*) * nargs);
719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        list_add_tail(&svc->onrestart.commands, &cmd->clist);
720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_critical:
722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc->flags |= SVC_CRITICAL;
723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_setenv: { /* name value */
725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        struct svcenvinfo *ei;
726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (nargs < 2) {
727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "setenv option requires name and value arguments\n");
728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ei = calloc(1, sizeof(*ei));
731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!ei) {
732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "out of memory\n");
733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ei->name = args[1];
736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ei->value = args[2];
737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ei->next = svc->envvars;
738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc->envvars = ei;
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_socket: {/* name type perm [ uid gid ] */
742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        struct socketinfo *si;
743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (nargs < 4) {
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "socket option requires name, type, perm arguments\n");
745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (strcmp(args[2],"dgram") && strcmp(args[2],"stream")) {
748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "socket type must be 'dgram' or 'stream'\n");
749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        si = calloc(1, sizeof(*si));
752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!si) {
753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "out of memory\n");
754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        si->name = args[1];
757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        si->type = args[2];
758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        si->perm = strtoul(args[3], 0, 8);
759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (nargs > 4)
760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            si->uid = decode_uid(args[4]);
761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (nargs > 5)
762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            si->gid = decode_uid(args[5]);
763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        si->next = svc->sockets;
764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc->sockets = si;
765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case K_user:
768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (nargs != 2) {
769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parse_error(state, "user option requires a user id\n");
770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            svc->uid = decode_uid(args[1]);
772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    default:
775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parse_error(state, "invalid option '%s'\n", args[0]);
776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *parse_action(struct parse_state *state, int nargs, char **args)
780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct action *act;
782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (nargs < 2) {
783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parse_error(state, "actions must have a trigger\n");
784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (nargs > 2) {
787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parse_error(state, "actions may not have extra parameters\n");
788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    act = calloc(1, sizeof(*act));
791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    act->name = args[1];
792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_init(&act->commands);
793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_add_tail(&action_list, &act->alist);
794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* XXX add to hash */
795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return act;
796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void parse_line_action(struct parse_state* state, int nargs, char **args)
799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct command *cmd;
801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct action *act = state->context;
802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int (*func)(int nargs, char **args);
803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int kw, n;
804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (nargs == 0) {
806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    kw = lookup_keyword(args[0]);
810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!kw_is(kw, COMMAND)) {
811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parse_error(state, "invalid command '%s'\n", args[0]);
812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    n = kw_nargs(kw);
816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (nargs < n) {
817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parse_error(state, "%s requires %d %s\n", args[0], n - 1,
818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            n > 2 ? "arguments" : "argument");
819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs);
822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cmd->func = kw_func(kw);
823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cmd->nargs = nargs;
824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memcpy(cmd->args, args, sizeof(char*) * nargs);
825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_add_tail(&act->commands, &cmd->clist);
826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
827