+
+
+int ParseURL(ParsedURL **Url, StrBuf *UrlStr, short DefaultPort)
+{
+ const char *pch, *pStartHost, *pEndHost, *pPort, *pCredEnd, *pUserEnd;
+ ParsedURL *url = (ParsedURL *)malloc(sizeof(ParsedURL));
+ memset(url, 0, sizeof(ParsedURL));
+
+ url->af = AF_INET;
+ url->Port = DefaultPort;
+ /*
+ * http://username:passvoid@[ipv6]:port/url
+ */
+ url->URL = NewStrBufDup(UrlStr);
+ pStartHost = pch = ChrPtr(url->URL);
+ url->LocalPart = strchr(pch, '/');
+ if (url->LocalPart != NULL) {
+ if ((*(url->LocalPart + 1) == '/') &&
+ (*(url->LocalPart + 2) == ':')) { /* TODO: find default port for this protocol... */
+ pStartHost = url->LocalPart + 3;
+ url->LocalPart = strchr(pStartHost, '/');
+ }
+ }
+ if (url->LocalPart == NULL) {
+ url->LocalPart = pch + StrLength(UrlStr);
+ }
+
+ pCredEnd = strchr(pch, '@');
+ if (pCredEnd >= url->LocalPart)
+ pCredEnd = NULL;
+ if (pCredEnd != NULL)
+ {
+ url->User = pStartHost;
+ pStartHost = pCredEnd + 1;
+ pUserEnd = strchr(url->User, ':');
+
+ if (pUserEnd > pCredEnd)
+ pUserEnd = pCredEnd;
+ else {
+ url->Pass = pUserEnd + 1;
+ }
+ StrBufPeek(UrlStr, pUserEnd, 0, '\0');
+ StrBufPeek(UrlStr, pCredEnd, 0, '\0');
+ }
+
+ pPort = NULL;
+ if (*pStartHost == '[') {
+ pStartHost ++;
+ pEndHost = strchr(pStartHost, ']');
+ if (pEndHost == NULL) {
+ free(url);
+ return 0; /* invalid syntax, no ipv6 */
+ }
+ if (*(pEndHost + 1) == ':')
+ pPort = pEndHost + 2;
+ url->af = AF_INET6;
+ }
+ else {
+ pPort = strchr(pStartHost, ':');
+ if (pPort != NULL)
+ pPort ++;
+ }
+ if (pPort != NULL)
+ url->Port = atol(pPort);
+ url->IsIP = inet_pton(url->af, pStartHost, &url->Addr);
+ return 1;
+}
+/*
+{
+
+ if (threadding)
+ n_smarthosts = get_hosts(char *mxbuf, char *rectype);
+}
+*/