]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/io/usb/slave/v2_0/host/usbchmod.c
Initial revision
[karo-tx-redboot.git] / packages / io / usb / slave / v2_0 / host / usbchmod.c
1 //=================================================================
2 //
3 //        usb_chmod.c
4 //
5 //        A utility to manipulate /proc/bus/usb access rights
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // The Linux kernel allows raw access to USB devices via /proc/bus/usb.
44 // However, such access requires root privileges: this makes perfect
45 // sense for typical USB devices, but gets in the way of eCos USB
46 // testing. This utility runs suid and can be used to change the access
47 // rights to a specific and validated USB device.
48 //
49 // Author(s):     bartv
50 // Date:          2001-07-18
51 //####DESCRIPTIONEND####
52 //==========================================================================
53
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <limits.h>
57 #include <sys/types.h>
58 #include <sys/stat.h>
59 #include <errno.h>
60
61 // Note: this code is duplicated in usbhost.c. Any changes here
62 // should be propagated. For now the routine is too small to warrant
63 // a separate source file.
64 #define USB_ROOT        "/proc/bus/usb/"
65 #define PRODUCT_STRING  "Red Hat eCos USB test"
66
67 static int
68 usb_scan_devices(int* bus, int* dev)
69 {
70     FILE*       devs_file       = fopen(USB_ROOT "devices", "r");
71     int         current_bus     = -1;
72     int         current_dev     = -1;
73     int         ch;
74     
75     if (NULL == devs_file) {
76         fprintf(stderr, "Error: unable to access " USB_ROOT "devices\n");
77         return 0;
78     }
79     ch = getc(devs_file);
80     while (EOF != ch) {
81         if ('T' == ch) {
82             if (2 !=fscanf(devs_file, ":  Bus=%d %*[^D\n]Dev#=%d", &current_bus, &current_dev)) { 
83                 current_bus = -1;
84                 current_dev = -1;
85             }
86         } else if ('S' == ch) {
87             int start = 0, end = 0;
88             if (EOF != fscanf(devs_file, ":  Product=%n" PRODUCT_STRING "%n", &start, &end)) {
89                 if (start < end) {
90                     *bus = current_bus;
91                     *dev = current_dev;
92                     break;
93                 }
94             } 
95         }
96         // Move to the end of the current line.
97         do {
98             ch = getc(devs_file);
99         } while ((EOF != ch) && ('\n' != ch));
100         if (EOF != ch) {
101             ch = getc(devs_file);
102         }
103     }
104     
105     fclose(devs_file);
106     if ((-1 != *bus) && (-1 != *dev)) {
107         return 1;
108     }
109     fprintf(stderr, "Error: failed to find a USB device \"" PRODUCT_STRING "\"\n");
110     return 0;
111 }
112
113 int
114 main(int argc, char** argv)
115 {
116     int         bus, dev;
117     int         actual_bus, actual_dev;
118     char        devname[_POSIX_PATH_MAX];
119     long        strtol_tmp1;
120     char*       strtol_tmp2;
121     
122     if (3 != argc) {
123         fprintf(stderr, "usb_chmod: wrong number of arguments\n");
124         fprintf(stderr, "         : usage, usb_chmod <bus> <dev>\n");
125         exit(EXIT_FAILURE);
126     }
127     if (('\0' == argv[1][0]) || ('\0' == argv[2][0])) {
128         fprintf(stderr, "usb_chmod: invalid arguments\n");
129         exit(EXIT_FAILURE);
130     }
131                                  
132     strtol_tmp1 = strtol(argv[1], &strtol_tmp2, 10);
133     if ('\0' != *strtol_tmp2) {
134         fprintf(stderr, "usbchmod: invalid first argument, not a number\n");
135         exit(EXIT_FAILURE);
136     }
137     if (strtol_tmp1 > INT_MAX) {
138         fprintf(stderr, "usbchmod: invalid first argument, number too large\n");
139         exit(EXIT_FAILURE);
140     }
141     bus = (int) strtol_tmp1;
142
143     strtol_tmp1 = strtol(argv[2], &strtol_tmp2, 10);
144     if ('\0' != *strtol_tmp2) {
145         fprintf(stderr, "usbchmod: invalid second argument, not a number\n");
146         exit(EXIT_FAILURE);
147     }
148     if (strtol_tmp1 > INT_MAX) {
149         fprintf(stderr, "usbchmod: invalid second argument, number too large\n");
150         exit(EXIT_FAILURE);
151     }
152     dev = (int) strtol_tmp1;
153         
154     if (!usb_scan_devices(&actual_bus, &actual_dev)) {
155         fprintf(stderr, "usb_chmod: failed to find eCos USB test application\n");
156         exit(EXIT_FAILURE);
157     }
158     if ((bus != actual_bus) || (dev != actual_dev)) {
159         fprintf(stderr, "usbchmod: mismatch between specified and actual USB identifiers.\n");
160         fprintf(stderr, "         : eCos test application is at %03d/%03d, not %03d/%03d\n",
161                 actual_bus, actual_dev, bus, dev);
162         exit(EXIT_FAILURE);
163     }
164     
165     if (_POSIX_PATH_MAX == snprintf(devname, _POSIX_PATH_MAX, "/proc/bus/usb/" "%03d/%03d", actual_bus, actual_dev)) {
166         fprintf(stderr, "usbchmod: internal error, buffer overflow\n");
167         exit(EXIT_FAILURE);
168     }
169
170     if (0 != chmod(devname, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) {
171         int old_errno = errno;
172         fprintf(stderr, "usbchmod: failed to modify access rights on %s\n", devname);
173         if ((old_errno >= 0) && (old_errno < sys_nerr)) {
174             fprintf(stderr, "         : %s\n", sys_errlist[old_errno]);
175         }
176         exit(EXIT_FAILURE);
177     }
178
179     return EXIT_SUCCESS;
180 }