144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross/* 244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * Copyright (C) 2010 The Android Open Source Project 344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * 444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * Licensed under the Apache License, Version 2.0 (the "License"); 544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * you may not use this file except in compliance with the License. 644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * You may obtain a copy of the License at 744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * 844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * http://www.apache.org/licenses/LICENSE-2.0 944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * 1044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * Unless required by applicable law or agreed to in writing, software 1144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * distributed under the License is distributed on an "AS IS" BASIS, 1244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * See the License for the specific language governing permissions and 1444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross * limitations under the License. 1544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross */ 1644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 173312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#include <ctype.h> 183312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#include <errno.h> 1944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <stdio.h> 2044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <unistd.h> 2144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <stdarg.h> 223312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#include <stdlib.h> 2344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <string.h> 2444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 253312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#include "ueventd.h" 2644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include "ueventd_parser.h" 2744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include "parser.h" 2844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include "log.h" 2944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include "util.h" 3044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 313312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmannstatic list_declare(subsystem_list); 323312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 3344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Crossstatic void parse_line_device(struct parse_state *state, int nargs, char **args); 3444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 353312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#define SECTION 0x01 363312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#define OPTION 0x02 373312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 383312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#include "ueventd_keywords.h" 393312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 403312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#define KEYWORD(symbol, flags, nargs) \ 413312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann [ K_##symbol ] = { #symbol, nargs + 1, flags, }, 423312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 433312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmannstatic struct { 443312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann const char *name; 453312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann unsigned char nargs; 463312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann unsigned char flags; 473312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann} keyword_info[KEYWORD_COUNT] = { 483312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann [ K_UNKNOWN ] = { "unknown", 0, 0 }, 493312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#include "ueventd_keywords.h" 503312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann}; 513312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#undef KEYWORD 523312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 533312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#define kw_is(kw, type) (keyword_info[kw].flags & (type)) 543312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann#define kw_nargs(kw) (keyword_info[kw].nargs) 553312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 563312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmannstatic int lookup_keyword(const char *s) 573312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann{ 583312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann switch (*s++) { 593312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann case 'd': 603312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (!strcmp(s, "evname")) return K_devname; 613312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (!strcmp(s, "irname")) return K_dirname; 623312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann break; 633312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann case 's': 643312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (!strcmp(s, "ubsystem")) return K_subsystem; 653312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann break; 663312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 673312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return K_UNKNOWN; 683312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann} 693312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 703312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmannstatic void parse_line_no_op(struct parse_state *state __attribute__((unused)), 713312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann int nargs __attribute__((unused)), char **args __attribute__((unused))) 723312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann{ 733312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann} 743312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 753312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmannstatic int valid_name(const char *name) 763312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann{ 773312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann while (*name) { 783312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (!isalnum(*name) && (*name != '_') && (*name != '-')) { 793312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return 0; 803312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 813312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann name++; 823312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 833312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return 1; 843312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann} 853312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 863312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmannstruct ueventd_subsystem *ueventd_subsystem_find_by_name(const char *name) 873312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann{ 883312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann struct listnode *node; 893312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann struct ueventd_subsystem *s; 903312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 913312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann list_for_each(node, &subsystem_list) { 923312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann s = node_to_item(node, struct ueventd_subsystem, slist); 933312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (!strcmp(s->name, name)) { 943312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return s; 953312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 963312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 973312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return 0; 983312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann} 993312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1003312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmannstatic void *parse_subsystem(struct parse_state *state, 1013312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann int nargs __attribute__((unused)), char **args) 1023312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann{ 1033312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann struct ueventd_subsystem *s; 1043312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1053312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (!valid_name(args[1])) { 1063312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann parse_error(state, "invalid subsystem name '%s'\n", args[1]); 1073312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return 0; 1083312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 1093312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1103312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann s = ueventd_subsystem_find_by_name(args[1]); 1113312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (s) { 1123312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann parse_error(state, "ignored duplicate definition of subsystem '%s'\n", 1133312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann args[1]); 1143312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return 0; 1153312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 1163312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1173312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann s = calloc(1, sizeof(*s)); 1183312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (!s) { 1193312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann parse_error(state, "out of memory\n"); 1203312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return 0; 1213312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 1223312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann s->name = args[1]; 1233312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann s->dirname = "/dev"; 1243312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann list_add_tail(&subsystem_list, &s->slist); 1253312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return s; 1263312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann} 1273312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1283312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmannstatic void parse_line_subsystem(struct parse_state *state, int nargs, 1293312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann char **args) 1303312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann{ 1313312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann struct ueventd_subsystem *s = state->context; 1323312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann int kw; 1333312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1343312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (nargs == 0) { 1353312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return; 1363312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 1373312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1383312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann kw = lookup_keyword(args[0]); 1393312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann switch (kw) { 1403312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann case K_devname: 1413312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (!strcmp(args[1], "uevent_devname")) 1423312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann s->devname_src = DEVNAME_UEVENT_DEVNAME; 1433312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann else if (!strcmp(args[1], "uevent_devpath")) 1443312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann s->devname_src = DEVNAME_UEVENT_DEVPATH; 1453312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann else 1463312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann parse_error(state, "invalid devname '%s'\n", args[1]); 1473312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann break; 1483312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1493312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann case K_dirname: 1503312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (args[1][0] == '/') 1513312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann s->dirname = args[1]; 1523312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann else 1533312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann parse_error(state, "dirname '%s' does not start with '/'\n", 1543312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann args[1]); 1553312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann break; 1563312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1573312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann default: 1583312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann parse_error(state, "invalid option '%s'\n", args[0]); 1593312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 1603312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann} 1613312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1623312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmannstatic void parse_new_section(struct parse_state *state, int kw, 1633312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann int nargs, char **args) 1643312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann{ 1653312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann printf("[ %s %s ]\n", args[0], 1663312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann nargs > 1 ? args[1] : ""); 1673312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1683312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann switch(kw) { 1693312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann case K_subsystem: 1703312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann state->context = parse_subsystem(state, nargs, args); 1713312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (state->context) { 1723312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann state->parse_line = parse_line_subsystem; 1733312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return; 1743312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 1753312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann break; 1763312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 1773312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann state->parse_line = parse_line_no_op; 1783312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann} 1793312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1803312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmannstatic void parse_line(struct parse_state *state, char **args, int nargs) 1813312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann{ 1823312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann int kw = lookup_keyword(args[0]); 1833312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann int kw_nargs = kw_nargs(kw); 1843312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1853312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (nargs < kw_nargs) { 1863312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann parse_error(state, "%s requires %d %s\n", args[0], kw_nargs - 1, 1873312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann kw_nargs > 2 ? "arguments" : "argument"); 1883312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann return; 1893312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 1903312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 1913312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann if (kw_is(kw, SECTION)) { 1923312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann parse_new_section(state, kw, nargs, args); 1933312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } else if (kw_is(kw, OPTION)) { 1943312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann state->parse_line(state, nargs, args); 1953312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } else { 1963312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann parse_line_device(state, nargs, args); 1973312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann } 1983312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann} 1993312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann 20044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Crossstatic void parse_config(const char *fn, char *s) 20144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross{ 20244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross struct parse_state state; 20344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross char *args[UEVENTD_PARSER_MAXARGS]; 20444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross int nargs; 20544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross nargs = 0; 20644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross state.filename = fn; 20744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross state.line = 1; 20844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross state.ptr = s; 20944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross state.nexttoken = 0; 2103312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann state.parse_line = parse_line_no_op; 21144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross for (;;) { 21244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross int token = next_token(&state); 21344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross switch (token) { 21444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross case T_EOF: 2153312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann parse_line(&state, args, nargs); 21644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 21744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross case T_NEWLINE: 21844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (nargs) { 2193312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann parse_line(&state, args, nargs); 22044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross nargs = 0; 22144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 2223312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann state.line++; 22344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross break; 22444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross case T_TEXT: 22544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (nargs < UEVENTD_PARSER_MAXARGS) { 22644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross args[nargs++] = state.text; 22744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 22844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross break; 22944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 23044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 23144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross} 23244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 23344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Crossint ueventd_parse_config_file(const char *fn) 23444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross{ 23544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross char *data; 23644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross data = read_file(fn, 0); 23744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (!data) return -1; 23844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 23944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross parse_config(fn, data); 24044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross DUMP(); 24144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return 0; 24244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross} 24344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 2443312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmannstatic void parse_line_device(struct parse_state *state __attribute__((unused)), 2453312aa8379d877044def52f3b3be5c912a5e61a2Greg Hackmann int nargs, char **args) 24644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross{ 24744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross set_device_permission(nargs, args); 24844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross} 249