utf8ify_rfc822_string() is in libcitadel now
[citadel.git] / libcitadel / lib / urlhandling.c
index cfadf345f5cf154eb1b9f4582afa36b6688465a0..7d53f9bdb83701b20f597ae7e49304335bbdea3d 100644 (file)
@@ -1,3 +1,5 @@
+// This program is open source software.  Use, duplication, or disclosure
+// is subject to the terms of the GNU General Public License, version 3.
 #include "sysdep.h"
 #include <ctype.h>
 #include <errno.h>
@@ -9,6 +11,7 @@
 #include <fcntl.h>
 #include <sys/types.h>
 #include "libcitadel.h"
+#include <sys/socket.h>
 
 /**
  * @defgroup URLHandling ParsedURL object to handle connection data
@@ -25,6 +28,8 @@ void FreeURL(ParsedURL** Url)
                FreeStrBuf(&(*Url)->URL);
                FreeStrBuf(&(*Url)->UrlWithoutCred);
                FreeStrBuf(&(*Url)->CurlCreds);
+               FreeStrBuf(&(*Url)->UsrName);
+               FreeStrBuf(&(*Url)->Password);
                if ((*Url)->Next != NULL)
                        FreeURL(&(*Url)->Next);
                free(*Url);
@@ -41,7 +46,7 @@ void FreeURL(ParsedURL** Url)
  */
 int ParseURL(ParsedURL **Url, StrBuf *UrlStr, unsigned short DefaultPort)
 {
-       const char *pch, *pEndHost, *pPort, *pCredEnd, *pUserEnd;
+       const char *pch, *pPort, *pCredEnd, *pUserEnd;
        ParsedURL *url = (ParsedURL *)malloc(sizeof(ParsedURL));
        memset(url, 0, sizeof(ParsedURL));
 
@@ -66,10 +71,10 @@ int ParseURL(ParsedURL **Url, StrBuf *UrlStr, unsigned short DefaultPort)
                }
        }
        if (url->LocalPart == NULL) {
-               url->LocalPart = pch + StrLength(url->URL);
+               url->LocalPart = ChrPtr(url->URL) + StrLength(url->URL);
        }
 
-       pCredEnd = strchr(pch, '@');
+       pCredEnd = strrchr(ChrPtr(url->URL), '@');
        if (pCredEnd >= url->LocalPart)
                pCredEnd = NULL;
        if (pCredEnd != NULL)
@@ -86,9 +91,12 @@ int ParseURL(ParsedURL **Url, StrBuf *UrlStr, unsigned short DefaultPort)
                StrBufPeek(url->URL, pUserEnd, 0, '\0');
                StrBufPeek(url->URL, pCredEnd, 0, '\0');                
        }
+       else
+               pUserEnd = NULL;
        
        pPort = NULL;
        if (*url->Host == '[') {
+               const char *pEndHost;
                url->Host ++;
                pEndHost = strchr(url->Host, ']');
                if (pEndHost == NULL) {
@@ -129,7 +137,22 @@ int ParseURL(ParsedURL **Url, StrBuf *UrlStr, unsigned short DefaultPort)
                ((struct sockaddr_in *)&(url->Addr))->sin_port = htons(url->Port);
                ((struct sockaddr_in *)&(url->Addr))->sin_family = AF_INET;
            }   
-       }       
+       }
+
+       if (url->User != NULL) {
+               url->UsrName = NewStrBufPlain(url->User, pUserEnd - url->User);
+               StrBufUnescape(url->UsrName, 0);
+               url->User = ChrPtr(url->UsrName);
+       }
+
+       if (url->Pass != NULL) {
+               url->Password = NewStrBufPlain(url->Pass, pCredEnd - url->Pass);
+               StrBufUnescape(url->Password, 0);
+               url->Pass = ChrPtr(url->Password);
+       }
+
+       if (*Url != NULL)
+               url->Next = *Url;
        *Url = url;
        return 1;
 }