199ca880aSopenharmony_ci/***
299ca880aSopenharmony_ci  This file is part of systemd.
399ca880aSopenharmony_ci
499ca880aSopenharmony_ci  Copyright 2007-2012 Kay Sievers <kay@vrfy.org>
599ca880aSopenharmony_ci
699ca880aSopenharmony_ci  systemd is free software; you can redistribute it and/or modify it
799ca880aSopenharmony_ci  under the terms of the GNU Lesser General Public License as published by
899ca880aSopenharmony_ci  the Free Software Foundation; either version 2.1 of the License, or
999ca880aSopenharmony_ci  (at your option) any later version.
1099ca880aSopenharmony_ci
1199ca880aSopenharmony_ci  systemd is distributed in the hope that it will be useful, but
1299ca880aSopenharmony_ci  WITHOUT ANY WARRANTY; without even the implied warranty of
1399ca880aSopenharmony_ci  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1499ca880aSopenharmony_ci  Lesser General Public License for more details.
1599ca880aSopenharmony_ci
1699ca880aSopenharmony_ci  You should have received a copy of the GNU Lesser General Public License
1799ca880aSopenharmony_ci  along with systemd; If not, see <http://www.gnu.org/licenses/>.
1899ca880aSopenharmony_ci***/
1999ca880aSopenharmony_ci
2099ca880aSopenharmony_ci#include <unistd.h>
2199ca880aSopenharmony_ci#include <stdio.h>
2299ca880aSopenharmony_ci#include <stdlib.h>
2399ca880aSopenharmony_ci#include <stddef.h>
2499ca880aSopenharmony_ci#include <string.h>
2599ca880aSopenharmony_ci#include <errno.h>
2699ca880aSopenharmony_ci#include <getopt.h>
2799ca880aSopenharmony_ci
2899ca880aSopenharmony_ci#include "udev.h"
2999ca880aSopenharmony_ci
3099ca880aSopenharmony_cistatic bool initialized;
3199ca880aSopenharmony_ci
3299ca880aSopenharmony_cistatic const struct udev_builtin *builtins[] = {
3399ca880aSopenharmony_ci#ifdef HAVE_BLKID
3499ca880aSopenharmony_ci        [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid,
3599ca880aSopenharmony_ci#endif
3699ca880aSopenharmony_ci        [UDEV_BUILTIN_BTRFS] = &udev_builtin_btrfs,
3799ca880aSopenharmony_ci        [UDEV_BUILTIN_HWDB] = &udev_builtin_hwdb,
3899ca880aSopenharmony_ci        [UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id,
3999ca880aSopenharmony_ci        [UDEV_BUILTIN_KEYBOARD] = &udev_builtin_keyboard,
4099ca880aSopenharmony_ci#ifdef HAVE_KMOD
4199ca880aSopenharmony_ci        [UDEV_BUILTIN_KMOD] = &udev_builtin_kmod,
4299ca880aSopenharmony_ci#endif
4399ca880aSopenharmony_ci        [UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id,
4499ca880aSopenharmony_ci        [UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id,
4599ca880aSopenharmony_ci        [UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id,
4699ca880aSopenharmony_ci};
4799ca880aSopenharmony_ci
4899ca880aSopenharmony_civoid udev_builtin_init(struct udev *udev) {
4999ca880aSopenharmony_ci        unsigned int i;
5099ca880aSopenharmony_ci
5199ca880aSopenharmony_ci        if (initialized)
5299ca880aSopenharmony_ci                return;
5399ca880aSopenharmony_ci
5499ca880aSopenharmony_ci        for (i = 0; i < ELEMENTSOF(builtins); i++)
5599ca880aSopenharmony_ci                if (builtins[i]->init)
5699ca880aSopenharmony_ci                        builtins[i]->init(udev);
5799ca880aSopenharmony_ci
5899ca880aSopenharmony_ci        initialized = true;
5999ca880aSopenharmony_ci}
6099ca880aSopenharmony_ci
6199ca880aSopenharmony_civoid udev_builtin_exit(struct udev *udev) {
6299ca880aSopenharmony_ci        unsigned int i;
6399ca880aSopenharmony_ci
6499ca880aSopenharmony_ci        if (!initialized)
6599ca880aSopenharmony_ci                return;
6699ca880aSopenharmony_ci
6799ca880aSopenharmony_ci        for (i = 0; i < ELEMENTSOF(builtins); i++)
6899ca880aSopenharmony_ci                if (builtins[i]->exit)
6999ca880aSopenharmony_ci                        builtins[i]->exit(udev);
7099ca880aSopenharmony_ci
7199ca880aSopenharmony_ci        initialized = false;
7299ca880aSopenharmony_ci}
7399ca880aSopenharmony_ci
7499ca880aSopenharmony_cibool udev_builtin_validate(struct udev *udev) {
7599ca880aSopenharmony_ci        unsigned int i;
7699ca880aSopenharmony_ci
7799ca880aSopenharmony_ci        for (i = 0; i < ELEMENTSOF(builtins); i++)
7899ca880aSopenharmony_ci                if (builtins[i]->validate && builtins[i]->validate(udev))
7999ca880aSopenharmony_ci                        return true;
8099ca880aSopenharmony_ci        return false;
8199ca880aSopenharmony_ci}
8299ca880aSopenharmony_ci
8399ca880aSopenharmony_civoid udev_builtin_list(struct udev *udev) {
8499ca880aSopenharmony_ci        unsigned int i;
8599ca880aSopenharmony_ci
8699ca880aSopenharmony_ci        for (i = 0; i < ELEMENTSOF(builtins); i++)
8799ca880aSopenharmony_ci                fprintf(stderr, "  %-14s  %s\n", builtins[i]->name, builtins[i]->help);
8899ca880aSopenharmony_ci}
8999ca880aSopenharmony_ci
9099ca880aSopenharmony_ciconst char *udev_builtin_name(enum udev_builtin_cmd cmd) {
9199ca880aSopenharmony_ci        return builtins[cmd]->name;
9299ca880aSopenharmony_ci}
9399ca880aSopenharmony_ci
9499ca880aSopenharmony_cibool udev_builtin_run_once(enum udev_builtin_cmd cmd) {
9599ca880aSopenharmony_ci        return builtins[cmd]->run_once;
9699ca880aSopenharmony_ci}
9799ca880aSopenharmony_ci
9899ca880aSopenharmony_cienum udev_builtin_cmd udev_builtin_lookup(const char *command) {
9999ca880aSopenharmony_ci        char name[UTIL_PATH_SIZE];
10099ca880aSopenharmony_ci        enum udev_builtin_cmd i;
10199ca880aSopenharmony_ci        char *pos;
10299ca880aSopenharmony_ci
10399ca880aSopenharmony_ci        strscpy(name, sizeof(name), command);
10499ca880aSopenharmony_ci        pos = strchr(name, ' ');
10599ca880aSopenharmony_ci        if (pos)
10699ca880aSopenharmony_ci                pos[0] = '\0';
10799ca880aSopenharmony_ci        for (i = 0; i < ELEMENTSOF(builtins); i++)
10899ca880aSopenharmony_ci                if (streq(builtins[i]->name, name))
10999ca880aSopenharmony_ci                        return i;
11099ca880aSopenharmony_ci        return UDEV_BUILTIN_MAX;
11199ca880aSopenharmony_ci}
11299ca880aSopenharmony_ci
11399ca880aSopenharmony_ciint udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test) {
11499ca880aSopenharmony_ci        char arg[UTIL_PATH_SIZE];
11599ca880aSopenharmony_ci        int argc;
11699ca880aSopenharmony_ci        char *argv[128];
11799ca880aSopenharmony_ci
11899ca880aSopenharmony_ci        /* we need '0' here to reset the internal state */
11999ca880aSopenharmony_ci        optind = 0;
12099ca880aSopenharmony_ci        strscpy(arg, sizeof(arg), command);
12199ca880aSopenharmony_ci        udev_build_argv(udev_device_get_udev(dev), arg, &argc, argv);
12299ca880aSopenharmony_ci        return builtins[cmd]->cmd(dev, argc, argv, test);
12399ca880aSopenharmony_ci}
12499ca880aSopenharmony_ci
12599ca880aSopenharmony_ciint udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val) {
12699ca880aSopenharmony_ci        udev_device_add_property(dev, key, val);
12799ca880aSopenharmony_ci
12899ca880aSopenharmony_ci        if (test)
12999ca880aSopenharmony_ci                printf("%s=%s\n", key, val);
13099ca880aSopenharmony_ci        return 0;
13199ca880aSopenharmony_ci}
132