XMMS2

src/lib/xmmsipc/url.c

Go to the documentation of this file.
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 }