1 /*
2  * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
3  *               2005-2007 Takahiro Hirofuchi
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <sysfs/libsysfs.h>
20 
21 #include <ctype.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include <getopt.h>
28 #include <unistd.h>
29 
30 #include "vhci_driver.h"
31 #include "usbip_common.h"
32 #include "usbip_network.h"
33 #include "usbip.h"
34 
35 static const char usbip_detach_usage_string[] =
36 	"usbip detach <args>\n"
37 	"    -p, --port=<port>    " USBIP_VHCI_DRV_NAME
38 	" port the device is on\n";
39 
usbip_detach_usage(void)40 void usbip_detach_usage(void)
41 {
42 	printf("usage: %s", usbip_detach_usage_string);
43 }
44 
detach_port(char * port)45 static int detach_port(char *port)
46 {
47 	int ret;
48 	uint8_t portnum;
49 
50 	for (unsigned int i=0; i < strlen(port); i++)
51 		if (!isdigit(port[i])) {
52 			err("invalid port %s", port);
53 			return -1;
54 		}
55 
56 	/* check max port */
57 
58 	portnum = atoi(port);
59 
60 	ret = usbip_vhci_driver_open();
61 	if (ret < 0) {
62 		err("open vhci_driver");
63 		return -1;
64 	}
65 
66 	ret = usbip_vhci_detach_device(portnum);
67 	if (ret < 0)
68 		return -1;
69 
70 	usbip_vhci_driver_close();
71 
72 	return ret;
73 }
74 
usbip_detach(int argc,char * argv[])75 int usbip_detach(int argc, char *argv[])
76 {
77 	static const struct option opts[] = {
78 		{ "port", required_argument, NULL, 'p' },
79 		{ NULL, 0, NULL, 0 }
80 	};
81 	int opt;
82 	int ret = -1;
83 
84 	for (;;) {
85 		opt = getopt_long(argc, argv, "p:", opts, NULL);
86 
87 		if (opt == -1)
88 			break;
89 
90 		switch (opt) {
91 		case 'p':
92 			ret = detach_port(optarg);
93 			goto out;
94 		default:
95 			goto err_out;
96 		}
97 	}
98 
99 err_out:
100 	usbip_detach_usage();
101 out:
102 	return ret;
103 }
104