⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.c

📁 Android 一些工具
💻 C
📖 第 1 页 / 共 2 页
字号:
                nargs = 0;            }            break;        case T_TEXT:            if (nargs < MAXARGS) {                args[nargs++] = state.text;            }            break;        }    }}int parse_config_file(const char *fn){    char *data;    data = read_file(fn, 0);    if (!data) return -1;    parse_config(fn, data);    DUMP();    return 0;}static int valid_name(const char *name){    if (strlen(name) > 16) {        return 0;    }    while (*name) {        if (!isalnum(*name) && (*name != '_') && (*name != '-')) {            return 0;        }        name++;    }    return 1;}struct service *service_find_by_name(const char *name){    struct listnode *node;    struct service *svc;    list_for_each(node, &service_list) {        svc = node_to_item(node, struct service, slist);        if (!strcmp(svc->name, name)) {            return svc;        }    }    return 0;}struct service *service_find_by_pid(pid_t pid){    struct listnode *node;    struct service *svc;    list_for_each(node, &service_list) {        svc = node_to_item(node, struct service, slist);        if (svc->pid == pid) {            return svc;        }    }    return 0;}void service_for_each_class(const char *classname,                            void (*func)(struct service *svc)){    struct listnode *node;    struct service *svc;    list_for_each(node, &service_list) {        svc = node_to_item(node, struct service, slist);        if (!strcmp(svc->classname, classname)) {            func(svc);        }    }}void service_for_each_flags(unsigned matchflags,                            void (*func)(struct service *svc)){    struct listnode *node;    struct service *svc;    list_for_each(node, &service_list) {        svc = node_to_item(node, struct service, slist);        if (svc->flags & matchflags) {            func(svc);        }    }}void action_for_each_trigger(const char *trigger,                             void (*func)(struct action *act)){    struct listnode *node;    struct action *act;    list_for_each(node, &action_list) {        act = node_to_item(node, struct action, alist);        if (!strcmp(act->name, trigger)) {            func(act);        }    }}void queue_property_triggers(const char *name, const char *value){    struct listnode *node;    struct action *act;    list_for_each(node, &action_list) {        act = node_to_item(node, struct action, alist);        if (!strncmp(act->name, "property:", strlen("property:"))) {            const char *test = act->name + strlen("property:");            int name_length = strlen(name);                        if (!strncmp(name, test, name_length) &&                     test[name_length] == '=' &&                    !strcmp(test + name_length + 1, value)) {                action_add_queue_tail(act);            }        }    }}void queue_all_property_triggers(){    struct listnode *node;    struct action *act;    list_for_each(node, &action_list) {        act = node_to_item(node, struct action, alist);        if (!strncmp(act->name, "property:", strlen("property:"))) {            /* parse property name and value               syntax is property:<name>=<value> */            const char* name = act->name + strlen("property:");            const char* equals = strchr(name, '=');            if (equals) {                char* prop_name[PROP_NAME_MAX + 1];                const char* value;                int length = equals - name;                if (length > PROP_NAME_MAX) {                    ERROR("property name too long in trigger %s", act->name);                } else {                    memcpy(prop_name, name, length);                    prop_name[length] = 0;                                        /* does the property exist, and match the trigger value? */                    value = property_get((const char *)&prop_name[0]);                    if (value && !strcmp(equals + 1, value)) {                        action_add_queue_tail(act);                    }                }            }        }    }}void action_add_queue_tail(struct action *act){    list_add_tail(&action_queue, &act->qlist);}struct action *action_remove_queue_head(void){    if (list_empty(&action_queue)) {        return 0;    } else {        struct listnode *node = list_head(&action_queue);        struct action *act = node_to_item(node, struct action, qlist);        list_remove(node);        return act;    }}static void *parse_service(struct parse_state *state, int nargs, char **args){    struct service *svc;    if (nargs < 3) {        parse_error(state, "services must have a name and a program\n");        return 0;    }    if (!valid_name(args[1])) {        parse_error(state, "invalid service name '%s'\n", args[1]);        return 0;    }    svc = service_find_by_name(args[1]);    if (svc) {        parse_error(state, "ignored duplicate definition of service '%s'\n", args[1]);        return 0;    }        nargs -= 2;    svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs);    if (!svc) {        parse_error(state, "out of memory\n");        return 0;    }    svc->name = args[1];    svc->classname = "default";    memcpy(svc->args, args + 2, sizeof(char*) * nargs);    svc->args[nargs] = 0;    svc->nargs = nargs;    svc->onrestart.name = "onrestart";    list_init(&svc->onrestart.commands);    list_add_tail(&service_list, &svc->slist);    return svc;}static void parse_line_service(struct parse_state *state, int nargs, char **args){    struct service *svc = state->context;    struct command *cmd;    int kw, kw_nargs;    if (nargs == 0) {        return;    }        kw = lookup_keyword(args[0]);    switch (kw) {    case K_capability:        break;    case K_class:        if (nargs != 2) {            parse_error(state, "class option requires a classname\n");        } else {            svc->classname = args[1];        }        break;    case K_console:        svc->flags |= SVC_CONSOLE;        break;    case K_disabled:        svc->flags |= SVC_DISABLED;        break;    case K_group:        if (nargs < 2) {            parse_error(state, "group option requires a group id\n");        } else if (nargs > NR_SVC_SUPP_GIDS + 2) {            parse_error(state, "group option accepts at most %d supp. groups\n",                        NR_SVC_SUPP_GIDS);        } else {            int n;            svc->gid = decode_uid(args[1]);            for (n = 2; n < nargs; n++) {                svc->supp_gids[n-2] = decode_uid(args[n]);            }            svc->nr_supp_gids = n - 2;        }        break;    case K_oneshot:        svc->flags |= SVC_ONESHOT;        break;    case K_onrestart:        nargs--;        args++;        kw = lookup_keyword(args[0]);        if (!kw_is(kw, COMMAND)) {            parse_error(state, "invalid command '%s'\n", args[0]);            break;        }        kw_nargs = kw_nargs(kw);        if (nargs < kw_nargs) {            parse_error(state, "%s requires %d %s\n", args[0], kw_nargs - 1,                kw_nargs > 2 ? "arguments" : "argument");            break;        }        cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs);        cmd->func = kw_func(kw);        cmd->nargs = nargs;        memcpy(cmd->args, args, sizeof(char*) * nargs);        list_add_tail(&svc->onrestart.commands, &cmd->clist);        break;    case K_critical:        svc->flags |= SVC_CRITICAL;        break;    case K_setenv: { /* name value */        struct svcenvinfo *ei;        if (nargs < 2) {            parse_error(state, "setenv option requires name and value arguments\n");            break;        }        ei = calloc(1, sizeof(*ei));        if (!ei) {            parse_error(state, "out of memory\n");            break;        }        ei->name = args[1];        ei->value = args[2];        ei->next = svc->envvars;        svc->envvars = ei;        break;    }    case K_socket: {/* name type perm [ uid gid ] */        struct socketinfo *si;        if (nargs < 4) {            parse_error(state, "socket option requires name, type, perm arguments\n");            break;        }        if (strcmp(args[2],"dgram") && strcmp(args[2],"stream")) {            parse_error(state, "socket type must be 'dgram' or 'stream'\n");            break;        }        si = calloc(1, sizeof(*si));        if (!si) {            parse_error(state, "out of memory\n");            break;        }        si->name = args[1];        si->type = args[2];        si->perm = strtoul(args[3], 0, 8);        if (nargs > 4)            si->uid = decode_uid(args[4]);        if (nargs > 5)            si->gid = decode_uid(args[5]);        si->next = svc->sockets;        svc->sockets = si;        break;    }    case K_user:        if (nargs != 2) {            parse_error(state, "user option requires a user id\n");        } else {            svc->uid = decode_uid(args[1]);        }        break;    default:        parse_error(state, "invalid option '%s'\n", args[0]);    }}static void *parse_action(struct parse_state *state, int nargs, char **args){    struct action *act;    if (nargs < 2) {        parse_error(state, "actions must have a trigger\n");        return 0;    }    if (nargs > 2) {        parse_error(state, "actions may not have extra parameters\n");        return 0;    }    act = calloc(1, sizeof(*act));    act->name = args[1];    list_init(&act->commands);    list_add_tail(&action_list, &act->alist);        /* XXX add to hash */    return act;}static void parse_line_action(struct parse_state* state, int nargs, char **args){    struct command *cmd;    struct action *act = state->context;    int (*func)(int nargs, char **args);    int kw, n;    if (nargs == 0) {        return;    }    kw = lookup_keyword(args[0]);    if (!kw_is(kw, COMMAND)) {        parse_error(state, "invalid command '%s'\n", args[0]);        return;    }    n = kw_nargs(kw);    if (nargs < n) {        parse_error(state, "%s requires %d %s\n", args[0], n - 1,            n > 2 ? "arguments" : "argument");        return;    }    cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs);    cmd->func = kw_func(kw);    cmd->nargs = nargs;    memcpy(cmd->args, args, sizeof(char*) * nargs);    list_add_tail(&act->commands, &cmd->clist);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -