1 /* 2 * command structure borrowed from udev 3 * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git) 4 * 5 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> 6 * 2005-2007 Takahiro Hirofuchi 7 * 8 * This program is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation, either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 25 #include <getopt.h> 26 #include <syslog.h> 27 28 #include "usbip_common.h" 29 #include "usbip_network.h" 30 #include "usbip.h" 31 32 static int usbip_help(int argc, char *argv[]); 33 static int usbip_version(int argc, char *argv[]); 34 35 static const char usbip_version_string[] = PACKAGE_STRING; 36 37 static const char usbip_usage_string[] = 38 "usbip [--debug] [--log] [--tcp-port PORT] [version]\n" 39 " [help] <command> <args>\n"; 40 41 static void usbip_usage(void) 42 { 43 printf("usage: %s", usbip_usage_string); 44 } 45 46 struct command { 47 const char *name; 48 int (*fn)(int argc, char *argv[]); 49 const char *help; 50 void (*usage)(void); 51 }; 52 53 static const struct command cmds[] = { 54 { 55 .name = "help", 56 .fn = usbip_help, 57 .help = NULL, 58 .usage = NULL 59 }, 60 { 61 .name = "version", 62 .fn = usbip_version, 63 .help = NULL, 64 .usage = NULL 65 }, 66 { 67 .name = "attach", 68 .fn = usbip_attach, 69 .help = "Attach a remote USB device", 70 .usage = usbip_attach_usage 71 }, 72 { 73 .name = "detach", 74 .fn = usbip_detach, 75 .help = "Detach a remote USB device", 76 .usage = usbip_detach_usage 77 }, 78 { 79 .name = "list", 80 .fn = usbip_list, 81 .help = "List exportable or local USB devices", 82 .usage = usbip_list_usage 83 }, 84 { 85 .name = "bind", 86 .fn = usbip_bind, 87 .help = "Bind device to " USBIP_HOST_DRV_NAME ".ko", 88 .usage = usbip_bind_usage 89 }, 90 { 91 .name = "unbind", 92 .fn = usbip_unbind, 93 .help = "Unbind device from " USBIP_HOST_DRV_NAME ".ko", 94 .usage = usbip_unbind_usage 95 }, 96 { 97 .name = "port", 98 .fn = usbip_port_show, 99 .help = "Show imported USB devices", 100 .usage = NULL 101 }, 102 { NULL, NULL, NULL, NULL } 103 }; 104 105 static int usbip_help(int argc, char *argv[]) 106 { 107 const struct command *cmd; 108 int i; 109 int ret = 0; 110 111 if (argc > 1 && argv++) { 112 for (i = 0; cmds[i].name != NULL; i++) 113 if (!strcmp(cmds[i].name, argv[0]) && cmds[i].usage) { 114 cmds[i].usage(); 115 goto done; 116 } 117 ret = -1; 118 } 119 120 usbip_usage(); 121 printf("\n"); 122 for (cmd = cmds; cmd->name != NULL; cmd++) 123 if (cmd->help != NULL) 124 printf(" %-10s %s\n", cmd->name, cmd->help); 125 printf("\n"); 126 done: 127 return ret; 128 } 129 130 static int usbip_version(int argc, char *argv[]) 131 { 132 (void) argc; 133 (void) argv; 134 135 printf(PROGNAME " (%s)\n", usbip_version_string); 136 return 0; 137 } 138 139 static int run_command(const struct command *cmd, int argc, char *argv[]) 140 { 141 dbg("running command: `%s'", cmd->name); 142 return cmd->fn(argc, argv); 143 } 144 145 int main(int argc, char *argv[]) 146 { 147 static const struct option opts[] = { 148 { "debug", no_argument, NULL, 'd' }, 149 { "log", no_argument, NULL, 'l' }, 150 { "tcp-port", required_argument, NULL, 't' }, 151 { NULL, 0, NULL, 0 } 152 }; 153 154 char *cmd; 155 int opt; 156 int i, rc = -1; 157 158 usbip_use_stderr = 1; 159 opterr = 0; 160 for (;;) { 161 opt = getopt_long(argc, argv, "+dlt:", opts, NULL); 162 163 if (opt == -1) 164 break; 165 166 switch (opt) { 167 case 'd': 168 usbip_use_debug = 1; 169 break; 170 case 'l': 171 usbip_use_syslog = 1; 172 openlog("", LOG_PID, LOG_USER); 173 break; 174 case 't': 175 usbip_setup_port_number(optarg); 176 break; 177 case '?': 178 printf("usbip: invalid option\n"); 179 /* Terminate after printing error */ 180 /* FALLTHRU */ 181 default: 182 usbip_usage(); 183 goto out; 184 } 185 } 186 187 cmd = argv[optind]; 188 if (cmd) { 189 for (i = 0; cmds[i].name != NULL; i++) 190 if (!strcmp(cmds[i].name, cmd)) { 191 argc -= optind; 192 argv += optind; 193 optind = 0; 194 rc = run_command(&cmds[i], argc, argv); 195 goto out; 196 } 197 } 198 199 /* invalid command */ 200 usbip_help(0, NULL); 201 out: 202 return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE); 203 } 204