urlfns.c

Go to the documentation of this file.
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     free(buf);
00123     s=p;
00124   }
00125 
00126   /* get port */
00127   if (*s==':') {
00128     p=++s;
00129     while(*p && *p!='?' && *p!='/')
00130       p++;
00131     if (p!=s) {
00132       char *buf;
00133       int port;
00134 
00135       /* got port */
00136       buf=(char*)malloc(p-s+1);
00137       assert(buf);
00138       memmove(buf, s, p-s+1);
00139       buf[p-s]=0;
00140       if (sscanf(buf, "%d", &port)!=1) {
00141         DBG_ERROR(GWEN_LOGDOMAIN, "Bad port (%s) in url \"%s\"", buf, str);
00142         free(buf);
00143         GWEN_Url_free(url);
00144         return 0;
00145       }
00146       url->port=port;
00147       free(buf);
00148       s=p;
00149     }
00150   }
00151   else {
00152     if (url->protocol) {
00153       if (strcasecmp(url->protocol, "http")==0)
00154         url->port=80;
00155       else if (strcasecmp(url->protocol, "https")==0)
00156         url->port=443;
00157     }
00158   }
00159 
00160   /* get path */
00161   if (starts_with_drive_letter || *s=='/') {
00162     p=s;
00163     while(*p && *p!='?')
00164       p++;
00165     if (p!=s) {
00166       char *buf;
00167 
00168       /* got path */
00169       buf=(char*)malloc(p-s+1);
00170       assert(buf);
00171       memmove(buf, s, p-s+1);
00172       buf[p-s]=0;
00173       GWEN_Url_SetPath(url, buf);
00174       free(buf);
00175       s=p;
00176     }
00177   }
00178   else {
00179     GWEN_Url_SetPath(url, "/");
00180     if (*s)
00181       s++;
00182   }
00183 
00184   /* read vars */
00185   while(*s && *s=='?') {
00186     GWEN_BUFFER *bName;
00187     GWEN_BUFFER *bValue;
00188 
00189     bName=GWEN_Buffer_new(0, 256, 0, 1);
00190     bValue=GWEN_Buffer_new(0, 256, 0, 1);
00191     s++;
00192     p=s;
00193     while(*p && *p!='?' && *p!='=')
00194       p++;
00195     if (p!=s)
00196       GWEN_Buffer_AppendBytes(bName, s, (p-s));
00197     s=p;
00198     if (*p=='=') {
00199       s++;
00200       p=s;
00201       while(*p && *p!='?')
00202         p++;
00203       if (p!=s)
00204         GWEN_Buffer_AppendBytes(bValue, s, (p-s));
00205       s=p;
00206     }
00207     /* store variable/value pair */
00208     if (GWEN_Buffer_GetUsedBytes(bName))
00209       GWEN_DB_SetCharValue(GWEN_Url_GetVars(url),
00210                            GWEN_DB_FLAGS_DEFAULT,
00211                            GWEN_Buffer_GetStart(bName),
00212                            GWEN_Buffer_GetStart(bValue));
00213     GWEN_Buffer_free(bValue);
00214     GWEN_Buffer_free(bName);
00215   }
00216 
00217   url->url=strdup(str);
00218   url->_modified=0;
00219   return url;
00220 }
00221 
00222 
00223 
00224 int GWEN_Url_toString(const GWEN_URL *url, GWEN_BUFFER *buf) {
00225   assert(url);
00226   if (!url->_modified && !(url->url==0 || url->url[0]==0)) {
00227     GWEN_Buffer_AppendString(buf, url->url);
00228   }
00229   else {
00230     GWEN_DB_NODE *dbV;
00231 
00232     if (url->protocol) {
00233       GWEN_Buffer_AppendString(buf, url->protocol);
00234       GWEN_Buffer_AppendString(buf, "://");
00235     }
00236     if (url->server) {
00237       GWEN_Buffer_AppendString(buf, url->server);
00238     }
00239     if (url->port) {
00240       char numbuf[32];
00241 
00242       snprintf(numbuf, sizeof(numbuf), "%d", url->port);
00243       GWEN_Buffer_AppendString(buf, ":");
00244       GWEN_Buffer_AppendString(buf, numbuf);
00245     }
00246     if (url->path) {
00247       GWEN_Buffer_AppendString(buf, url->path);
00248     }
00249     if (url->vars) {
00250       dbV=GWEN_DB_GetFirstVar(url->vars);
00251       while(dbV) {
00252         const char *s;
00253   
00254         s=GWEN_DB_VariableName(dbV);
00255         if (s) {
00256           GWEN_DB_NODE *dbVal;
00257   
00258           GWEN_Buffer_AppendString(buf, "?");
00259           GWEN_Buffer_AppendString(buf, s);
00260           dbVal=GWEN_DB_GetFirstValue(dbV);
00261           if (dbVal) {
00262             s=GWEN_DB_GetCharValueFromNode(dbVal);
00263             if (s) {
00264               GWEN_Buffer_AppendString(buf, "=");
00265               GWEN_Buffer_AppendString(buf, s);
00266             }
00267           }
00268         }
00269         dbV=GWEN_DB_GetNextVar(dbV);
00270       } /* while */
00271     }
00272   }
00273   return 0;
00274 }
00275 
00276 
00277 
00278 GWEN_URL *GWEN_Url_fromCommandString(const char *str) {
00279   GWEN_URL *url;
00280   GWEN_DB_NODE *dbVars;
00281   const char *s;
00282   const char *p;
00283 
00284   url=GWEN_Url_new();
00285   dbVars=GWEN_DB_Group_new("vars");
00286   GWEN_Url_SetVars(url, dbVars);
00287   GWEN_DB_Group_free(dbVars);
00288   dbVars=0;
00289 
00290   s=str;
00291 
00292   /* get path */
00293   if (*s=='/') {
00294     p=s;
00295     while(*p && *p!='?')
00296       p++;
00297     if (p!=s) {
00298       char *buf;
00299 
00300       /* got path */
00301       buf=(char*)malloc(p-s+1);
00302       assert(buf);
00303       memmove(buf, s, p-s+1);
00304       buf[p-s]=0;
00305       GWEN_Url_SetPath(url, buf);
00306       free(buf);
00307       s=p;
00308     }
00309   }
00310   else {
00311     GWEN_Url_SetPath(url, "/");
00312     if (*s)
00313       s++;
00314   }
00315 
00316   /* read vars */
00317   while(*s && *s=='?') {
00318     GWEN_BUFFER *bName;
00319     GWEN_BUFFER *bValue;
00320 
00321     bName=GWEN_Buffer_new(0, 256, 0, 1);
00322     bValue=GWEN_Buffer_new(0, 256, 0, 1);
00323     s++;
00324     p=s;
00325     while(*p && *p!='?' && *p!='=')
00326       p++;
00327     if (p!=s)
00328       GWEN_Buffer_AppendBytes(bName, s, (p-s));
00329     s=p;
00330     if (*p=='=') {
00331       s++;
00332       p=s;
00333       while(*p && *p!='?')
00334         p++;
00335       if (p!=s)
00336         GWEN_Buffer_AppendBytes(bValue, s, (p-s));
00337       s=p;
00338     }
00339     /* store variable/value pair */
00340     if (GWEN_Buffer_GetUsedBytes(bName))
00341       GWEN_DB_SetCharValue(GWEN_Url_GetVars(url),
00342                            GWEN_DB_FLAGS_DEFAULT,
00343                            GWEN_Buffer_GetStart(bName),
00344                            GWEN_Buffer_GetStart(bValue));
00345     GWEN_Buffer_free(bValue);
00346     GWEN_Buffer_free(bName);
00347   }
00348 
00349   url->url=strdup(str);
00350 
00351   return url;
00352 }
00353 
00354 
00355 
00356 int GWEN_Url_toCommandString(const GWEN_URL *url, GWEN_BUFFER *buf) {
00357   GWEN_DB_NODE *dbV;
00358 
00359   assert(url);
00360 
00361   if (url->path) {
00362     GWEN_Buffer_AppendString(buf, url->path);
00363   }
00364   if (url->vars) {
00365     dbV=GWEN_DB_GetFirstVar(url->vars);
00366     while(dbV) {
00367       const char *s;
00368   
00369       s=GWEN_DB_VariableName(dbV);
00370       if (s) {
00371         GWEN_DB_NODE *dbVal;
00372   
00373         GWEN_Buffer_AppendString(buf, "?");
00374         GWEN_Buffer_AppendString(buf, s);
00375         dbVal=GWEN_DB_GetFirstValue(dbV);
00376         if (dbVal) {
00377           s=GWEN_DB_GetCharValueFromNode(dbVal);
00378           if (s) {
00379             GWEN_Buffer_AppendString(buf, "=");
00380             GWEN_Buffer_AppendString(buf, s);
00381           }
00382         }
00383       }
00384       dbV=GWEN_DB_GetNextVar(dbV);
00385     }
00386   }
00387 
00388   return 0;
00389 }
00390 
00391 
00392 

Generated on Sat Jan 2 09:32:36 2010 for gwenhywfar by  doxygen 1.6.1