1/* 2 * Copyright (C) 2011 Kay Sievers <kay@vrfy.org> 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18#include <stdlib.h> 19#include <stddef.h> 20#include <string.h> 21#include <stdio.h> 22#include <unistd.h> 23#include <errno.h> 24#include <dirent.h> 25#include <fcntl.h> 26#include <getopt.h> 27#include <signal.h> 28#include <time.h> 29#include <sys/inotify.h> 30#include <poll.h> 31#include <sys/stat.h> 32#include <sys/types.h> 33 34#include "udev.h" 35 36static void help(struct udev *udev) { 37 printf("%s builtin [--help] COMMAND SYSPATH\n\n" 38 "Test a built-in command.\n\n" 39 " -h --help Print this message\n" 40 " --version Print version of the program\n\n" 41 "Commands:\n" 42 , program_invocation_short_name); 43 44 udev_builtin_list(udev); 45} 46 47static int adm_builtin(struct udev *udev, int argc, char *argv[]) { 48 static const struct option options[] = { 49 { "help", no_argument, NULL, 'h' }, 50 {} 51 }; 52 char *command = NULL; 53 char *syspath = NULL; 54 char filename[UTIL_PATH_SIZE]; 55 struct udev_device *dev = NULL; 56 enum udev_builtin_cmd cmd; 57 int rc = EXIT_SUCCESS, c; 58 59 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) 60 switch (c) { 61 case 'h': 62 help(udev); 63 goto out; 64 } 65 66 command = argv[optind++]; 67 if (command == NULL) { 68 fprintf(stderr, "command missing\n"); 69 help(udev); 70 rc = 2; 71 goto out; 72 } 73 74 syspath = argv[optind++]; 75 if (syspath == NULL) { 76 fprintf(stderr, "syspath missing\n"); 77 rc = 3; 78 goto out; 79 } 80 81 udev_builtin_init(udev); 82 83 cmd = udev_builtin_lookup(command); 84 if (cmd >= UDEV_BUILTIN_MAX) { 85 fprintf(stderr, "unknown command '%s'\n", command); 86 help(udev); 87 rc = 5; 88 goto out; 89 } 90 91 /* add /sys if needed */ 92 if (!startswith(syspath, "/sys")) 93 strscpyl(filename, sizeof(filename), "/sys", syspath, NULL); 94 else 95 strscpy(filename, sizeof(filename), syspath); 96 util_remove_trailing_chars(filename, '/'); 97 98 dev = udev_device_new_from_syspath(udev, filename); 99 if (dev == NULL) { 100 fprintf(stderr, "unable to open device '%s'\n\n", filename); 101 rc = 4; 102 goto out; 103 } 104 105 rc = udev_builtin_run(dev, cmd, command, true); 106 if (rc < 0) { 107 fprintf(stderr, "error executing '%s', exit code %i\n\n", command, rc); 108 rc = 6; 109 } 110out: 111 udev_device_unref(dev); 112 udev_builtin_exit(udev); 113 return rc; 114} 115 116const struct udevadm_cmd udevadm_test_builtin = { 117 .name = "test-builtin", 118 .cmd = adm_builtin, 119 .help = "Test a built-in command", 120 .debug = true, 121}; 122