Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * derived from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 : #include "giofuncP.h"
28 : #include "gfile.h"
29 : #include "ustring.h"
30 : #include "utype.h"
31 :
32 : #if !defined(__MINGW32__)
33 : #include <netdb.h>
34 : #endif
35 :
36 0 : char *_GIO_decomposeURL(const unichar_t *url,char **host, int *port, char **username,
37 : char **password) {
38 : unichar_t *pt, *pt2, *upt, *ppt;
39 : char *path;
40 : char proto[40];
41 : /* ftp://[user[:password]@]ftpserver[:port]/url-path */
42 :
43 0 : *username = NULL; *password = NULL; *port = -1;
44 0 : pt = uc_strstr(url,"://");
45 0 : if ( pt==NULL ) {
46 0 : *host = NULL;
47 0 : return( cu_copy(url));
48 : }
49 0 : cu_strncpy(proto,url,(size_t)(pt-url)<sizeof(proto)?(size_t)(pt-url):sizeof(proto));
50 0 : pt += 3;
51 :
52 0 : pt2 = u_strchr(pt,'/');
53 0 : if ( pt2==NULL ) {
54 0 : pt2 = pt+u_strlen(pt);
55 0 : path = copy("/");
56 : } else {
57 0 : path = cu_copy(pt2);
58 : }
59 :
60 0 : upt = u_strchr(pt,'@');
61 0 : if ( upt!=NULL && upt<pt2 ) {
62 0 : ppt = u_strchr(pt,':');
63 0 : if ( ppt==NULL )
64 0 : *username = cu_copyn(pt,upt-pt);
65 : else {
66 0 : *username = cu_copyn(pt,ppt-pt);
67 0 : *password = cu_copyn(ppt+1,upt-ppt-1);
68 : }
69 0 : pt = upt+1;
70 : }
71 :
72 0 : ppt = u_strchr(pt,':');
73 0 : if ( ppt!=NULL && ppt<pt2 ) {
74 0 : char *temp = cu_copyn(ppt+1,pt2-ppt-1), *end;
75 0 : *port = strtol(temp,&end,10);
76 0 : if ( *end!='\0' )
77 0 : *port = -2;
78 0 : free(temp);
79 0 : pt2 = ppt;
80 : }
81 0 : *host = cu_copyn(pt,pt2-pt);
82 0 : if ( *username )
83 0 : *password = GIO_PasswordCache(proto,*host,*username,*password);
84 0 : return( path );
85 : }
86 :
87 : struct passwd_cache {
88 : char *proto;
89 : char *host;
90 : char *username;
91 : char *password;
92 : };
93 : static int pc_cnt = 0, pc_max=0;
94 : struct passwd_cache *pc = NULL;
95 :
96 0 : char *GIO_PasswordCache(char *proto,char *host,char *username,char *password) {
97 : int i;
98 : #ifdef HAVE_PTHREAD_H
99 : static pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
100 : #endif
101 :
102 0 : if ( proto==NULL || host==NULL || username==NULL )
103 0 : return( password );
104 :
105 : #ifdef HAVE_PTHREAD_H
106 0 : pthread_mutex_lock(&mymutex);
107 : #endif
108 :
109 0 : for ( i=0; i<pc_cnt; ++i ) {
110 0 : if ( strcasecmp(proto,pc[i].proto)==0 &&
111 0 : strcasecmp(host,pc[i].host)==0 &&
112 0 : strcmp(username,pc[i].username)==0 ) {
113 0 : if ( password==NULL ) {
114 0 : password = copy( pc[i].password );
115 0 : goto leave;
116 : }
117 0 : if ( strcmp(password,pc[i].password)!=0 ) {
118 0 : free( pc[i].password );
119 0 : pc[i].password = copy( password );
120 : }
121 0 : goto leave;
122 : }
123 : }
124 :
125 0 : if ( password==NULL )
126 0 : goto leave;
127 :
128 0 : if ( pc_cnt>=pc_max )
129 0 : pc = realloc(pc,(pc_max+=10)*sizeof(struct passwd_cache));
130 0 : pc[pc_cnt].proto = copy( proto );
131 0 : pc[pc_cnt].host = copy( host );
132 0 : pc[pc_cnt].username = copy( username );
133 0 : pc[pc_cnt].password = copy( password );
134 0 : ++pc_cnt;
135 : leave:
136 : #ifdef HAVE_PTHREAD_H
137 0 : pthread_mutex_unlock(&mymutex);
138 : #endif
139 :
140 0 : return( password );
141 : }
142 :
143 : /* simple hash tables */
144 : static struct hostdata *names[26], *numbers[10];
145 :
146 0 : struct hostdata *_GIO_LookupHost(char *host) {
147 : #if defined(__MINGW32__)
148 : return NULL;
149 : #else
150 :
151 : struct hostdata **base, *cur;
152 : #ifdef HAVE_PTHREAD_H
153 : static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
154 : #endif
155 : int i;
156 :
157 : #ifdef HAVE_PTHREAD_H
158 0 : pthread_mutex_lock(&mutex);
159 : #endif
160 0 : if ( isdigit(host[0]))
161 0 : base = &numbers[host[0]-'0'];
162 0 : else if ( isupper(host[0]) && host[0]<127 )
163 0 : base = &names[host[0]-'A'];
164 0 : else if ( islower(host[0]) && host[0]<127 )
165 0 : base = &names[host[0]-'a'];
166 : else
167 0 : base = &names['z'-'a'];
168 :
169 0 : for ( cur= *base; cur!=NULL && strmatch(cur->hostname,host)!=0; cur = cur->next );
170 0 : if ( cur!=NULL ) {
171 : #ifdef HAVE_PTHREAD_H
172 0 : pthread_mutex_unlock(&mutex);
173 : #endif
174 0 : return( cur );
175 : }
176 :
177 0 : cur = calloc(1,sizeof(struct hostdata));
178 0 : cur->addr.sin_family = AF_INET;
179 0 : cur->addr.sin_port = 0;
180 0 : if ( isdigit(host[0])) {
181 0 : if ( !inet_aton(host,&cur->addr.sin_addr)) {
182 0 : free(cur);
183 : #ifdef HAVE_PTHREAD_H
184 0 : pthread_mutex_unlock(&mutex);
185 : #endif
186 0 : return( NULL );
187 : }
188 : } else {
189 : struct hostent *he;
190 0 : he = gethostbyname(host);
191 0 : if ( he==NULL ) {
192 0 : free(cur);
193 : #ifdef HAVE_PTHREAD_H
194 0 : pthread_mutex_unlock(&mutex);
195 : #endif
196 0 : return( NULL );
197 : }
198 0 : for ( i=0; he->h_addr_list[i]!=NULL; ++i );
199 0 : memcpy(&cur->addr.sin_addr,he->h_addr_list[rand()%(i+1)],he->h_length);
200 : }
201 0 : cur->hostname = copy(host);
202 0 : cur->next = *base;
203 0 : *base = cur;
204 : #ifdef HAVE_PTHREAD_H
205 0 : pthread_mutex_unlock(&mutex);
206 : #endif
207 0 : return( cur );
208 : #endif
209 : }
|