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 
7 static int strstrsplit (const char *, const char *, char **, char **);
8 static int strchrsplit (const char *, const char, char **, char **);
9 static int strrchrsplit (const char *, const char, char **, char **);
10 static 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  */
17 xmms_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 
94 void free_url (xmms_url_t *url)
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  */
114 static 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  */
147 static 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  */
180 static 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  */
214 static 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 }
char * protocol
Definition: url.h:5
void free_url(xmms_url_t *url)
Definition: url.c:94
char * path
Definition: url.h:11
char * port
Definition: url.h:9
char * username
Definition: url.h:6
int ipv6_host
Definition: url.h:8
Definition: url.h:4
char * host
Definition: url.h:9
xmms_url_t * parse_url(const char *url)
Split a URL into its respective parts.
Definition: url.c:17
char * password
Definition: url.h:6