00001
00002
00003
00004
00005 static const char rcsid[] =
00006 "$Id: uri.c,v 1.6 2006/01/09 12:38:38 tat Exp $";
00007
00008 #include <stdlib.h>
00009 #include <string.h>
00010
00011 #include <u/uri.h>
00012 #include <u/carpal.h>
00013 #include <u/misc.h>
00014 #include <u/memory.h>
00015
00021
00022 static int split(const char *s, size_t len, char c, char **left, char **right)
00023 {
00024 char *buf = 0;
00025 const char *p;
00026 char *l = 0, *r = 0;
00027
00028 buf = u_strndup(s, len);
00029 nop_err_if(!buf);
00030
00031 if((p = strchr(buf, c)) != NULL)
00032 {
00033 l = u_strndup(s, p - buf);
00034 r = u_strndup(1 + p, len - (p - buf) - 1);
00035 nop_err_if(!l || !r);
00036 } else {
00037 r = NULL;
00038 nop_err_if((l = u_strndup(buf, len)) == NULL);
00039 }
00040
00041
00042 *left = l;
00043 *right = r;
00044
00045 U_FREE(buf);
00046
00047 return 0;
00048 err:
00049 U_FREE(buf);
00050 U_FREE(l);
00051 U_FREE(r);
00052 return ~0;
00053 }
00054
00055 static int parse_userinfo(const char *s, size_t len, u_uri_t *uri)
00056 {
00057 return split(s, len, ':', &uri->user, &uri->pwd);
00058 }
00059
00060 static int parse_hostinfo(const char *s, size_t len, u_uri_t *uri)
00061 {
00062 char *port = 0;
00063
00064 if(split(s, len, ':', &uri->host, &port))
00065 return ~0;
00066
00067 if(port)
00068 {
00069 uri->port = atoi(port);
00070 U_FREE(port);
00071 }
00072 return 0;
00073 }
00074
00075 static int parse_middle(const char *s, size_t len, u_uri_t *uri)
00076 {
00077 const char *p;
00078
00079 if( (p = strchr(s, '@')) == NULL)
00080 return parse_hostinfo(s, len, uri);
00081 else
00082 return parse_userinfo(s, p-s,uri) + parse_hostinfo(1+p, s+len-p-1, uri);
00083 }
00084
00086 void u_uri_free (u_uri_t *uri)
00087 {
00088 if (uri == NULL)
00089 return;
00090
00091 U_FREE(uri->scheme);
00092 U_FREE(uri->user);
00093 U_FREE(uri->pwd);
00094 U_FREE(uri->host);
00095 U_FREE(uri->path);
00096 U_FREE(uri);
00097 }
00098
00100 int u_uri_parse (const char *s, u_uri_t **pu)
00101 {
00102 const char *p, *p0;
00103 int i;
00104 u_uri_t *uri;
00105
00106 dbg_return_if ((uri = (u_uri_t*) u_zalloc(sizeof(u_uri_t))) == NULL, ~0);
00107
00108 dbg_err_if ((p = strchr(s, ':')) == NULL);
00109
00110
00111 dbg_err_if ((uri->scheme = u_strndup(s, p - s)) == NULL);
00112
00113 p++;
00114
00115
00116 for (i = 0; i < 2; ++i, ++p)
00117 dbg_err_if (!p || *p == 0 || *p != '/');
00118
00119
00120 p0 = p;
00121
00122
00123 while (*p && *p != '/')
00124 ++p;
00125
00126
00127 dbg_err_if (p - p0 && parse_middle(p0, p - p0, uri));
00128
00129
00130 dbg_err_if (*p && (uri->path = u_strdup(p)) == NULL);
00131
00132 *pu = uri;
00133
00134 return 0;
00135 err:
00136 u_uri_free(uri);
00137 return ~0;
00138 }
00139