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