gwenhywfar 4.0.3
|
00001 /*************************************************************************** 00002 $RCSfile$ 00003 ------------------- 00004 cvs : $Id$ 00005 begin : Fri May 07 2004 00006 copyright : (C) 2004 by Martin Preuss 00007 email : martin@libchipcard.de 00008 00009 *************************************************************************** 00010 * Please see toplevel file COPYING for license details * 00011 ***************************************************************************/ 00012 00013 #ifdef HAVE_CONFIG_H 00014 # include <config.h> 00015 #endif 00016 00017 00018 #include "url_p.h" 00019 #include "urlfns.h" 00020 #include <gwenhywfar/debug.h> 00021 #include <ctype.h> // for isalpha() 00022 00023 00024 GWEN_URL *GWEN_Url_fromString(const char *str) { 00025 GWEN_URL *url; 00026 GWEN_DB_NODE *dbVars; 00027 const char *s; 00028 const char *p; 00029 int starts_with_drive_letter = 0; 00030 00031 url=GWEN_Url_new(); 00032 dbVars=GWEN_DB_Group_new("vars"); 00033 GWEN_Url_SetVars(url, dbVars); 00034 GWEN_DB_Group_free(dbVars); 00035 dbVars=0; 00036 00037 s=str; 00038 00039 /* Check for a drive letter, which occurs on windows, but this will 00040 always be one single alpha character followed by a colon followed 00041 by a directory separator. */ 00042 if (s && isalpha(s[0]) && s[1] == ':' 00043 && (s[2] == '/' || s[2] == '\\')) { 00044 starts_with_drive_letter = 1; 00045 } 00046 00047 /* read protocol (if any) */ 00048 p = starts_with_drive_letter ? s : strchr(s, ':'); 00049 if (p) { 00050 if (p[1]=='/' && p[2]=='/') { 00051 char *buf; 00052 00053 /* got protocol settings */ 00054 buf=(char*)malloc(p-s+1); 00055 assert(buf); 00056 memmove(buf, s, p-s+1); 00057 buf[p-s]=0; 00058 GWEN_Url_SetProtocol(url, buf); 00059 free(buf); 00060 s=p+3; 00061 } 00062 } 00063 00064 if (!*s) { 00065 DBG_ERROR(GWEN_LOGDOMAIN, "No server or path given in url \"%s\"", str); 00066 GWEN_Url_free(url); 00067 return 0; 00068 } 00069 00070 /* read user/password */ 00071 p=strchr(s, '@'); 00072 if (p) { 00073 char *upw; 00074 char *pw; 00075 char *pat; 00076 00077 upw=(char*)malloc(p-s+1); 00078 assert(upw); 00079 memmove(upw, s, p-s); 00080 upw[p-s]=0; 00081 pw=strchr(upw, ':'); 00082 if (pw) { 00083 /* there is also a password */ 00084 *pw=0; 00085 pw++; 00086 } 00087 pat=strchr(upw, '%'); 00088 if (pat) 00089 *pat='@'; 00090 GWEN_Url_SetUserName(url, upw); 00091 if (pw) 00092 GWEN_Url_SetPassword(url, pw); 00093 free(upw); 00094 s=p+1; 00095 } 00096 00097 /* Do we now have a drive letter? (After the protocol?) */ 00098 if (!starts_with_drive_letter 00099 && s && isalpha(s[0]) && s[1] == ':' 00100 && (s[2] == '/' || s[2] == '\\')) { 00101 starts_with_drive_letter = 1; 00102 } 00103 00104 /* read server */ 00105 if (!*s) { 00106 DBG_ERROR(GWEN_LOGDOMAIN, "No server given in url \"%s\"", str); 00107 GWEN_Url_free(url); 00108 return 0; 00109 } 00110 p=s; 00111 while(!starts_with_drive_letter && *p && *p!=':' && *p!='/' && *p!='?') 00112 p++; 00113 if (p!=s) { 00114 char *buf; 00115 00116 /* got server */ 00117 buf=(char*)malloc(p-s+1); 00118 assert(buf); 00119 memmove(buf, s, p-s+1); 00120 buf[p-s]=0; 00121 GWEN_Url_SetServer(url, buf); 00122 DBG_DEBUG(GWEN_LOGDOMAIN, "Server: [%s]", buf); 00123 free(buf); 00124 s=p; 00125 } 00126 00127 /* get port */ 00128 if (*s==':') { 00129 p=++s; 00130 while(*p && *p!='?' && *p!='/') 00131 p++; 00132 if (p!=s) { 00133 char *buf; 00134 int port; 00135 00136 /* got port */ 00137 buf=(char*)malloc(p-s+1); 00138 assert(buf); 00139 memmove(buf, s, p-s+1); 00140 buf[p-s]=0; 00141 if (sscanf(buf, "%d", &port)!=1) { 00142 DBG_ERROR(GWEN_LOGDOMAIN, "Bad port (%s) in url \"%s\"", buf, str); 00143 free(buf); 00144 GWEN_Url_free(url); 00145 return 0; 00146 } 00147 url->port=port; 00148 free(buf); 00149 s=p; 00150 } 00151 } 00152 else { 00153 if (url->protocol) { 00154 if (strcasecmp(url->protocol, "http")==0) 00155 url->port=80; 00156 else if (strcasecmp(url->protocol, "https")==0) 00157 url->port=443; 00158 } 00159 } 00160 00161 /* get path */ 00162 if (starts_with_drive_letter || *s=='/') { 00163 p=s; 00164 while(*p && *p!='?') 00165 p++; 00166 if (p!=s) { 00167 char *buf; 00168 00169 /* got path */ 00170 buf=(char*)malloc(p-s+1); 00171 assert(buf); 00172 memmove(buf, s, p-s+1); 00173 buf[p-s]=0; 00174 GWEN_Url_SetPath(url, buf); 00175 DBG_DEBUG(GWEN_LOGDOMAIN, "Path: [%s]", buf); 00176 free(buf); 00177 s=p; 00178 } 00179 } 00180 else { 00181 GWEN_Url_SetPath(url, "/"); 00182 if (*s) 00183 s++; 00184 } 00185 00186 /* read vars */ 00187 while(*s && *s=='?') { 00188 GWEN_BUFFER *bName; 00189 GWEN_BUFFER *bValue; 00190 00191 bName=GWEN_Buffer_new(0, 256, 0, 1); 00192 bValue=GWEN_Buffer_new(0, 256, 0, 1); 00193 s++; 00194 p=s; 00195 while(*p && *p!='?' && *p!='=') 00196 p++; 00197 if (p!=s) 00198 GWEN_Buffer_AppendBytes(bName, s, (p-s)); 00199 s=p; 00200 if (*p=='=') { 00201 s++; 00202 p=s; 00203 while(*p && *p!='?') 00204 p++; 00205 if (p!=s) 00206 GWEN_Buffer_AppendBytes(bValue, s, (p-s)); 00207 s=p; 00208 } 00209 /* store variable/value pair */ 00210 if (GWEN_Buffer_GetUsedBytes(bName)) 00211 GWEN_DB_SetCharValue(GWEN_Url_GetVars(url), 00212 GWEN_DB_FLAGS_DEFAULT, 00213 GWEN_Buffer_GetStart(bName), 00214 GWEN_Buffer_GetStart(bValue)); 00215 GWEN_Buffer_free(bValue); 00216 GWEN_Buffer_free(bName); 00217 } 00218 00219 url->url=strdup(str); 00220 url->_modified=0; 00221 return url; 00222 } 00223 00224 00225 00226 int GWEN_Url_toString(const GWEN_URL *url, GWEN_BUFFER *buf) { 00227 assert(url); 00228 if (!url->_modified && !(url->url==0 || url->url[0]==0)) { 00229 GWEN_Buffer_AppendString(buf, url->url); 00230 } 00231 else { 00232 GWEN_DB_NODE *dbV; 00233 00234 if (url->protocol) { 00235 GWEN_Buffer_AppendString(buf, url->protocol); 00236 GWEN_Buffer_AppendString(buf, "://"); 00237 } 00238 if (url->server) { 00239 GWEN_Buffer_AppendString(buf, url->server); 00240 } 00241 if (url->port) { 00242 char numbuf[32]; 00243 00244 snprintf(numbuf, sizeof(numbuf), "%d", url->port); 00245 GWEN_Buffer_AppendString(buf, ":"); 00246 GWEN_Buffer_AppendString(buf, numbuf); 00247 } 00248 if (url->path) { 00249 GWEN_Buffer_AppendString(buf, url->path); 00250 } 00251 if (url->vars) { 00252 dbV=GWEN_DB_GetFirstVar(url->vars); 00253 while(dbV) { 00254 const char *s; 00255 00256 s=GWEN_DB_VariableName(dbV); 00257 if (s) { 00258 GWEN_DB_NODE *dbVal; 00259 00260 GWEN_Buffer_AppendString(buf, "?"); 00261 GWEN_Buffer_AppendString(buf, s); 00262 dbVal=GWEN_DB_GetFirstValue(dbV); 00263 if (dbVal) { 00264 s=GWEN_DB_GetCharValueFromNode(dbVal); 00265 if (s) { 00266 GWEN_Buffer_AppendString(buf, "="); 00267 GWEN_Buffer_AppendString(buf, s); 00268 } 00269 } 00270 } 00271 dbV=GWEN_DB_GetNextVar(dbV); 00272 } /* while */ 00273 } 00274 } 00275 return 0; 00276 } 00277 00278 00279 00280 GWEN_URL *GWEN_Url_fromCommandString(const char *str) { 00281 GWEN_URL *url; 00282 GWEN_DB_NODE *dbVars; 00283 const char *s; 00284 const char *p; 00285 00286 url=GWEN_Url_new(); 00287 dbVars=GWEN_DB_Group_new("vars"); 00288 GWEN_Url_SetVars(url, dbVars); 00289 GWEN_DB_Group_free(dbVars); 00290 dbVars=0; 00291 00292 s=str; 00293 00294 /* get path */ 00295 if (*s=='/') { 00296 p=s; 00297 while(*p && *p!='?') 00298 p++; 00299 if (p!=s) { 00300 char *buf; 00301 00302 /* got path */ 00303 buf=(char*)malloc(p-s+1); 00304 assert(buf); 00305 memmove(buf, s, p-s+1); 00306 buf[p-s]=0; 00307 GWEN_Url_SetPath(url, buf); 00308 free(buf); 00309 s=p; 00310 } 00311 } 00312 else { 00313 GWEN_Url_SetPath(url, "/"); 00314 if (*s) 00315 s++; 00316 } 00317 00318 /* read vars */ 00319 while(*s && *s=='?') { 00320 GWEN_BUFFER *bName; 00321 GWEN_BUFFER *bValue; 00322 00323 bName=GWEN_Buffer_new(0, 256, 0, 1); 00324 bValue=GWEN_Buffer_new(0, 256, 0, 1); 00325 s++; 00326 p=s; 00327 while(*p && *p!='?' && *p!='=') 00328 p++; 00329 if (p!=s) 00330 GWEN_Buffer_AppendBytes(bName, s, (p-s)); 00331 s=p; 00332 if (*p=='=') { 00333 s++; 00334 p=s; 00335 while(*p && *p!='?') 00336 p++; 00337 if (p!=s) 00338 GWEN_Buffer_AppendBytes(bValue, s, (p-s)); 00339 s=p; 00340 } 00341 /* store variable/value pair */ 00342 if (GWEN_Buffer_GetUsedBytes(bName)) 00343 GWEN_DB_SetCharValue(GWEN_Url_GetVars(url), 00344 GWEN_DB_FLAGS_DEFAULT, 00345 GWEN_Buffer_GetStart(bName), 00346 GWEN_Buffer_GetStart(bValue)); 00347 GWEN_Buffer_free(bValue); 00348 GWEN_Buffer_free(bName); 00349 } 00350 00351 url->url=strdup(str); 00352 00353 return url; 00354 } 00355 00356 00357 00358 int GWEN_Url_toCommandString(const GWEN_URL *url, GWEN_BUFFER *buf) { 00359 GWEN_DB_NODE *dbV; 00360 00361 assert(url); 00362 00363 if (url->path) { 00364 GWEN_Buffer_AppendString(buf, url->path); 00365 } 00366 if (url->vars) { 00367 dbV=GWEN_DB_GetFirstVar(url->vars); 00368 while(dbV) { 00369 const char *s; 00370 00371 s=GWEN_DB_VariableName(dbV); 00372 if (s) { 00373 GWEN_DB_NODE *dbVal; 00374 00375 GWEN_Buffer_AppendString(buf, "?"); 00376 GWEN_Buffer_AppendString(buf, s); 00377 dbVal=GWEN_DB_GetFirstValue(dbV); 00378 if (dbVal) { 00379 s=GWEN_DB_GetCharValueFromNode(dbVal); 00380 if (s) { 00381 GWEN_Buffer_AppendString(buf, "="); 00382 GWEN_Buffer_AppendString(buf, s); 00383 } 00384 } 00385 } 00386 dbV=GWEN_DB_GetNextVar(dbV); 00387 } 00388 } 00389 00390 return 0; 00391 } 00392 00393 00394