Annotation of libaitwww/src/tools.c, revision 1.4.4.1
1.1 misho 1: /*************************************************************************
2: * (C) 2012 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
3: * by Michael Pounov <misho@elwix.org>
4: *
5: * $Author: misho $
1.4.4.1 ! misho 6: * $Id: tools.c,v 1.4 2012/09/20 14:19:45 misho Exp $
1.1 misho 7: *
8: **************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
1.4.4.1 ! misho 15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
1.1 misho 16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
46: #include "global.h"
47:
48:
1.3 misho 49: /*
50: * www_cmp() - Compare two string
51: *
52: * @ct = content text from www
53: * @s = string
54: * return: 0 are equal or !0 are different
55: */
1.1 misho 56: int
57: www_cmp(const char *ct, const char *s)
58: {
59: char *sc;
60:
61: assert(ct && s);
62:
1.3 misho 63: while (isspace((int) *ct))
1.1 misho 64: ct++;
65:
66: if (!(sc = strchr(ct, ';')))
67: sc = strchr(ct, '\x0');
1.3 misho 68: while (isspace((int) *(sc - 1)))
1.1 misho 69: sc--;
70:
71: if (strlen(s) != sc - ct)
72: return -1;
73: return strncasecmp(ct, s, sc - ct);
74: }
75:
1.3 misho 76: /*
77: * www_cmptype() - Compare context type
78: *
79: * @ct = content text from www
80: * @type = content type
81: * return: 0 are equal or !0 are different
82: */
1.1 misho 83: int
84: www_cmptype(const char *ct, const char *type)
85: {
86: char *sl;
87:
88: assert(ct && type);
89:
1.3 misho 90: while (isspace((int) *ct))
1.1 misho 91: ct++;
92:
93: if (!(sl = strchr(ct, '/')))
94: return -1;
95:
96: if (strlen(type) != sl - ct)
97: return 1;
98: return strncasecmp(ct, type, sl - ct);
99: }
100:
1.3 misho 101: /*
102: * www_getpair() - Get AV pair from WWW query string
103: *
104: * @str = query string
105: * @delim = delimiter
1.4.4.1 ! misho 106: * return: NULL error or AV pair, must be e_free() after use!
1.3 misho 107: */
108: ait_val_t *
1.1 misho 109: www_getpair(char ** __restrict str, const char *delim)
110: {
1.3 misho 111: char *tr;
1.1 misho 112: int cx;
1.3 misho 113: ait_val_t *s;
1.1 misho 114:
115: assert(str && *str && delim);
116:
1.4.4.1 ! misho 117: s = ait_allocVar();
1.3 misho 118: if (!s) {
1.4.4.1 ! misho 119: www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
1.3 misho 120: return NULL;
121: }
122:
1.1 misho 123: cx = strcspn(*str, delim);
124: tr = *str + cx;
1.3 misho 125: if (*tr)
126: *tr++ = 0;
1.1 misho 127:
1.3 misho 128: AIT_SET_STR(s, *str);
1.1 misho 129:
130: *str = tr;
131: return s;
132: }
133:
1.3 misho 134: /*
135: * www_x2c() - Hex from string to digit
136: *
137: * @str = string
138: * return: digit
139: */
1.1 misho 140: inline char
141: www_x2c(const char *str)
142: {
143: register char digit;
144:
145: assert(str);
146:
147: digit = (str[0] >= 'A' ? ((str[0] & 0xdf) - 'A') + 10 : (str[0] - '0'));
148: digit *= 16;
149: digit += (str[1] >= 'A' ? ((str[1] & 0xdf) - 'A') + 10 : (str[1] - '0'));
150:
151: return digit;
152: }
153:
1.3 misho 154: /*
155: * www_unescape() - Unescape/decode WWW query string to host string
156: *
157: * @str = string
158: * return: none
159: */
1.1 misho 160: inline void
161: www_unescape(char * __restrict str)
162: {
163: register int i, j;
164:
1.3 misho 165: if (!str)
166: return;
1.1 misho 167:
168: for (i = j = 0; str[j]; i++, j++) {
169: str[i] = str[j];
170:
171: if (str[j] == '+')
172: str[i] = ' ';
173: else if (str[j] == '%') {
174: str[i] = www_x2c(&str[j + 1]);
175: j += 2;
176: }
177: }
178:
179: str[i] = 0;
180: }
1.4 misho 181:
182: /*
183: * www_undot() - Undotted and clean WWW query filename
184: *
185: * @pname = query filename
1.4.4.1 ! misho 186: * return: =NULL error or !=NULL allocated valid filename, after use you must call ait_freeVar()
1.4 misho 187: */
188: ait_val_t *
189: www_undot(const char * __restrict pname)
190: {
191: char *s, *s2, *fname;
192: int l;
193: ait_val_t *v;
194:
195: if (!pname)
196: return NULL;
197: /* check for valid query filename */
198: if (*pname != '/')
199: return NULL;
200:
1.4.4.1 ! misho 201: v = ait_allocVar();
1.4 misho 202: if (!v) {
1.4.4.1 ! misho 203: www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
1.4 misho 204: return NULL;
205: } else {
206: AIT_SET_STR(v, pname + 1);
207: fname = AIT_GET_STR(v);
208: }
209:
210: /* collapse / sequences */
211: if ((s = strstr(fname, "//"))) {
212: s2 = s + 1;
213: for (s2 = ++s; *s2 == '/'; s2++);
214: memmove(s, s2, strlen(s2) + 1);
215: }
216:
217: /* escaped ./ and /./ sequences */
218: while (!strncmp(fname, "./", 2))
219: memmove(fname, fname + 2, strlen(fname + 1));
220: while ((s = strstr(fname, "/./")))
221: memmove(s, s + 2, strlen(s + 1));
222:
223: /* alternate between removing leading ../ and removing xxx/../ */
224: while (42) {
225: while (!strncmp(fname, "../", 3))
226: memmove(fname, fname + 3, strlen(fname + 2));
227: if (!(s = strstr(fname, "/../")))
228: break;
229: for (s2 = s - 1; s2 >= fname && *s2 != '/'; --s2);
230: memmove(s2 + 1, s + 4, strlen(s + 3));
231: }
232:
233: /* elide any /.. at the end */
234: while ((l = strlen(fname)) > 3 &&
235: !strcmp((s = fname + l - 3), "/..")) {
236: for (s2 = s - 1; s2 >= fname && *s2 != '/'; --s2);
237: if (s2 < fname)
238: break;
239: *s2 = 0;
240: }
241:
242: /* if filename is empry add current dir */
243: if (!*fname) {
244: AIT_FREE_VAL(v);
245: AIT_SET_STR(v, "./");
246: fname = AIT_GET_STR(v);
247: }
248:
249: /* check for valid filename */
250: if (*fname == '/' || (fname[0] == '.' && fname[1] == '.' &&
251: (!fname[2] || fname[2] == '/'))) {
1.4.4.1 ! misho 252: ait_freeVar(&v);
1.4 misho 253: return NULL;
254: }
255:
256: return v;
257: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>