Commit 4ef89f34 4ef89f34158d37b3e2aed8cdc39a64c7c84a270c by Sergey Poznyakoff

Change handling of URL query part.

Queries are now parsed into arguments and returned as arrays
of arguments.

* libproto/include/url0.h (struct _mu_url): Replace query with
array of query arguments.
* include/mailutils/url.h (mu_url_dup): New proto.
(mu_url_get_query): Remove.
(mu_url_sget_query, mu_url_aget_query): Return query split into
arguments.
(mu_url_set_scheme): New function.
(mu_url_decode_len): New function.
* mailbox/url.c (mu_url_dup): New function.
(mu_url_get_query): Remove.
(mu_url_sget_query, mu_url_aget_query): Return query split into
arguments.
(mu_url_set_scheme): New function.
(mu_url_decode_len): New function.
* libproto/remote/mbox.c (remote_mbox_init): Use parsed out URL,
instead of the full URL string.

* examples/url-parse.c: Change query output.
* mailbox/testsuite/Urls: Reflect changes to url-parse.  Add new
testcases.

* libproto/imap/url.c, libproto/pop/url.c: Reflect changes to URL
functions.
1 parent 966f07cc
...@@ -56,6 +56,23 @@ print_fvpairs (mu_url_t url) ...@@ -56,6 +56,23 @@ print_fvpairs (mu_url_t url)
56 printf ("\tparam[%d] <%s>\n", i, fvp[i]); 56 printf ("\tparam[%d] <%s>\n", i, fvp[i]);
57 } 57 }
58 58
59 static void
60 print_query (mu_url_t url)
61 {
62 size_t qargc, i;
63 char **qargv;
64 int rc = mu_url_sget_query (url, &qargc, &qargv);
65 if (rc)
66 {
67 mu_error ("cannot get query: %s", mu_strerror (rc));
68 exit (1);
69 }
70 if (qargc == 0)
71 return;
72 for (i = 0; i < qargc; i++)
73 printf ("\tquery[%d] <%s>\n", i, qargv[i]);
74 }
75
59 int 76 int
60 main () 77 main ()
61 { 78 {
...@@ -101,7 +118,7 @@ main () ...@@ -101,7 +118,7 @@ main ()
101 118
102 GET_AND_PRINT (path, u, buf, rc); 119 GET_AND_PRINT (path, u, buf, rc);
103 print_fvpairs (u); 120 print_fvpairs (u);
104 GET_AND_PRINT (query, u, buf, rc); 121 print_query (u);
105 122
106 mu_url_destroy (&u); 123 mu_url_destroy (&u);
107 124
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2005, 2007 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001, 2005, 2007,
3 2008 Free Software Foundation, Inc.
3 4
4 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
...@@ -26,6 +27,8 @@ extern "C" { ...@@ -26,6 +27,8 @@ extern "C" {
26 #endif 27 #endif
27 28
28 extern int mu_url_create (mu_url_t *, const char *name); 29 extern int mu_url_create (mu_url_t *, const char *name);
30 extern int mu_url_dup (mu_url_t old_url, mu_url_t *new_url);
31
29 extern void mu_url_destroy (mu_url_t *); 32 extern void mu_url_destroy (mu_url_t *);
30 extern int mu_url_parse (mu_url_t); 33 extern int mu_url_parse (mu_url_t);
31 34
...@@ -53,9 +56,8 @@ extern int mu_url_sget_path (const mu_url_t, const char **); ...@@ -53,9 +56,8 @@ extern int mu_url_sget_path (const mu_url_t, const char **);
53 extern int mu_url_aget_path (const mu_url_t, char **); 56 extern int mu_url_aget_path (const mu_url_t, char **);
54 extern int mu_url_get_path (const mu_url_t, char *, size_t, size_t *); 57 extern int mu_url_get_path (const mu_url_t, char *, size_t, size_t *);
55 58
56 extern int mu_url_sget_query (const mu_url_t, const char **); 59 extern int mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv);
57 extern int mu_url_aget_query (const mu_url_t, char **); 60 extern int mu_url_aget_query (const mu_url_t url, size_t *qc, char ***qv);
58 extern int mu_url_get_query (const mu_url_t, char *, size_t, size_t *);
59 61
60 extern int mu_url_get_port (const mu_url_t, long *); 62 extern int mu_url_get_port (const mu_url_t, long *);
61 63
...@@ -65,6 +67,8 @@ int mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp); ...@@ -65,6 +67,8 @@ int mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp);
65 extern int mu_url_expand_path (mu_url_t url); 67 extern int mu_url_expand_path (mu_url_t url);
66 extern const char *mu_url_to_string (const mu_url_t); 68 extern const char *mu_url_to_string (const mu_url_t);
67 69
70 extern int mu_url_set_scheme (mu_url_t url, const char *scheme);
71
68 extern int mu_url_is_scheme (mu_url_t, const char *scheme); 72 extern int mu_url_is_scheme (mu_url_t, const char *scheme);
69 73
70 extern int mu_url_is_same_scheme (mu_url_t, mu_url_t); 74 extern int mu_url_is_same_scheme (mu_url_t, mu_url_t);
...@@ -73,6 +77,7 @@ extern int mu_url_is_same_path (mu_url_t, mu_url_t); ...@@ -73,6 +77,7 @@ extern int mu_url_is_same_path (mu_url_t, mu_url_t);
73 extern int mu_url_is_same_host (mu_url_t, mu_url_t); 77 extern int mu_url_is_same_host (mu_url_t, mu_url_t);
74 extern int mu_url_is_same_port (mu_url_t, mu_url_t); 78 extern int mu_url_is_same_port (mu_url_t, mu_url_t);
75 79
80 extern char *mu_url_decode_len (const char *s, size_t len);
76 extern char *mu_url_decode (const char *s); 81 extern char *mu_url_decode (const char *s);
77 82
78 extern int mu_url_is_ticket (mu_url_t ticket, mu_url_t url); 83 extern int mu_url_is_ticket (mu_url_t ticket, mu_url_t url);
......
...@@ -54,7 +54,7 @@ _url_imap_init (mu_url_t url) ...@@ -54,7 +54,7 @@ _url_imap_init (mu_url_t url)
54 54
55 url->_destroy = url_imap_destroy; 55 url->_destroy = url_imap_destroy;
56 56
57 if(!url->host || url->query) 57 if (!url->host || url->qargc)
58 return EINVAL; 58 return EINVAL;
59 59
60 /* fill in default auth, if necessary */ 60 /* fill in default auth, if necessary */
...@@ -85,7 +85,7 @@ _url_imaps_init (mu_url_t url) ...@@ -85,7 +85,7 @@ _url_imaps_init (mu_url_t url)
85 85
86 url->_destroy = url_imap_destroy; 86 url->_destroy = url_imap_destroy;
87 87
88 if (!url->host || url->query) 88 if (!url->host || url->qargc)
89 return EINVAL; 89 return EINVAL;
90 90
91 /* fill in default auth, if necessary */ 91 /* fill in default auth, if necessary */
......
...@@ -42,7 +42,9 @@ struct _mu_url ...@@ -42,7 +42,9 @@ struct _mu_url
42 char *path; 42 char *path;
43 char **fvpairs; 43 char **fvpairs;
44 int fvcount; 44 int fvcount;
45 char *query; 45
46 char **qargv;
47 int qargc;
46 48
47 void *data; 49 void *data;
48 50
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2003, 2007 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001, 2003, 2007,
3 2008 Free Software Foundation, Inc.
3 4
4 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
...@@ -55,7 +56,7 @@ _url_pop_init (mu_url_t url) ...@@ -55,7 +56,7 @@ _url_pop_init (mu_url_t url)
55 url->_destroy = url_pop_destroy; 56 url->_destroy = url_pop_destroy;
56 57
57 /* not valid in pop url */ 58 /* not valid in pop url */
58 if (url->path || url->query || !url->host) 59 if (url->path || url->qargc || !url->host)
59 return EINVAL; 60 return EINVAL;
60 61
61 return 0; 62 return 0;
...@@ -77,7 +78,7 @@ _url_pops_init (mu_url_t url) ...@@ -77,7 +78,7 @@ _url_pops_init (mu_url_t url)
77 url->_destroy = url_pop_destroy; 78 url->_destroy = url_pop_destroy;
78 79
79 /* not valid in pops url */ 80 /* not valid in pops url */
80 if (url->path || url->query || !url->host) 81 if (url->path || url->qargc || !url->host)
81 return EINVAL; 82 return EINVAL;
82 83
83 return 0; 84 return 0;
......
...@@ -206,29 +206,43 @@ remote_mbox_init (mu_mailbox_t mailbox) ...@@ -206,29 +206,43 @@ remote_mbox_init (mu_mailbox_t mailbox)
206 const char *s, *p; 206 const char *s, *p;
207 int rc; 207 int rc;
208 mu_mailer_t mailer; 208 mu_mailer_t mailer;
209 mu_url_t url;
209 210
210 if (mailbox == NULL) 211 if (mailbox == NULL)
211 return EINVAL; 212 return EINVAL;
212 213
213 s = mu_url_to_string (mailbox->url); 214 MU_DEBUG1 (mailbox->debug, MU_DEBUG_TRACE1,
214 215 "remote_mbox_init (%s)\n", mu_url_to_string (mailbox->url));
215 MU_DEBUG1 (mailbox->debug, MU_DEBUG_TRACE1, "remote_mbox_init (%s)\n", s); 216 rc = mu_url_sget_scheme (mailbox->url, &s);
216 217 if (rc)
218 return rc;
217 p = strchr (s, '+'); 219 p = strchr (s, '+');
218 if (!p) 220 if (!p)
219 { 221 {
220 MU_DEBUG2 (mailbox->debug, MU_DEBUG_ERROR, 222 MU_DEBUG2 (mailbox->debug, MU_DEBUG_ERROR,
221 "remote_mbox_init(%s): invalid url: %s\n", s, 223 "remote_mbox_init(%s): invalid url: %s\n",
224 mu_url_to_string (mailbox->url),
222 mu_strerror (rc)); 225 mu_strerror (rc));
223 return MU_ERR_MAILER_BAD_URL; 226 return MU_ERR_MAILER_BAD_URL;
224 } 227 }
225 p++; 228
226 rc = mu_mailer_create (&mailer, p); 229 rc = mu_url_dup (mailbox->url, &url);
230 if (rc)
231 return rc;
232 rc = mu_url_set_scheme (url, p + 1);
233 if (rc)
234 {
235 mu_url_destroy (&url);
236 return rc;
237 }
238
239 rc = mu_mailer_create_from_url (&mailer, url);
227 if (rc) 240 if (rc)
228 { 241 {
229 MU_DEBUG2 (mailbox->debug, MU_DEBUG_ERROR, 242 MU_DEBUG2 (mailbox->debug, MU_DEBUG_ERROR,
230 "remote_mbox_init(%s): cannot create mailer: %s\n", 243 "remote_mbox_init(%s): cannot create mailer: %s\n",
231 s, mu_strerror (rc)); 244 mu_url_to_string (url), mu_strerror (rc));
245 mu_url_destroy (&url);
232 return rc; 246 return rc;
233 } 247 }
234 248
......
1 # This file is part of Mailutils testsuite. 1 # This file is part of Mailutils testsuite.
2 # Copyright (C) 2002, 2007 Free Software Foundation 2 # Copyright (C) 2002, 2007, 2008 Free Software Foundation
3 # 3 #
4 # This program is free software; you can redistribute it and/or modify 4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by 5 # it under the terms of the GNU General Public License as published by
...@@ -25,7 +25,6 @@ scheme: => SUCCESS ...@@ -25,7 +25,6 @@ scheme: => SUCCESS
25 host <> 25 host <>
26 port 0 26 port 0
27 path <> 27 path <>
28 query <>
29 28
30 scheme:/absolute/path => SUCCESS 29 scheme:/absolute/path => SUCCESS
31 scheme <scheme> 30 scheme <scheme>
...@@ -35,7 +34,6 @@ scheme:/absolute/path => SUCCESS ...@@ -35,7 +34,6 @@ scheme:/absolute/path => SUCCESS
35 host <> 34 host <>
36 port 0 35 port 0
37 path </absolute/path> 36 path </absolute/path>
38 query <>
39 37
40 scheme:relative/path => SUCCESS 38 scheme:relative/path => SUCCESS
41 scheme <scheme> 39 scheme <scheme>
...@@ -45,7 +43,6 @@ scheme:relative/path => SUCCESS ...@@ -45,7 +43,6 @@ scheme:relative/path => SUCCESS
45 host <> 43 host <>
46 port 0 44 port 0
47 path <relative/path> 45 path <relative/path>
48 query <>
49 46
50 scheme:///absolute/path => SUCCESS 47 scheme:///absolute/path => SUCCESS
51 scheme <scheme> 48 scheme <scheme>
...@@ -55,7 +52,6 @@ scheme:///absolute/path => SUCCESS ...@@ -55,7 +52,6 @@ scheme:///absolute/path => SUCCESS
55 host <> 52 host <>
56 port 0 53 port 0
57 path </absolute/path> 54 path </absolute/path>
58 query <>
59 55
60 scheme://%75%73%65%72:%70%61%73%73@%68%6f%73%74 => SUCCESS 56 scheme://%75%73%65%72:%70%61%73%73@%68%6f%73%74 => SUCCESS
61 scheme <scheme> 57 scheme <scheme>
...@@ -65,7 +61,6 @@ scheme://%75%73%65%72:%70%61%73%73@%68%6f%73%74 => SUCCESS ...@@ -65,7 +61,6 @@ scheme://%75%73%65%72:%70%61%73%73@%68%6f%73%74 => SUCCESS
65 host <hest> 61 host <hest>
66 port 0 62 port 0
67 path <> 63 path <>
68 query <>
69 64
70 ftp://user:pass@host//a/path => SUCCESS 65 ftp://user:pass@host//a/path => SUCCESS
71 scheme <ftp> 66 scheme <ftp>
...@@ -75,7 +70,6 @@ ftp://user:pass@host//a/path => SUCCESS ...@@ -75,7 +70,6 @@ ftp://user:pass@host//a/path => SUCCESS
75 host <host> 70 host <host>
76 port 0 71 port 0
77 path </a/path> 72 path </a/path>
78 query <>
79 73
80 ftp://:pass@host//a/path => SUCCESS 74 ftp://:pass@host//a/path => SUCCESS
81 scheme <ftp> 75 scheme <ftp>
...@@ -85,7 +79,6 @@ ftp://:pass@host//a/path => SUCCESS ...@@ -85,7 +79,6 @@ ftp://:pass@host//a/path => SUCCESS
85 host <host> 79 host <host>
86 port 0 80 port 0
87 path </a/path> 81 path </a/path>
88 query <>
89 82
90 ftp://user:@host//a/path => SUCCESS 83 ftp://user:@host//a/path => SUCCESS
91 scheme <ftp> 84 scheme <ftp>
...@@ -95,7 +88,6 @@ ftp://user:@host//a/path => SUCCESS ...@@ -95,7 +88,6 @@ ftp://user:@host//a/path => SUCCESS
95 host <host> 88 host <host>
96 port 0 89 port 0
97 path </a/path> 90 path </a/path>
98 query <>
99 91
100 ftp://user:pass@//a/path => SUCCESS 92 ftp://user:pass@//a/path => SUCCESS
101 scheme <ftp> 93 scheme <ftp>
...@@ -105,7 +97,6 @@ ftp://user:pass@//a/path => SUCCESS ...@@ -105,7 +97,6 @@ ftp://user:pass@//a/path => SUCCESS
105 host <> 97 host <>
106 port 0 98 port 0
107 path </a/path> 99 path </a/path>
108 query <>
109 100
110 ftp://user:@//a/path => SUCCESS 101 ftp://user:@//a/path => SUCCESS
111 scheme <ftp> 102 scheme <ftp>
...@@ -115,7 +106,6 @@ ftp://user:@//a/path => SUCCESS ...@@ -115,7 +106,6 @@ ftp://user:@//a/path => SUCCESS
115 host <> 106 host <>
116 port 0 107 port 0
117 path </a/path> 108 path </a/path>
118 query <>
119 109
120 ftp://:@host//a/path => SUCCESS 110 ftp://:@host//a/path => SUCCESS
121 scheme <ftp> 111 scheme <ftp>
...@@ -125,7 +115,6 @@ ftp://:@host//a/path => SUCCESS ...@@ -125,7 +115,6 @@ ftp://:@host//a/path => SUCCESS
125 host <host> 115 host <host>
126 port 0 116 port 0
127 path </a/path> 117 path </a/path>
128 query <>
129 118
130 ftp://:pass@//a/path => SUCCESS 119 ftp://:pass@//a/path => SUCCESS
131 scheme <ftp> 120 scheme <ftp>
...@@ -135,7 +124,6 @@ ftp://:pass@//a/path => SUCCESS ...@@ -135,7 +124,6 @@ ftp://:pass@//a/path => SUCCESS
135 host <> 124 host <>
136 port 0 125 port 0
137 path </a/path> 126 path </a/path>
138 query <>
139 127
140 ftp://:@//a/path => SUCCESS 128 ftp://:@//a/path => SUCCESS
141 scheme <ftp> 129 scheme <ftp>
...@@ -145,7 +133,6 @@ ftp://:@//a/path => SUCCESS ...@@ -145,7 +133,6 @@ ftp://:@//a/path => SUCCESS
145 host <> 133 host <>
146 port 0 134 port 0
147 path </a/path> 135 path </a/path>
148 query <>
149 136
150 ftp://://a/path => SUCCESS 137 ftp://://a/path => SUCCESS
151 scheme <ftp> 138 scheme <ftp>
...@@ -155,7 +142,6 @@ ftp://://a/path => SUCCESS ...@@ -155,7 +142,6 @@ ftp://://a/path => SUCCESS
155 host <> 142 host <>
156 port 0 143 port 0
157 path </a/path> 144 path </a/path>
158 query <>
159 145
160 ftp://@//a/path => SUCCESS 146 ftp://@//a/path => SUCCESS
161 scheme <ftp> 147 scheme <ftp>
...@@ -165,7 +151,6 @@ ftp://@//a/path => SUCCESS ...@@ -165,7 +151,6 @@ ftp://@//a/path => SUCCESS
165 host <> 151 host <>
166 port 0 152 port 0
167 path </a/path> 153 path </a/path>
168 query <>
169 154
170 ftp:/a/path => SUCCESS 155 ftp:/a/path => SUCCESS
171 scheme <ftp> 156 scheme <ftp>
...@@ -175,7 +160,6 @@ ftp:/a/path => SUCCESS ...@@ -175,7 +160,6 @@ ftp:/a/path => SUCCESS
175 host <> 160 host <>
176 port 0 161 port 0
177 path </a/path> 162 path </a/path>
178 query <>
179 163
180 ftp://user:pass@host/a/path => SUCCESS 164 ftp://user:pass@host/a/path => SUCCESS
181 scheme <ftp> 165 scheme <ftp>
...@@ -185,7 +169,6 @@ ftp://user:pass@host/a/path => SUCCESS ...@@ -185,7 +169,6 @@ ftp://user:pass@host/a/path => SUCCESS
185 host <host> 169 host <host>
186 port 0 170 port 0
187 path <a/path> 171 path <a/path>
188 query <>
189 172
190 ftp://:pass@host/a/path => SUCCESS 173 ftp://:pass@host/a/path => SUCCESS
191 scheme <ftp> 174 scheme <ftp>
...@@ -195,7 +178,6 @@ ftp://:pass@host/a/path => SUCCESS ...@@ -195,7 +178,6 @@ ftp://:pass@host/a/path => SUCCESS
195 host <host> 178 host <host>
196 port 0 179 port 0
197 path <a/path> 180 path <a/path>
198 query <>
199 181
200 ftp://user:@host/a/path => SUCCESS 182 ftp://user:@host/a/path => SUCCESS
201 scheme <ftp> 183 scheme <ftp>
...@@ -205,7 +187,6 @@ ftp://user:@host/a/path => SUCCESS ...@@ -205,7 +187,6 @@ ftp://user:@host/a/path => SUCCESS
205 host <host> 187 host <host>
206 port 0 188 port 0
207 path <a/path> 189 path <a/path>
208 query <>
209 190
210 ftp://user:pass@/a/path => SUCCESS 191 ftp://user:pass@/a/path => SUCCESS
211 scheme <ftp> 192 scheme <ftp>
...@@ -215,7 +196,6 @@ ftp://user:pass@/a/path => SUCCESS ...@@ -215,7 +196,6 @@ ftp://user:pass@/a/path => SUCCESS
215 host <> 196 host <>
216 port 0 197 port 0
217 path <a/path> 198 path <a/path>
218 query <>
219 199
220 ftp://user:@/a/path => SUCCESS 200 ftp://user:@/a/path => SUCCESS
221 scheme <ftp> 201 scheme <ftp>
...@@ -225,7 +205,6 @@ ftp://user:@/a/path => SUCCESS ...@@ -225,7 +205,6 @@ ftp://user:@/a/path => SUCCESS
225 host <> 205 host <>
226 port 0 206 port 0
227 path <a/path> 207 path <a/path>
228 query <>
229 208
230 ftp://:@host/a/path => SUCCESS 209 ftp://:@host/a/path => SUCCESS
231 scheme <ftp> 210 scheme <ftp>
...@@ -235,7 +214,6 @@ ftp://:@host/a/path => SUCCESS ...@@ -235,7 +214,6 @@ ftp://:@host/a/path => SUCCESS
235 host <host> 214 host <host>
236 port 0 215 port 0
237 path <a/path> 216 path <a/path>
238 query <>
239 217
240 ftp://:pass@/a/path => SUCCESS 218 ftp://:pass@/a/path => SUCCESS
241 scheme <ftp> 219 scheme <ftp>
...@@ -245,7 +223,6 @@ ftp://:pass@/a/path => SUCCESS ...@@ -245,7 +223,6 @@ ftp://:pass@/a/path => SUCCESS
245 host <> 223 host <>
246 port 0 224 port 0
247 path <a/path> 225 path <a/path>
248 query <>
249 226
250 ftp://:@/a/path => SUCCESS 227 ftp://:@/a/path => SUCCESS
251 scheme <ftp> 228 scheme <ftp>
...@@ -255,7 +232,6 @@ ftp://:@/a/path => SUCCESS ...@@ -255,7 +232,6 @@ ftp://:@/a/path => SUCCESS
255 host <> 232 host <>
256 port 0 233 port 0
257 path <a/path> 234 path <a/path>
258 query <>
259 235
260 ftp://:/a/path => SUCCESS 236 ftp://:/a/path => SUCCESS
261 scheme <ftp> 237 scheme <ftp>
...@@ -265,7 +241,6 @@ ftp://:/a/path => SUCCESS ...@@ -265,7 +241,6 @@ ftp://:/a/path => SUCCESS
265 host <> 241 host <>
266 port 0 242 port 0
267 path <a/path> 243 path <a/path>
268 query <>
269 244
270 ftp://@/a/path => SUCCESS 245 ftp://@/a/path => SUCCESS
271 scheme <ftp> 246 scheme <ftp>
...@@ -275,7 +250,6 @@ ftp://@/a/path => SUCCESS ...@@ -275,7 +250,6 @@ ftp://@/a/path => SUCCESS
275 host <> 250 host <>
276 port 0 251 port 0
277 path <a/path> 252 path <a/path>
278 query <>
279 253
280 ftp:///a/path => SUCCESS 254 ftp:///a/path => SUCCESS
281 scheme <ftp> 255 scheme <ftp>
...@@ -285,7 +259,6 @@ ftp:///a/path => SUCCESS ...@@ -285,7 +259,6 @@ ftp:///a/path => SUCCESS
285 host <> 259 host <>
286 port 0 260 port 0
287 path </a/path> 261 path </a/path>
288 query <>
289 262
290 pop://pop.example.net => SUCCESS 263 pop://pop.example.net => SUCCESS
291 scheme <pop> 264 scheme <pop>
...@@ -295,7 +268,6 @@ pop://pop.example.net => SUCCESS ...@@ -295,7 +268,6 @@ pop://pop.example.net => SUCCESS
295 host <pop.example.net> 268 host <pop.example.net>
296 port 0 269 port 0
297 path <> 270 path <>
298 query <>
299 271
300 pop://user@pop.example.net => SUCCESS 272 pop://user@pop.example.net => SUCCESS
301 scheme <pop> 273 scheme <pop>
...@@ -305,7 +277,6 @@ pop://user@pop.example.net => SUCCESS ...@@ -305,7 +277,6 @@ pop://user@pop.example.net => SUCCESS
305 host <pop.example.net> 277 host <pop.example.net>
306 port 0 278 port 0
307 path <> 279 path <>
308 query <>
309 280
310 pop://user:passwd@pop.example.net => SUCCESS 281 pop://user:passwd@pop.example.net => SUCCESS
311 scheme <pop> 282 scheme <pop>
...@@ -315,7 +286,6 @@ pop://user:passwd@pop.example.net => SUCCESS ...@@ -315,7 +286,6 @@ pop://user:passwd@pop.example.net => SUCCESS
315 host <pop.example.net> 286 host <pop.example.net>
316 port 0 287 port 0
317 path <> 288 path <>
318 query <>
319 289
320 pop://user;auth=*@pop.example.net => SUCCESS 290 pop://user;auth=*@pop.example.net => SUCCESS
321 scheme <pop> 291 scheme <pop>
...@@ -325,7 +295,6 @@ pop://user;auth=*@pop.example.net => SUCCESS ...@@ -325,7 +295,6 @@ pop://user;auth=*@pop.example.net => SUCCESS
325 host <pop.example.net> 295 host <pop.example.net>
326 port 0 296 port 0
327 path <> 297 path <>
328 query <>
329 298
330 pop://pop.example.net:111 => SUCCESS 299 pop://pop.example.net:111 => SUCCESS
331 scheme <pop> 300 scheme <pop>
...@@ -335,7 +304,6 @@ pop://pop.example.net:111 => SUCCESS ...@@ -335,7 +304,6 @@ pop://pop.example.net:111 => SUCCESS
335 host <pop.example.net> 304 host <pop.example.net>
336 port 111 305 port 111
337 path <> 306 path <>
338 query <>
339 307
340 pop://user@pop.example.net:111 => SUCCESS 308 pop://user@pop.example.net:111 => SUCCESS
341 scheme <pop> 309 scheme <pop>
...@@ -345,7 +313,6 @@ pop://user@pop.example.net:111 => SUCCESS ...@@ -345,7 +313,6 @@ pop://user@pop.example.net:111 => SUCCESS
345 host <pop.example.net> 313 host <pop.example.net>
346 port 111 314 port 111
347 path <> 315 path <>
348 query <>
349 316
350 pop://user:passwd@pop.example.net:111 => SUCCESS 317 pop://user:passwd@pop.example.net:111 => SUCCESS
351 scheme <pop> 318 scheme <pop>
...@@ -355,7 +322,6 @@ pop://user:passwd@pop.example.net:111 => SUCCESS ...@@ -355,7 +322,6 @@ pop://user:passwd@pop.example.net:111 => SUCCESS
355 host <pop.example.net> 322 host <pop.example.net>
356 port 111 323 port 111
357 path <> 324 path <>
358 query <>
359 325
360 pop://user;auth=*@pop.example.net:111 => SUCCESS 326 pop://user;auth=*@pop.example.net:111 => SUCCESS
361 scheme <pop> 327 scheme <pop>
...@@ -365,7 +331,6 @@ pop://user;auth=*@pop.example.net:111 => SUCCESS ...@@ -365,7 +331,6 @@ pop://user;auth=*@pop.example.net:111 => SUCCESS
365 host <pop.example.net> 331 host <pop.example.net>
366 port 111 332 port 111
367 path <> 333 path <>
368 query <>
369 334
370 imap://imap.example.net => SUCCESS 335 imap://imap.example.net => SUCCESS
371 scheme <imap> 336 scheme <imap>
...@@ -375,7 +340,6 @@ imap://imap.example.net => SUCCESS ...@@ -375,7 +340,6 @@ imap://imap.example.net => SUCCESS
375 host <imap.example.net> 340 host <imap.example.net>
376 port 0 341 port 0
377 path <> 342 path <>
378 query <>
379 343
380 imap://user@imap.example.net => SUCCESS 344 imap://user@imap.example.net => SUCCESS
381 scheme <imap> 345 scheme <imap>
...@@ -385,7 +349,6 @@ imap://user@imap.example.net => SUCCESS ...@@ -385,7 +349,6 @@ imap://user@imap.example.net => SUCCESS
385 host <imap.example.net> 349 host <imap.example.net>
386 port 0 350 port 0
387 path <> 351 path <>
388 query <>
389 352
390 imap://user:passwd@imap.example.net => SUCCESS 353 imap://user:passwd@imap.example.net => SUCCESS
391 scheme <imap> 354 scheme <imap>
...@@ -395,7 +358,6 @@ imap://user:passwd@imap.example.net => SUCCESS ...@@ -395,7 +358,6 @@ imap://user:passwd@imap.example.net => SUCCESS
395 host <imap.example.net> 358 host <imap.example.net>
396 port 0 359 port 0
397 path <> 360 path <>
398 query <>
399 361
400 imap://user;auth=*@imap.example.net => SUCCESS 362 imap://user;auth=*@imap.example.net => SUCCESS
401 scheme <imap> 363 scheme <imap>
...@@ -405,7 +367,6 @@ imap://user;auth=*@imap.example.net => SUCCESS ...@@ -405,7 +367,6 @@ imap://user;auth=*@imap.example.net => SUCCESS
405 host <imap.example.net> 367 host <imap.example.net>
406 port 0 368 port 0
407 path <> 369 path <>
408 query <>
409 370
410 imap://imap.example.net:111 => SUCCESS 371 imap://imap.example.net:111 => SUCCESS
411 scheme <imap> 372 scheme <imap>
...@@ -415,7 +376,6 @@ imap://imap.example.net:111 => SUCCESS ...@@ -415,7 +376,6 @@ imap://imap.example.net:111 => SUCCESS
415 host <imap.example.net> 376 host <imap.example.net>
416 port 111 377 port 111
417 path <> 378 path <>
418 query <>
419 379
420 imap://user@imap.example.net:111 => SUCCESS 380 imap://user@imap.example.net:111 => SUCCESS
421 scheme <imap> 381 scheme <imap>
...@@ -425,7 +385,6 @@ imap://user@imap.example.net:111 => SUCCESS ...@@ -425,7 +385,6 @@ imap://user@imap.example.net:111 => SUCCESS
425 host <imap.example.net> 385 host <imap.example.net>
426 port 111 386 port 111
427 path <> 387 path <>
428 query <>
429 388
430 imap://user:passwd@imap.example.net:111 => SUCCESS 389 imap://user:passwd@imap.example.net:111 => SUCCESS
431 scheme <imap> 390 scheme <imap>
...@@ -435,7 +394,6 @@ imap://user:passwd@imap.example.net:111 => SUCCESS ...@@ -435,7 +394,6 @@ imap://user:passwd@imap.example.net:111 => SUCCESS
435 host <imap.example.net> 394 host <imap.example.net>
436 port 111 395 port 111
437 path <> 396 path <>
438 query <>
439 397
440 imap://user;auth=*@imap.example.net:111 => SUCCESS 398 imap://user;auth=*@imap.example.net:111 => SUCCESS
441 scheme <imap> 399 scheme <imap>
...@@ -445,7 +403,6 @@ imap://user;auth=*@imap.example.net:111 => SUCCESS ...@@ -445,7 +403,6 @@ imap://user;auth=*@imap.example.net:111 => SUCCESS
445 host <imap.example.net> 403 host <imap.example.net>
446 port 111 404 port 111
447 path <> 405 path <>
448 query <>
449 406
450 imap://imap.example.net/mbox => SUCCESS 407 imap://imap.example.net/mbox => SUCCESS
451 scheme <imap> 408 scheme <imap>
...@@ -455,7 +412,6 @@ imap://imap.example.net/mbox => SUCCESS ...@@ -455,7 +412,6 @@ imap://imap.example.net/mbox => SUCCESS
455 host <imap.example.net> 412 host <imap.example.net>
456 port 0 413 port 0
457 path <mbox> 414 path <mbox>
458 query <>
459 415
460 imap://user@imap.example.net/mbox => SUCCESS 416 imap://user@imap.example.net/mbox => SUCCESS
461 scheme <imap> 417 scheme <imap>
...@@ -465,7 +421,6 @@ imap://user@imap.example.net/mbox => SUCCESS ...@@ -465,7 +421,6 @@ imap://user@imap.example.net/mbox => SUCCESS
465 host <imap.example.net> 421 host <imap.example.net>
466 port 0 422 port 0
467 path <mbox> 423 path <mbox>
468 query <>
469 424
470 imap://user:passwd@imap.example.net/mbox => SUCCESS 425 imap://user:passwd@imap.example.net/mbox => SUCCESS
471 scheme <imap> 426 scheme <imap>
...@@ -475,7 +430,6 @@ imap://user:passwd@imap.example.net/mbox => SUCCESS ...@@ -475,7 +430,6 @@ imap://user:passwd@imap.example.net/mbox => SUCCESS
475 host <imap.example.net> 430 host <imap.example.net>
476 port 0 431 port 0
477 path <mbox> 432 path <mbox>
478 query <>
479 433
480 imap://user;auth=*@imap.example.net/mbox => SUCCESS 434 imap://user;auth=*@imap.example.net/mbox => SUCCESS
481 scheme <imap> 435 scheme <imap>
...@@ -485,7 +439,6 @@ imap://user;auth=*@imap.example.net/mbox => SUCCESS ...@@ -485,7 +439,6 @@ imap://user;auth=*@imap.example.net/mbox => SUCCESS
485 host <imap.example.net> 439 host <imap.example.net>
486 port 0 440 port 0
487 path <mbox> 441 path <mbox>
488 query <>
489 442
490 imap://imap.example.net:111/mbox => SUCCESS 443 imap://imap.example.net:111/mbox => SUCCESS
491 scheme <imap> 444 scheme <imap>
...@@ -495,7 +448,6 @@ imap://imap.example.net:111/mbox => SUCCESS ...@@ -495,7 +448,6 @@ imap://imap.example.net:111/mbox => SUCCESS
495 host <imap.example.net> 448 host <imap.example.net>
496 port 111 449 port 111
497 path <mbox> 450 path <mbox>
498 query <>
499 451
500 imap://user@imap.example.net:111/mbox => SUCCESS 452 imap://user@imap.example.net:111/mbox => SUCCESS
501 scheme <imap> 453 scheme <imap>
...@@ -505,7 +457,6 @@ imap://user@imap.example.net:111/mbox => SUCCESS ...@@ -505,7 +457,6 @@ imap://user@imap.example.net:111/mbox => SUCCESS
505 host <imap.example.net> 457 host <imap.example.net>
506 port 111 458 port 111
507 path <mbox> 459 path <mbox>
508 query <>
509 460
510 imap://user:passwd@imap.example.net:111/mbox => SUCCESS 461 imap://user:passwd@imap.example.net:111/mbox => SUCCESS
511 scheme <imap> 462 scheme <imap>
...@@ -515,7 +466,6 @@ imap://user:passwd@imap.example.net:111/mbox => SUCCESS ...@@ -515,7 +466,6 @@ imap://user:passwd@imap.example.net:111/mbox => SUCCESS
515 host <imap.example.net> 466 host <imap.example.net>
516 port 111 467 port 111
517 path <mbox> 468 path <mbox>
518 query <>
519 469
520 imap://user;auth=*@imap.example.net:111/mbox => SUCCESS 470 imap://user;auth=*@imap.example.net:111/mbox => SUCCESS
521 scheme <imap> 471 scheme <imap>
...@@ -525,7 +475,6 @@ imap://user;auth=*@imap.example.net:111/mbox => SUCCESS ...@@ -525,7 +475,6 @@ imap://user;auth=*@imap.example.net:111/mbox => SUCCESS
525 host <imap.example.net> 475 host <imap.example.net>
526 port 111 476 port 111
527 path <mbox> 477 path <mbox>
528 query <>
529 478
530 imap://imap.example.net/mbox/user@host => SUCCESS 479 imap://imap.example.net/mbox/user@host => SUCCESS
531 scheme <imap> 480 scheme <imap>
...@@ -535,7 +484,6 @@ imap://imap.example.net/mbox/user@host => SUCCESS ...@@ -535,7 +484,6 @@ imap://imap.example.net/mbox/user@host => SUCCESS
535 host <host> 484 host <host>
536 port 0 485 port 0
537 path <> 486 path <>
538 query <>
539 487
540 imap://user@imap.example.net/mbox/user@host => SUCCESS 488 imap://user@imap.example.net/mbox/user@host => SUCCESS
541 scheme <imap> 489 scheme <imap>
...@@ -545,7 +493,6 @@ imap://user@imap.example.net/mbox/user@host => SUCCESS ...@@ -545,7 +493,6 @@ imap://user@imap.example.net/mbox/user@host => SUCCESS
545 host <imap.example.net> 493 host <imap.example.net>
546 port 0 494 port 0
547 path <mbox/user@host> 495 path <mbox/user@host>
548 query <>
549 496
550 imap://user:passwd@imap.example.net/mbox/user@host => SUCCESS 497 imap://user:passwd@imap.example.net/mbox/user@host => SUCCESS
551 scheme <imap> 498 scheme <imap>
...@@ -555,7 +502,6 @@ imap://user:passwd@imap.example.net/mbox/user@host => SUCCESS ...@@ -555,7 +502,6 @@ imap://user:passwd@imap.example.net/mbox/user@host => SUCCESS
555 host <imap.example.net> 502 host <imap.example.net>
556 port 0 503 port 0
557 path <mbox/user@host> 504 path <mbox/user@host>
558 query <>
559 505
560 imap://user;auth=*@imap.example.net/mbox/user@host => SUCCESS 506 imap://user;auth=*@imap.example.net/mbox/user@host => SUCCESS
561 scheme <imap> 507 scheme <imap>
...@@ -565,7 +511,6 @@ imap://user;auth=*@imap.example.net/mbox/user@host => SUCCESS ...@@ -565,7 +511,6 @@ imap://user;auth=*@imap.example.net/mbox/user@host => SUCCESS
565 host <imap.example.net> 511 host <imap.example.net>
566 port 0 512 port 0
567 path <mbox/user@host> 513 path <mbox/user@host>
568 query <>
569 514
570 imap://imap.example.net:111/mbox/user@host => SUCCESS 515 imap://imap.example.net:111/mbox/user@host => SUCCESS
571 scheme <imap> 516 scheme <imap>
...@@ -575,7 +520,6 @@ imap://imap.example.net:111/mbox/user@host => SUCCESS ...@@ -575,7 +520,6 @@ imap://imap.example.net:111/mbox/user@host => SUCCESS
575 host <host> 520 host <host>
576 port 0 521 port 0
577 path <> 522 path <>
578 query <>
579 523
580 imap://user@imap.example.net:111/mbox/user@host => SUCCESS 524 imap://user@imap.example.net:111/mbox/user@host => SUCCESS
581 scheme <imap> 525 scheme <imap>
...@@ -585,7 +529,6 @@ imap://user@imap.example.net:111/mbox/user@host => SUCCESS ...@@ -585,7 +529,6 @@ imap://user@imap.example.net:111/mbox/user@host => SUCCESS
585 host <imap.example.net> 529 host <imap.example.net>
586 port 111 530 port 111
587 path <mbox/user@host> 531 path <mbox/user@host>
588 query <>
589 532
590 imap://user:passwd@imap.example.net:111/mbox/user@host => SUCCESS 533 imap://user:passwd@imap.example.net:111/mbox/user@host => SUCCESS
591 scheme <imap> 534 scheme <imap>
...@@ -595,7 +538,6 @@ imap://user:passwd@imap.example.net:111/mbox/user@host => SUCCESS ...@@ -595,7 +538,6 @@ imap://user:passwd@imap.example.net:111/mbox/user@host => SUCCESS
595 host <imap.example.net> 538 host <imap.example.net>
596 port 111 539 port 111
597 path <mbox/user@host> 540 path <mbox/user@host>
598 query <>
599 541
600 imap://user;auth=*@imap.example.net:111/mbox/user@host => SUCCESS 542 imap://user;auth=*@imap.example.net:111/mbox/user@host => SUCCESS
601 scheme <imap> 543 scheme <imap>
...@@ -605,7 +547,6 @@ imap://user;auth=*@imap.example.net:111/mbox/user@host => SUCCESS ...@@ -605,7 +547,6 @@ imap://user;auth=*@imap.example.net:111/mbox/user@host => SUCCESS
605 host <imap.example.net> 547 host <imap.example.net>
606 port 111 548 port 111
607 path <mbox/user@host> 549 path <mbox/user@host>
608 query <>
609 550
610 ftp://ftp.example.org/mbox/user%40host => SUCCESS 551 ftp://ftp.example.org/mbox/user%40host => SUCCESS
611 scheme <ftp> 552 scheme <ftp>
...@@ -615,7 +556,6 @@ ftp://ftp.example.org/mbox/user%40host => SUCCESS ...@@ -615,7 +556,6 @@ ftp://ftp.example.org/mbox/user%40host => SUCCESS
615 host <ftp.example.org> 556 host <ftp.example.org>
616 port 0 557 port 0
617 path <mbox/user@host> 558 path <mbox/user@host>
618 query <>
619 559
620 ftp://ftp.example.org:111/mbox/user%40host => SUCCESS 560 ftp://ftp.example.org:111/mbox/user%40host => SUCCESS
621 scheme <ftp> 561 scheme <ftp>
...@@ -625,7 +565,6 @@ ftp://ftp.example.org:111/mbox/user%40host => SUCCESS ...@@ -625,7 +565,6 @@ ftp://ftp.example.org:111/mbox/user%40host => SUCCESS
625 host <ftp.example.org> 565 host <ftp.example.org>
626 port 111 566 port 111
627 path <mbox/user@host> 567 path <mbox/user@host>
628 query <>
629 568
630 ftp://ftp.example.org:111/mbox/user%40host;type=pass => SUCCESS 569 ftp://ftp.example.org:111/mbox/user%40host;type=pass => SUCCESS
631 scheme <ftp> 570 scheme <ftp>
...@@ -636,7 +575,6 @@ ftp://ftp.example.org:111/mbox/user%40host;type=pass => SUCCESS ...@@ -636,7 +575,6 @@ ftp://ftp.example.org:111/mbox/user%40host;type=pass => SUCCESS
636 port 111 575 port 111
637 path <mbox/user@host> 576 path <mbox/user@host>
638 param[0] <type=pass> 577 param[0] <type=pass>
639 query <>
640 578
641 mbox:/var/spool/mail;type=index;param=2;user=gray => SUCCESS 579 mbox:/var/spool/mail;type=index;param=2;user=gray => SUCCESS
642 scheme <mbox> 580 scheme <mbox>
...@@ -649,7 +587,6 @@ mbox:/var/spool/mail;type=index;param=2;user=gray => SUCCESS ...@@ -649,7 +587,6 @@ mbox:/var/spool/mail;type=index;param=2;user=gray => SUCCESS
649 param[0] <type=index> 587 param[0] <type=index>
650 param[1] <param=2> 588 param[1] <param=2>
651 param[2] <user=gray> 589 param[2] <user=gray>
652 query <>
653 590
654 mbox:///var/spool/mail;type=index;param=2;user=gray => SUCCESS 591 mbox:///var/spool/mail;type=index;param=2;user=gray => SUCCESS
655 scheme <mbox> 592 scheme <mbox>
...@@ -662,6 +599,31 @@ mbox:///var/spool/mail;type=index;param=2;user=gray => SUCCESS ...@@ -662,6 +599,31 @@ mbox:///var/spool/mail;type=index;param=2;user=gray => SUCCESS
662 param[0] <type=index> 599 param[0] <type=index>
663 param[1] <param=2> 600 param[1] <param=2>
664 param[2] <user=gray> 601 param[2] <user=gray>
665 query <> 602
603 http:///gnu.org.ua/home/gray?prog&arg1&arg2
604 scheme <http>
605 user <>
606 passwd <>
607 auth <>
608 host <gnu.org.ua>
609 port 0
610 path <home/gray>
611 query[0] <prog>
612 query[1] <arg1>
613 query[2] <arg2>
614
615 http:///gnu.org.ua/home/gray;foo=bar;baz=qux?prog&arg%201&arg%202
616 scheme <http>
617 user <>
618 passwd <>
619 auth <>
620 host <gnu.org.ua>
621 port 0
622 path <home/gray>
623 param[0] <foo=bar>
624 param[1] <baz=qux>
625 query[0] <prog>
626 query[1] <arg 1>
627 query[2] <arg 2>
666 628
667 # NOTE: This file must end with an empty line 629 # NOTE: This file must end with an empty line
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001, 2007, 2008 Free Software Foundation, Inc.
3 3
4 This library is free software; you can redistribute it and/or 4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public 5 modify it under the terms of the GNU Lesser General Public
...@@ -33,14 +33,56 @@ ...@@ -33,14 +33,56 @@
33 #include <mailutils/argcv.h> 33 #include <mailutils/argcv.h>
34 #include <url0.h> 34 #include <url0.h>
35 35
36 /* 36 #define AC2(a,b) a ## b
37 TODO: implement functions to create a url and encode it properly. 37 #define AC4(a,b,c,d) a ## b ## c ## d
38 */
39 38
40 static int url_parse0 (mu_url_t, char *); 39 static int url_parse0 (mu_url_t, char *);
41 40
41 static int
42 parse_query (const char *query,
43 char *delim,
44 int *pargc, char ***pargv, const char **pend)
45 {
46 size_t count, i;
47 char **v;
48 const char *p;
49
50 for (p = query, count = 0; ; count++)
51 {
52 size_t len = strcspn (p, delim);
53 p += len;
54 if (!*p || *p == delim[1])
55 break;
56 p++;
57 }
58
59 if (pend)
60 *pend = p;
61 if (p == query)
62 return 0;
63 count++;
64
65 v = calloc (count + 1, sizeof (v[0]));
66 for (i = 0, p = query; i < count; i++)
67 {
68 size_t len = strcspn (p, delim);
69 v[i] = mu_url_decode_len (p, len);
70 if (v[i] == NULL)
71 {
72 mu_argcv_free (i, v);
73 return 1;
74 }
75 p += len + 1;
76 }
77 v[i] = NULL;
78
79 *pargc = count;
80 *pargv = v;
81 return 0;
82 }
83
42 int 84 int
43 mu_url_create (mu_url_t * purl, const char *name) 85 mu_url_create (mu_url_t *purl, const char *name)
44 { 86 {
45 mu_url_t url = calloc (1, sizeof (*url)); 87 mu_url_t url = calloc (1, sizeof (*url));
46 if (url == NULL) 88 if (url == NULL)
...@@ -56,6 +98,89 @@ mu_url_create (mu_url_t * purl, const char *name) ...@@ -56,6 +98,89 @@ mu_url_create (mu_url_t * purl, const char *name)
56 return 0; 98 return 0;
57 } 99 }
58 100
101 static char **
102 argcv_copy (size_t argc, char **argv)
103 {
104 size_t i;
105 char **nv = calloc (argc + 1, sizeof (nv[0]));
106 if (!nv)
107 return NULL;
108 for (i = 0; i < argc; i++)
109 if ((nv[i] = strdup (argv[i])) == NULL)
110 {
111 mu_argcv_free (i, nv);
112 free (nv);
113 return NULL;
114 }
115 return nv;
116 }
117
118 static int
119 mu_url_copy0 (mu_url_t old_url, mu_url_t new_url)
120 {
121 const char *str;
122 size_t argc;
123 char **argv;
124 int rc;
125
126 #define URLCOPY(what) \
127 do \
128 { \
129 rc = AC2(mu_url_sget_,what) (old_url, &str); \
130 if (rc == 0) \
131 { \
132 if ((new_url->what = strdup (str)) == NULL) \
133 return ENOMEM; \
134 } \
135 else if (rc != MU_ERR_NOENT) \
136 return rc; \
137 } \
138 while (0);
139
140 URLCOPY (scheme);
141 URLCOPY (user);
142 URLCOPY (passwd);
143 URLCOPY (auth);
144 URLCOPY (host);
145 new_url->port = old_url->port;
146 URLCOPY (path);
147
148 rc = mu_url_sget_fvpairs (old_url, &argc, &argv);
149 if (rc == 0 && argc)
150 {
151 if ((new_url->fvpairs = argcv_copy (argc, argv)) == NULL)
152 return ENOMEM;
153 new_url->fvcount = argc;
154 }
155
156 rc = mu_url_sget_query (old_url, &argc, &argv);
157 if (rc == 0 && argc)
158 {
159 if ((new_url->qargv = argcv_copy (argc, argv)) == NULL)
160 return ENOMEM;
161 new_url->qargc = argc;
162 }
163 return 0;
164 #undef URLCOPY
165 }
166
167 int
168 mu_url_dup (mu_url_t old_url, mu_url_t *new_url)
169 {
170 mu_url_t url;
171 int rc = mu_url_create (&url, mu_url_to_string (old_url));
172
173 if (rc)
174 return rc;
175
176 rc = mu_url_copy0 (old_url, url);
177 if (rc == 0)
178 *new_url = url;
179 else
180 mu_url_destroy (&url);
181 return rc;
182 }
183
59 void 184 void
60 mu_url_destroy (mu_url_t * purl) 185 mu_url_destroy (mu_url_t * purl)
61 { 186 {
...@@ -90,8 +215,7 @@ mu_url_destroy (mu_url_t * purl) ...@@ -90,8 +215,7 @@ mu_url_destroy (mu_url_t * purl)
90 if (url->fvcount) 215 if (url->fvcount)
91 mu_argcv_free (url->fvcount, url->fvpairs); 216 mu_argcv_free (url->fvcount, url->fvpairs);
92 217
93 if (url->query) 218 mu_argcv_free (url->qargc, url->qargv);
94 free (url->query);
95 219
96 free (url); 220 free (url);
97 221
...@@ -112,7 +236,7 @@ mu_url_parse (mu_url_t url) ...@@ -112,7 +236,7 @@ mu_url_parse (mu_url_t url)
112 memset (&u, 0, sizeof u); 236 memset (&u, 0, sizeof u);
113 /* can't have been parsed already */ 237 /* can't have been parsed already */
114 if (url->scheme || url->user || url->passwd || url->auth || 238 if (url->scheme || url->user || url->passwd || url->auth ||
115 url->host || url->path || url->query) 239 url->host || url->path || url->qargc)
116 return EINVAL; 240 return EINVAL;
117 241
118 n = strdup (url->name); 242 n = strdup (url->name);
...@@ -148,10 +272,14 @@ mu_url_parse (mu_url_t url) ...@@ -148,10 +272,14 @@ mu_url_parse (mu_url_t url)
148 UALLOC (auth); 272 UALLOC (auth);
149 UALLOC (host); 273 UALLOC (host);
150 UALLOC (path); 274 UALLOC (path);
151 UALLOC (query); 275
152 #undef UALLOC 276 #undef UALLOC
153 url->fvcount = u.fvcount; 277 url->fvcount = u.fvcount;
154 url->fvpairs = u.fvpairs; 278 url->fvpairs = u.fvpairs;
279
280 url->qargc = u.qargc;
281 url->qargv = u.qargv;
282
155 url->port = u.port; 283 url->port = u.port;
156 } 284 }
157 285
...@@ -168,7 +296,8 @@ CLEANUP: ...@@ -168,7 +296,8 @@ CLEANUP:
168 UFREE (url->auth); 296 UFREE (url->auth);
169 UFREE (url->host); 297 UFREE (url->host);
170 UFREE (url->path); 298 UFREE (url->path);
171 UFREE (url->query); 299 mu_argcv_free (url->fvcount, url->fvpairs);
300 mu_argcv_free (url->qargc, url->qargv);
172 #undef UFREE 301 #undef UFREE
173 } 302 }
174 303
...@@ -213,6 +342,19 @@ url_parse0 (mu_url_t u, char *name) ...@@ -213,6 +342,19 @@ url_parse0 (mu_url_t u, char *name)
213 { 342 {
214 u->scheme = "file"; 343 u->scheme = "file";
215 } 344 }
345 else if (name[0] == '|')
346 {
347 int rc;
348 u->scheme = "prog";
349 rc = mu_argcv_get (name + 1, NULL, NULL, &u->qargc, &u->qargv);
350 if (rc == 0)
351 {
352 u->path = strdup (u->qargv[0]);
353 if (!u->path)
354 rc = ENOMEM;
355 }
356 return rc;
357 }
216 else 358 else
217 { 359 {
218 /* Parse out the SCHEME. */ 360 /* Parse out the SCHEME. */
...@@ -318,15 +460,16 @@ url_parse0 (mu_url_t u, char *name) ...@@ -318,15 +460,16 @@ url_parse0 (mu_url_t u, char *name)
318 if (*p == ';') 460 if (*p == ';')
319 { 461 {
320 *p++ = 0; 462 *p++ = 0;
321 mu_argcv_get_np (p, strlen (p), ";", "?", 0, 463 if (parse_query (p, ";?", &u->fvcount, &u->fvpairs, (const char **)&p))
322 &u->fvcount, &u->fvpairs, &p); 464 return ENOMEM;
323 } 465 }
324 466
325 if (*p == '?') 467 if (*p == '?')
326 { 468 {
327 /* found a query */ 469 /* found a query */
328 *p++ = 0; 470 *p++ = 0;
329 u->query = p; 471 if (parse_query (p, "&", &u->qargc, &u->qargv, NULL))
472 return ENOMEM;
330 } 473 }
331 474
332 return 0; 475 return 0;
...@@ -334,8 +477,6 @@ url_parse0 (mu_url_t u, char *name) ...@@ -334,8 +477,6 @@ url_parse0 (mu_url_t u, char *name)
334 477
335 478
336 /* General accessors: */ 479 /* General accessors: */
337 #define AC2(a,b) a ## b
338 #define AC4(a,b,c,d) a ## b ## c ## d
339 #define ACCESSOR(action,field) AC4(mu_url_,action,_,field) 480 #define ACCESSOR(action,field) AC4(mu_url_,action,_,field)
340 481
341 #define DECL_SGET(field) \ 482 #define DECL_SGET(field) \
...@@ -453,7 +594,45 @@ DECL_ACCESSORS (passwd) ...@@ -453,7 +594,45 @@ DECL_ACCESSORS (passwd)
453 DECL_ACCESSORS (auth) 594 DECL_ACCESSORS (auth)
454 DECL_ACCESSORS (host) 595 DECL_ACCESSORS (host)
455 DECL_ACCESSORS (path) 596 DECL_ACCESSORS (path)
456 DECL_ACCESSORS (query) 597
598 int
599 mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv)
600 {
601 if (url == NULL)
602 return EINVAL;
603 /* See FIXME below */
604 *qc = url->qargc;
605 *qv = url->qargv;
606 return 0;
607 }
608
609 int
610 mu_url_aget_query (const mu_url_t url, size_t *qc, char ***qv)
611 {
612 size_t qargc, i;
613 char **qargv;
614 char **qcopy;
615
616 int rc = mu_url_sget_fvpairs (url, &qargc, &qargv);
617 if (rc)
618 return rc;
619
620 qcopy = calloc (qargc + 1, sizeof (qcopy[0]));
621 if (!qcopy)
622 return errno;
623 for (i = 0; i < qargc; i++)
624 {
625 if (!(qcopy[i] = strdup (qargv[i])))
626 {
627 mu_argcv_free (i, qcopy);
628 return errno;
629 }
630 }
631 qcopy[i] = NULL;
632 *qc = qargc;
633 *qv = qcopy;
634 return 0;
635 }
457 636
458 /* field-value pairs accessors */ 637 /* field-value pairs accessors */
459 int 638 int
...@@ -507,7 +686,6 @@ mu_url_get_port (const mu_url_t url, long *pport) ...@@ -507,7 +686,6 @@ mu_url_get_port (const mu_url_t url, long *pport)
507 return 0; 686 return 0;
508 } 687 }
509 688
510
511 const char * 689 const char *
512 mu_url_to_string (const mu_url_t url) 690 mu_url_to_string (const mu_url_t url)
513 { 691 {
...@@ -517,6 +695,19 @@ mu_url_to_string (const mu_url_t url) ...@@ -517,6 +695,19 @@ mu_url_to_string (const mu_url_t url)
517 } 695 }
518 696
519 int 697 int
698 mu_url_set_scheme (mu_url_t url, const char *scheme)
699 {
700 char *p;
701 if (!url || !scheme)
702 return EINVAL;
703 p = realloc (url->scheme, strlen (scheme) + 1);
704 if (!p)
705 return ENOMEM;
706 strcpy (url->scheme, scheme);
707 return 0;
708 }
709
710 int
520 mu_url_is_scheme (mu_url_t url, const char *scheme) 711 mu_url_is_scheme (mu_url_t url, const char *scheme)
521 { 712 {
522 if (url && scheme && url->scheme && strcasecmp (url->scheme, scheme) == 0) 713 if (url && scheme && url->scheme && strcasecmp (url->scheme, scheme) == 0)
...@@ -537,12 +728,13 @@ mu_url_is_same_port (mu_url_t url1, mu_url_t url2) ...@@ -537,12 +728,13 @@ mu_url_is_same_port (mu_url_t url1, mu_url_t url2)
537 728
538 /* From RFC 1738, section 2.2 */ 729 /* From RFC 1738, section 2.2 */
539 char * 730 char *
540 mu_url_decode (const char *s) 731 mu_url_decode_len (const char *s, size_t len)
541 { 732 {
542 char *d = strdup (s); 733 char *d;
543 const char *eos = s + strlen (s); 734 const char *eos = s + len;
544 int i; 735 int i;
545 736
737 d = malloc (len + 1);
546 if (!d) 738 if (!d)
547 return NULL; 739 return NULL;
548 740
...@@ -576,6 +768,12 @@ mu_url_decode (const char *s) ...@@ -576,6 +768,12 @@ mu_url_decode (const char *s)
576 return d; 768 return d;
577 } 769 }
578 770
771 char *
772 mu_url_decode (const char *s)
773 {
774 return mu_url_decode_len (s, strlen (s));
775 }
776
579 static int 777 static int
580 defined (const char *s) 778 defined (const char *s)
581 { 779 {
......