/*************************************************************************** * * Copyright 2001,2011,2013 by Sean Conner. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, see . * * Comments, questions and criticisms can be sent to: sean@conman.org * *************************************************************************/ #include #include #include #include #include #include #include "../url.h" /**********************************************************************/ extern struct urlvector g_httpvec; extern struct urlvector g_filevec; extern struct urlvector g_gophervec; struct urlrelation const g_protos[] = { { "file" , URL_FILE , &g_filevec , sizeof(urlfile__t) }, { "http" , URL_HTTP , &g_httpvec , sizeof(urlhttp__t) }, { "gopher" , URL_GOPHER , &g_gophervec , sizeof(urlgopher__t) }, { "https" , URL_HTTPS , &g_httpvec , sizeof(urlhttp__t) }, }; #define PROTOCOLS (sizeof(g_protos) / sizeof(struct urlrelation)) /********************************************************************/ size_t UrlGetProto(char *d,size_t sd,char const **ppurl) { char const *s; char *rd; char c; assert(d != NULL); assert(sd > 0); assert(ppurl != NULL); assert(*ppurl != NULL); rd = d; s = *ppurl; while(((c = *s++) != 0) && (--sd)) { if (c == ':') break; *d++ = tolower(c); } *d = '\0'; *ppurl = s; return((size_t)(d - rd)); } /***********************************************************************/ size_t UrlGetHost(char *d,size_t sd,char const **ppurl) { char const *s; char *rd; assert(d != NULL); assert(sd > 0); assert(ppurl != NULL); assert(*ppurl != NULL); rd = d; s = *ppurl; if ((*s == '/') && (*(s+1) == '/')) { int c; s += 2; /* point past // in URL */ while(((c = *s) != 0) && (--sd)) { if ((c == ':') || (c == '/')) break; *d++ = tolower(c); s++; } } if (*(d-1) == '.') d--; /* remove any trailing '.' */ *d = '\0'; *ppurl = s; return((size_t)(d - rd)); } /***********************************************************************/ size_t UrlGetPort(char *d,size_t sd,char const **ppurl) { char const *s; char *rd; assert(d != NULL); assert(sd > 0); assert(ppurl != NULL); assert(*ppurl != NULL); rd = d; s = *ppurl; if (*s == ':') { s++; while (*s && --sd) { if (!isdigit(*s)) break; *d++ = *s++; } } *d = '\0'; *ppurl = s; return((size_t)(d - rd)); } /***********************************************************************/ size_t UrlGetFile(char *d,size_t sd,char const **ppurl) { char const *s; char *rd; char c; assert(d != NULL); assert(sd > 0); assert(ppurl != NULL); assert(*ppurl != NULL); rd = d; s = *ppurl; while(((c = *s) != 0) && (--sd)) { if (strchr("?#",c)) break; *d++ = c; s++; } *d = '\0'; *ppurl = s; return((size_t)(d - rd)); } /********************************************************************/ url__t *UrlNew(char const *url) { size_t i; char const *turl = url; char tmpbuf[BUFSIZ]; url__t *purl; assert(url != NULL); UrlGetProto(tmpbuf,BUFSIZ,&turl); for (i = 0 ; i < PROTOCOLS ; i++) { if (strcmp(tmpbuf,g_protos[i].proto) == 0) { purl = calloc(1,g_protos[i].size); if (purl != NULL) { purl->scheme = g_protos[i].scheme; if ((*g_protos[i].puv->new)(purl,turl) == 0) return purl; free(purl); return NULL; } } } return NULL; } /**********************************************************************/ .