xref: /linux/tools/usb/usbip/src/usbip.c (revision 848298c6fb36fbe459854e376ce90af32ba6e1ce)
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 		default:
180 			usbip_usage();
181 			goto out;
182 		}
183 	}
184 
185 	cmd = argv[optind];
186 	if (cmd) {
187 		for (i = 0; cmds[i].name != NULL; i++)
188 			if (!strcmp(cmds[i].name, cmd)) {
189 				argc -= optind;
190 				argv += optind;
191 				optind = 0;
192 				rc = run_command(&cmds[i], argc, argv);
193 				goto out;
194 			}
195 	}
196 
197 	/* invalid command */
198 	usbip_help(0, NULL);
199 out:
200 	return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE);
201 }
202