XMMS2
url.c
Go to the documentation of this file.
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "url.h"
6
7static int strstrsplit (const char *, const char *, char **, char **);
8static int strchrsplit (const char *, const char, char **, char **);
9static int strrchrsplit (const char *, const char, char **, char **);
10static int strpchrsplit (const char *, const char *, const char, char **, char **);
11
12
13/**
14 * Split a URL into its respective parts
15 * @param url The URL to split
16 */
17xmms_url_t *parse_url (const char *url)
18{
19 char *tmp1, *tmp2, *tmp3, *tmp4;
20 char *end;
21 char *protocol;
22 char *username, *password;
23 char *host, *port;
24 char *path;
25
26 xmms_url_t *result;
27
28
29 result = calloc (1, sizeof (xmms_url_t));
30 if (!result)
31 return NULL;
32
33 if (strstrsplit (url, "://", &protocol, &tmp1)) {
34 protocol = strdup ("");
35 tmp1 = strdup (url);
36 }
37
38 if (strchrsplit (tmp1, '/', &tmp2, &path)) {
39 tmp2 = strdup (tmp1);
40 path = strdup ("");
41 }
42
43 if (strchrsplit (tmp2, '@', &tmp3, &tmp4)) {
44 tmp3 = strdup ("");
45 tmp4 = strdup (tmp2);
46 }
47
48 if (strchrsplit (tmp3, ':', &username, &password)) {
49 username = strdup (tmp3);
50 password = strdup ("");
51 }
52
53 /* Parse IPv4 and IPv6 host+port fields differently */
54 if (tmp4[0] == '[') {
55 result->ipv6_host = 1;
56
57 end = strchr (tmp4 + 1, ']');
58 if (end) {
59 if (strpchrsplit (tmp4, end, ':', &host, &port)) {
60 host = strdup (tmp4);
61 port = strdup ("");
62 }
63
64 memmove (host, host + 1, end - tmp4 - 1);
65 host[end - tmp4 - 1] = '\0';
66 } else {
67 host = strdup (tmp4 + 1);
68 port = strdup ("");
69 }
70 } else {
71 result->ipv6_host = 0;
72
73 if (strrchrsplit (tmp4, ':', &host, &port)) {
74 host = strdup (tmp4);
75 port = strdup ("");
76 }
77 }
78
79 free (tmp1);
80 free (tmp2);
81 free (tmp3);
82 free (tmp4);
83
84 result->protocol = protocol;
85 result->username = username;
86 result->password = password;
87 result->host = host;
88 result->port = port;
89 result->path = path;
90
91 return result;
92}
93
95{
96 free (url->protocol);
97 free (url->username);
98 free (url->password);
99 free (url->host);
100 free (url->port);
101 free (url->path);
102 free (url);
103}
104
105
106/**
107 * Split a string by the given substring.
108 * @param str The string to split.
109 * @param sep The separator substring.
110 * @param former_result The first part (before the separator).
111 * @param latter_result The last part (after the separator).
112 * @return True on error, otherwise false.
113 */
114static int strstrsplit (const char *str, const char *sep, char **former_result, char **latter_result)
115{
116 char *split;
117 char *former, *latter;
118
119 split = strstr (str, sep);
120 if (!split) {
121 return 1;
122 }
123
124 former = malloc (split - str + 1);
125 if (!former) {
126 return 1;
127 }
128
129 strncpy (former, str, split - str);
130 former[split - str] = '\0';
131
132 latter = strdup (split + strlen (sep));
133
134 *former_result = former;
135 *latter_result = latter;
136 return 0;
137}
138
139/**
140 * Split a string by the first occurence of the given character.
141 * @param str The string to split.
142 * @param sep The separator character.
143 * @param former_result The first part (before the separator).
144 * @param latter_result The last part (after the separator).
145 * @return True on error, otherwise false.
146 */
147static int strchrsplit (const char *str, const char sep, char **former_result, char **latter_result)
148{
149 char *split;
150 char *former, *latter;
151
152 split = strchr (str, sep);
153 if (!split) {
154 return 1;
155 }
156
157 former = malloc (split - str + 1);
158 if (!former) {
159 return 1;
160 }
161
162 strncpy (former, str, split - str);
163 former[split - str] = '\0';
164
165 latter = strdup (split + 1);
166
167 *former_result = former;
168 *latter_result = latter;
169 return 0;
170}
171
172/**
173 * Split a string by the last occurence of the given character.
174 * @param str The string to split.
175 * @param sep The separator character.
176 * @param former_result The first part (before the separator).
177 * @param latter_result The last part (after the separator).
178 * @return True on error, otherwise false.
179 */
180static int strrchrsplit (const char *str, const char sep, char **former_result, char **latter_result)
181{
182 char *split;
183 char *former, *latter;
184
185 split = strrchr (str, sep);
186 if (!split) {
187 return 1;
188 }
189
190 former = malloc (split - str + 1);
191 if (!former) {
192 return 1;
193 }
194
195 strncpy (former, str, split - str);
196 former[split - str] = '\0';
197
198 latter = strdup (split + 1);
199
200 *former_result = former;
201 *latter_result = latter;
202 return 0;
203}
204
205/**
206 * Split a string by the given occurence of the given character.
207 * @param str The string to split.
208 * @param pos The position to search from.
209 * @param sep The separator character.
210 * @param former_result The first part (before the separator).
211 * @param latter_result The last part (after the separator).
212 * @return True on error, otherwise false.
213 */
214static int strpchrsplit (const char *str, const char *pos, const char sep, char **former_result, char **latter_result)
215{
216 char *split;
217 char *former, *latter;
218
219 split = strchr (pos, sep);
220 if (!split) {
221 return 1;
222 }
223
224 former = malloc (split - str + 1);
225 if (!former) {
226 return 1;
227 }
228
229 strncpy (former, str, split - str);
230 former[split - str] = '\0';
231
232 latter = strdup (split + 1);
233
234 *former_result = former;
235 *latter_result = latter;
236 return 0;
237}
Definition: url.h:4
int ipv6_host
Definition: url.h:8
char * port
Definition: url.h:9
char * protocol
Definition: url.h:5
char * password
Definition: url.h:6
char * host
Definition: url.h:9
char * username
Definition: url.h:6
char * path
Definition: url.h:11
void free_url(xmms_url_t *url)
Definition: url.c:94
xmms_url_t * parse_url(const char *url)
Split a URL into its respective parts.
Definition: url.c:17