XMMS2
|
00001 #include <stdio.h> 00002 #include <stdlib.h> 00003 #include <string.h> 00004 00005 #include "url.h" 00006 00007 static int strstrsplit (const char *, const char *, char **, char **); 00008 static int strchrsplit (const char *, const char, char **, char **); 00009 static int strrchrsplit (const char *, const char, char **, char **); 00010 static int strpchrsplit (const char *, const char *, const char, char **, char **); 00011 00012 00013 /** 00014 * Split a URL into its respective parts 00015 * @param url The URL to split 00016 */ 00017 xmms_url_t *parse_url (const char *url) 00018 { 00019 char *tmp1, *tmp2, *tmp3, *tmp4; 00020 char *end; 00021 char *protocol; 00022 char *username, *password; 00023 char *host, *port; 00024 char *path; 00025 00026 xmms_url_t *result; 00027 00028 00029 result = calloc (1, sizeof (xmms_url_t)); 00030 if (!result) 00031 return NULL; 00032 00033 if (strstrsplit (url, "://", &protocol, &tmp1)) { 00034 protocol = strdup (""); 00035 tmp1 = strdup (url); 00036 } 00037 00038 if (strchrsplit (tmp1, '/', &tmp2, &path)) { 00039 tmp2 = strdup (tmp1); 00040 path = strdup (""); 00041 } 00042 00043 if (strchrsplit (tmp2, '@', &tmp3, &tmp4)) { 00044 tmp3 = strdup (""); 00045 tmp4 = strdup (tmp2); 00046 } 00047 00048 if (strchrsplit (tmp3, ':', &username, &password)) { 00049 username = strdup (tmp3); 00050 password = strdup (""); 00051 } 00052 00053 /* Parse IPv4 and IPv6 host+port fields differently */ 00054 if (tmp4[0] == '[') { 00055 result->ipv6_host = 1; 00056 00057 end = strchr (tmp4 + 1, ']'); 00058 if (end) { 00059 if (strpchrsplit (tmp4, end, ':', &host, &port)) { 00060 host = strdup (tmp4); 00061 port = strdup (""); 00062 } 00063 00064 memmove (host, host + 1, end - tmp4 - 1); 00065 host[end - tmp4 - 1] = '\0'; 00066 } else { 00067 host = strdup (tmp4 + 1); 00068 port = strdup (""); 00069 } 00070 } else { 00071 result->ipv6_host = 0; 00072 00073 if (strrchrsplit (tmp4, ':', &host, &port)) { 00074 host = strdup (tmp4); 00075 port = strdup (""); 00076 } 00077 } 00078 00079 free (tmp1); 00080 free (tmp2); 00081 free (tmp3); 00082 free (tmp4); 00083 00084 result->protocol = protocol; 00085 result->username = username; 00086 result->password = password; 00087 result->host = host; 00088 result->port = port; 00089 result->path = path; 00090 00091 return result; 00092 } 00093 00094 void free_url (xmms_url_t *url) 00095 { 00096 free (url->protocol); 00097 free (url->username); 00098 free (url->password); 00099 free (url->host); 00100 free (url->port); 00101 free (url->path); 00102 free (url); 00103 } 00104 00105 00106 /** 00107 * Split a string by the given substring. 00108 * @param str The string to split. 00109 * @param sep The separator substring. 00110 * @param former_result The first part (before the separator). 00111 * @param latter_result The last part (after the separator). 00112 * @return True on error, otherwise false. 00113 */ 00114 static int strstrsplit (const char *str, const char *sep, char **former_result, char **latter_result) 00115 { 00116 char *split; 00117 char *former, *latter; 00118 00119 split = strstr (str, sep); 00120 if (!split) { 00121 return 1; 00122 } 00123 00124 former = malloc (split - str + 1); 00125 if (!former) { 00126 return 1; 00127 } 00128 00129 strncpy (former, str, split - str); 00130 former[split - str] = '\0'; 00131 00132 latter = strdup (split + strlen (sep)); 00133 00134 *former_result = former; 00135 *latter_result = latter; 00136 return 0; 00137 } 00138 00139 /** 00140 * Split a string by the first occurence of the given character. 00141 * @param str The string to split. 00142 * @param sep The separator character. 00143 * @param former_result The first part (before the separator). 00144 * @param latter_result The last part (after the separator). 00145 * @return True on error, otherwise false. 00146 */ 00147 static int strchrsplit (const char *str, const char sep, char **former_result, char **latter_result) 00148 { 00149 char *split; 00150 char *former, *latter; 00151 00152 split = strchr (str, sep); 00153 if (!split) { 00154 return 1; 00155 } 00156 00157 former = malloc (split - str + 1); 00158 if (!former) { 00159 return 1; 00160 } 00161 00162 strncpy (former, str, split - str); 00163 former[split - str] = '\0'; 00164 00165 latter = strdup (split + 1); 00166 00167 *former_result = former; 00168 *latter_result = latter; 00169 return 0; 00170 } 00171 00172 /** 00173 * Split a string by the last occurence of the given character. 00174 * @param str The string to split. 00175 * @param sep The separator character. 00176 * @param former_result The first part (before the separator). 00177 * @param latter_result The last part (after the separator). 00178 * @return True on error, otherwise false. 00179 */ 00180 static int strrchrsplit (const char *str, const char sep, char **former_result, char **latter_result) 00181 { 00182 char *split; 00183 char *former, *latter; 00184 00185 split = strrchr (str, sep); 00186 if (!split) { 00187 return 1; 00188 } 00189 00190 former = malloc (split - str + 1); 00191 if (!former) { 00192 return 1; 00193 } 00194 00195 strncpy (former, str, split - str); 00196 former[split - str] = '\0'; 00197 00198 latter = strdup (split + 1); 00199 00200 *former_result = former; 00201 *latter_result = latter; 00202 return 0; 00203 } 00204 00205 /** 00206 * Split a string by the given occurence of the given character. 00207 * @param str The string to split. 00208 * @param pos The position to search from. 00209 * @param sep The separator character. 00210 * @param former_result The first part (before the separator). 00211 * @param latter_result The last part (after the separator). 00212 * @return True on error, otherwise false. 00213 */ 00214 static int strpchrsplit (const char *str, const char *pos, const char sep, char **former_result, char **latter_result) 00215 { 00216 char *split; 00217 char *former, *latter; 00218 00219 split = strchr (pos, sep); 00220 if (!split) { 00221 return 1; 00222 } 00223 00224 former = malloc (split - str + 1); 00225 if (!former) { 00226 return 1; 00227 } 00228 00229 strncpy (former, str, split - str); 00230 former[split - str] = '\0'; 00231 00232 latter = strdup (split + 1); 00233 00234 *former_result = former; 00235 *latter_result = latter; 00236 return 0; 00237 }