tizen 2.4 release
[framework/system/usbutils.git] / usbmisc.c
1 /*****************************************************************************/
2 /*
3  *      usbmisc.c  --  Misc USB routines
4  *
5  *      Copyright (C) 2003  Aurelien Jarno (aurelien@aurel32.net)
6  *
7  *      This program is free software; you can redistribute it and/or modify
8  *      it under the terms of the GNU General Public License as published by
9  *      the Free Software Foundation; either version 2 of the License, or
10  *      (at your option) any later version.
11  *
12  *      This program is distributed in the hope that it will be useful,
13  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *      GNU General Public License for more details.
16  *
17  *      You should have received a copy of the GNU General Public License
18  *      along with this program; if not, write to the Free Software
19  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  *
22  */
23
24 /*****************************************************************************/
25
26 #include <stdio.h>
27 #include <string.h>
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "usbmisc.h"
34
35 /* ---------------------------------------------------------------------- */
36
37 static const char *devbususb = "/dev/bus/usb";
38
39 /* ---------------------------------------------------------------------- */
40
41 static int readlink_recursive(const char *path, char *buf, size_t bufsize)
42 {
43         char temp[PATH_MAX + 1];
44         char *ptemp;
45         int ret;
46
47         ret = readlink(path, buf, bufsize);
48
49         if (ret > 0) {
50                 buf[ret] = 0;
51                 if (*buf != '/')
52                 {
53                         strncpy(temp, path, sizeof(temp));
54                         ptemp = temp + strlen(temp);
55                         while (*ptemp != '/' && ptemp != temp) ptemp--;
56                         ptemp++;
57                         strncpy(ptemp, buf, bufsize + temp - ptemp);
58                 }
59                 else
60                         strncpy(temp, buf, sizeof(temp));
61                 return readlink_recursive(temp, buf, bufsize);
62         }
63         else {
64                 strncpy(buf, path, bufsize);
65                 return strlen(buf);
66         }
67 }
68
69 static char *get_absolute_path(const char *path, char *result, size_t result_size)
70 {
71         const char *ppath;      /* pointer on the input string */
72         char *presult;          /* pointer on the output string */
73
74         ppath = path;
75         presult = result;
76         result[0] = 0;
77
78         if (path == NULL)
79                 return result;
80
81         if (*ppath != '/') {
82                 result = getcwd(result, result_size);
83                 presult += strlen(result);
84                 result_size -= strlen(result);
85
86                 *presult++ = '/';
87                 result_size--;
88         }
89
90         while (*ppath != 0 && result_size > 1) {
91                 if (*ppath == '/') {
92                         do ppath++; while (*ppath == '/');
93                         *presult++ = '/';
94                         result_size--;
95                 }
96                 else if (*ppath == '.' && *(ppath + 1) == '.' && *(ppath + 2) == '/' && *(presult - 1) == '/') {
97                         if ((presult - 1) != result)
98                         {
99                                 /* go one directory upper */
100                                 do {
101                                         presult--;
102                                         result_size++;
103                                 } while (*(presult - 1) != '/');
104                         }
105                         ppath += 3;
106                 }
107                 else if (*ppath == '.'  && *(ppath + 1) == '/' && *(presult - 1) == '/') {
108                         ppath += 2;
109                 }
110                 else {
111                         *presult++ = *ppath++;
112                         result_size--;
113                 }
114         }
115         /* Don't forget to mark the end of the string! */
116         *presult = 0;
117         
118         return result;
119 }       
120
121 struct usb_device *get_usb_device(const char *path)
122 {
123         struct usb_bus *bus;
124         struct usb_device *dev;
125         char device_path[PATH_MAX + 1];
126         char absolute_path[PATH_MAX + 1];
127
128         readlink_recursive(path, device_path, sizeof(device_path));
129         get_absolute_path(device_path, absolute_path, sizeof(absolute_path));
130         
131         for (bus = usb_busses; bus; bus = bus->next) {
132                 for (dev = bus->devices; dev; dev = dev->next) {
133                         snprintf(device_path, sizeof(device_path), "%s/%s/%s", devbususb, bus->dirname, dev->filename);
134                         if (!strcmp(device_path, absolute_path))
135                                 return dev;
136                 }                               
137         }                       
138         return NULL;
139 }       
140