Adding upstream version 6.01~pre5+dfsg.
[syslinux-debian/hramrach.git] / core / fs / pxe / urlparse.c
blob6b73ddb6f1f41c8ef20dd5da185246ce80071663
1 /* ----------------------------------------------------------------------- *
3 * Copyright 2009-2011 Intel Corporation; author: H. Peter Anvin
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation
7 * files (the "Software"), to deal in the Software without
8 * restriction, including without limitation the rights to use,
9 * copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following
12 * conditions:
14 * The above copyright notice and this permission notice shall
15 * be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
26 * ----------------------------------------------------------------------- */
29 * urlparse.c
32 #include <string.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include "url.h"
38 * Return the type of a URL without modifying the string
40 enum url_type url_type(const char *url)
42 const char *q;
44 q = strchr(url, ':');
45 if (!q)
46 return URL_SUFFIX;
48 if (q[1] == '/' && q[2] == '/')
49 return URL_NORMAL;
51 if (q[1] == ':')
52 return URL_OLD_TFTP;
54 return URL_SUFFIX;
58 * Decompose a URL into its components. This is done in-place;
59 * this routine does not allocate any additional storage. Freeing the
60 * original buffer frees all storage used.
62 void parse_url(struct url_info *ui, char *url)
64 char *p = url;
65 char *q, *r, *s;
66 int c;
68 memset(ui, 0, sizeof *ui);
70 q = strchr(p, ':');
71 if (q && (q[1] == '/' && q[2] == '/')) {
72 ui->type = URL_NORMAL;
74 ui->scheme = p;
75 *q = '\0';
76 p = q+3;
78 q = strchr(p, '/');
79 if (q) {
80 *q = '\0';
81 ui->path = q+1;
82 q = strchr(q+1, '#');
83 if (q)
84 *q = '\0';
85 } else {
86 ui->path = "";
89 r = strchr(p, '@');
90 if (r) {
91 ui->user = p;
92 *r = '\0';
93 s = strchr(p, ':');
94 if (s) {
95 *s = '\0';
96 ui->passwd = s+1;
98 p = r+1;
101 ui->host = p;
102 r = strchr(p, ':');
103 if (r) {
104 *r++ = '\0';
105 ui->port = 0;
106 while ((c = *r++)) {
107 c -= '0';
108 if (c > 9)
109 break;
110 ui->port = ui->port * 10 + c;
113 } else if (q && q[1] == ':') {
114 *q = '\0';
115 ui->scheme = "tftp";
116 ui->host = p;
117 ui->path = q+2;
118 ui->type = URL_OLD_TFTP;
119 } else {
120 ui->path = p;
121 ui->type = URL_SUFFIX;
126 * Escapes unsafe characters in a URL.
127 * This does *not* escape things like query characters!
128 * Returns the number of characters in the total output.
130 size_t url_escape_unsafe(char *output, const char *input, size_t bufsize)
132 static const char uchexchar[] = "0123456789ABCDEF";
133 const char *p;
134 unsigned char c;
135 char *q;
136 size_t n = 0;
138 q = output;
139 for (p = input; (c = *p); p++) {
140 if (c <= ' ' || c > '~') {
141 if (++n < bufsize) *q++ = '%';
142 if (++n < bufsize) *q++ = uchexchar[c >> 4];
143 if (++n < bufsize) *q++ = uchexchar[c & 15];
144 } else {
145 if (++n < bufsize) *q++ = c;
149 *q = '\0';
150 return n;
153 static int hexdigit(char c)
155 if (c >= '0' && c <= '9')
156 return c - '0';
157 c |= 0x20;
158 if (c >= 'a' && c <= 'f')
159 return c - 'a' + 10;
160 return -1;
164 * Unescapes a buffer, optionally ending at an *unescaped* terminator
165 * (like ; for TFTP). The unescaping is done in-place.
167 * If a terminator is reached, return a pointer to the first character
168 * after the terminator.
170 char *url_unescape(char *buffer, char terminator)
172 char *p = buffer;
173 char *q = buffer;
174 unsigned char c;
175 int x, y;
177 while ((c = *p)) {
178 if (c == terminator) {
179 *q = '\0';
180 return p;
182 p++;
183 if (c == '%') {
184 x = hexdigit(p[0]);
185 if (x >= 0) {
186 y = hexdigit(p[1]);
187 if (y >= 0) {
188 *q++ = (x << 4) + y;
189 p += 2;
190 continue;
194 *q++ = c;
196 *q = '\0';
197 return NULL;
200 #ifdef URL_TEST
202 int main(int argc, char *argv[])
204 int i;
205 struct url_info url;
207 for (i = 1; i < argc; i++) {
208 parse_url(&url, argv[i]);
209 printf("scheme: %s\n"
210 "user: %s\n"
211 "passwd: %s\n"
212 "host: %s\n"
213 "port: %d\n"
214 "path: %s\n"
215 "type: %d\n",
216 url.scheme, url.user, url.passwd, url.host, url.port,
217 url.path, url.type);
220 return 0;
223 #endif