File:  [ELWIX - Embedded LightWeight unIX -] / libaitio / src / Attic / url.c
Revision 1.6: download - view: text, annotated - select for diffs - revision graph
Wed Apr 20 22:56:32 2011 UTC (13 years, 2 months ago) by misho
Branches: MAIN
CVS tags: io2_4, io2_3, io2_2, io2_1, io2_0, io1_9, io1_8, IO2_3, IO2_2, IO2_1, IO2_0, IO1_9, IO1_8, IO1_7, HEAD
Release 1.7

    1: /*************************************************************************
    2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
    3: *  by Michael Pounov <misho@elwix.org>
    4: *
    5: * $Author: misho $
    6: * $Id: url.c,v 1.6 2011/04/20 22:56:32 misho Exp $
    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: 
   15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
   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: 
   49: /*
   50:  * ioURLGet() Parse and get data from input URL
   51:  * @csURL = Input URL line
   52:  * @url = Output parsed URL
   53:  * return: 0 error format not find tech:// and return URL like path; 
   54:  		-1 error:: can`t read; >0 ok, up bits for known elements
   55: */
   56: int
   57: ioURLGet(const char *csURL, struct tagIOURL *url)
   58: {
   59: 	char *pos, *at, *cl, *sl;
   60: 	int ret = 0;
   61: 
   62: 	if (!url)
   63: 		return -1;
   64: 	else
   65: 		memset(url, 0, sizeof(*url));
   66: 
   67: 	strlcpy((char*) url->url_line, csURL, BUFSIZ);
   68: 	// Tech
   69: 	if (!(pos = strstr((char*) url->url_line, "://"))) {
   70: 		url->url_path.vallen = strlen((char*) url->url_line);
   71: 		url->url_path.value = (char*) url->url_line;
   72: 		return ret;
   73: 	} else {
   74: 		url->url_tech.value = (char*) url->url_line;
   75: 		url->url_tech.vallen = pos - (char*) url->url_line;
   76: 		if (url->url_tech.vallen)
   77: 			ret |= 1;
   78: 
   79: 		*pos = 0;
   80: 		pos += 3;
   81: 	}
   82: 
   83: 	// User
   84: 	if ((at = strchr(pos, '@'))) {
   85: 		*at++ = 0;
   86: 		// Pass
   87: 		if ((cl = strchr(pos, ':'))) {
   88: 			*cl++ = 0;
   89: 
   90: 			url->url_pass.value = cl;
   91: 			url->url_pass.vallen = at - cl - 1;
   92: 			if (url->url_pass.vallen)
   93: 				ret |= 4;
   94: 		} else
   95: 			cl = at;
   96: 
   97: 		url->url_user.value = pos;
   98: 		url->url_user.vallen = cl - pos - 1;
   99: 		if (url->url_user.vallen)
  100: 			ret |= 2;
  101: 
  102: 		pos = at;
  103: 	}
  104: 
  105: 	// Host
  106: 	if ((sl = strchr(pos, '/')))
  107: 		*sl++ = 0;
  108: 	else
  109: 		sl = pos + strlen(pos) + 1;
  110: 	// Port
  111: 	if ((cl = strchr(pos, ':'))) {
  112: 		*cl++ = 0;
  113: 
  114: 		url->url_port.value = cl;
  115: 		url->url_port.vallen = sl - cl - 1;
  116: 		if (url->url_port.vallen)
  117: 			ret |= 16;
  118: 	} else
  119: 		cl = sl;
  120: 
  121: 	url->url_host.value = pos;
  122: 	url->url_host.vallen = cl - pos - 1;
  123: 	if (url->url_host.vallen)
  124: 		ret |= 8;
  125: 
  126: 	pos = sl;
  127: 
  128: 	// Args
  129: 	if ((at = strchr(pos, '?'))) {
  130: 		*at++ = 0;
  131: 
  132: 		url->url_args.value = at;
  133: 		url->url_args.vallen = strlen(at);
  134: 		if (url->url_args.vallen)
  135: 			ret |= 64;
  136: 	} else
  137: 		at = pos + strlen(pos) + 1;
  138: 
  139: 	// Path
  140: 	url->url_path.value = pos;
  141: 	url->url_path.vallen = at - pos - 1;
  142: 	if (url->url_path.vallen)
  143: 		ret |= 32;
  144: 
  145: 	pos = at + strlen(at);
  146: 
  147: 	// Reserved
  148: 	url->url_reserved = pos;
  149: 	if (*pos)
  150: 		ret |= 128;
  151: 
  152: 	return ret;
  153: }
  154: 
  155: /*
  156:  * io_Path2File() Parse and make path/filename pair
  157:  * @csArgs = Input argument line
  158:  * @psPath = Output Path, if ==NULL path not returned
  159:  * @pathLen = Size of path array
  160:  * @psFile = Output File
  161:  * @fileLen = Size of file array
  162:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
  163: */
  164: inline int
  165: io_Path2File(const char * __restrict csArgs, char * __restrict psPath, int pathLen, 
  166: 		char * __restrict psFile, int fileLen)
  167: {
  168: 	char *pos, *psBuf;
  169: 
  170: 	if (!csArgs || !psFile || !fileLen)
  171: 		return -1;
  172: 	if (psPath && !pathLen)
  173: 		return -1;
  174: 	else
  175: 		memset(psPath, 0, pathLen);
  176: 	psBuf = strdup(csArgs);
  177: 	if (!psBuf) {
  178: 		LOGERR;
  179: 		return -1;
  180: 	}
  181: 
  182: 	pos = strrchr(psBuf, '/');
  183: 	if (!pos) {
  184: 		strlcpy(psFile, psBuf, fileLen);
  185: 
  186: 		free(psBuf);
  187: 		return 1;
  188: 	} else
  189: 		*pos++ = 0;
  190: 
  191: 	strlcpy(psFile, pos, fileLen);
  192: 	if (psPath)
  193: 		strlcpy(psPath, psBuf, pathLen);
  194: 
  195: 	free(psBuf);
  196: 	return 2;
  197: }
  198: 
  199: /*
  200:  * ioURLGetValue() Get value from parsed URL
  201:  * @url = Input parsed URL
  202:  * @csAttr = Attribute for search
  203:  * @psValue = Return value of attribute, if ==NULL only check for existence of attribute
  204:  * @valLen = Size of psValue array
  205:  * return: 0 error attribute not find; -1 error:: can`t read; >0 ok, find at position
  206: */
  207: int
  208: ioURLGetValue(struct tagIOURL *url, const char *csAttr, char * __restrict psValue, int valLen)
  209: {
  210: 	register int i, ret = 0;
  211: 	char szBuf[BUFSIZ], szElem[2][BUFSIZ];
  212: 	int len;
  213: 	array_t *items;
  214: 
  215: 	if (!url || !csAttr)
  216: 		return -1;
  217: 
  218: 	strlcpy(szBuf, url->url_args.value, BUFSIZ);
  219: 	if ((len = io_arrayMake(szBuf, 0, "&", &items)) < 1)
  220: 		return ret;
  221: 
  222: 	for (i = 0; i < len && items->arr_data[i]; i++) {
  223: 		if (io_MakeAV(items->arr_data[i], "=", szElem[0], BUFSIZ, szElem[1], BUFSIZ) < 1)
  224: 			continue;
  225: 
  226: 		if (!strcmp(szElem[0], csAttr)) {
  227: 			ret = i + 1;
  228: 			if (psValue && valLen)
  229: 				strlcpy(psValue, szElem[1], valLen);
  230: 			break;
  231: 		}
  232: 	}
  233: 
  234: 	io_arrayDestroy(&items);
  235: 	return ret;
  236: }
  237: 
  238: /*
  239:  * ioURLGetFile() Get file from parsed URL
  240:  * @url = Input parsed URL
  241:  * @psValue = Return filename, if not specified file in url path, replace with /
  242:  * @valLen = Size of psValue array
  243:  * return: -1 error:: can`t read; 0 ok
  244: */
  245: int
  246: ioURLGetFile(struct tagIOURL *url, char * __restrict psValue, int valLen)
  247: {
  248: 	if (!url || !psValue || !valLen)
  249: 		return -1;
  250: 
  251: 	if (io_Path2File(url->url_path.value, NULL, 0, psValue, valLen) < 1)
  252: 		return -1;
  253: 
  254: 	// If not specified file in path, default replace to /
  255: 	if (!*psValue)
  256: 		strlcpy(psValue, "/", valLen);
  257: 	return 0;
  258: }
  259: 
  260: // ------------------------------------------
  261: 
  262: /*
  263:  * ioXMLGet() Parse and get data from input XML request string [ns:]container[|attribute[=value]][?data]
  264:  * @csXML = Input XML request line
  265:  * @xml = Output parsed XML request
  266:  * return: 0 error format incorrect, -1 error:: can`t read; >0 ok readed elements bits
  267: */
  268: int
  269: ioXMLGet(const char *csXML, struct tagReqXML *xml)
  270: {
  271: 	char *pos, *p, *end;
  272: 	int ret = 0;
  273: 
  274: 	if (!csXML || !xml)
  275: 		return -1;
  276: 	else
  277: 		memset(xml, 0, sizeof *xml);
  278: 
  279: 	strlcpy((char*) xml->xml_line, csXML, BUFSIZ);
  280: 	// if namespace present
  281: 	if ((pos = strchr((char*) xml->xml_line, ':'))) {
  282: 		xml->xml_namespace.value = (char*) xml->xml_line;
  283: 		xml->xml_namespace.vallen = pos - (char*) xml->xml_line;
  284: 		if (xml->xml_namespace.vallen)
  285: 			ret |= 1;
  286: 		*pos++ = 0;
  287: 	} else
  288: 		pos = (char*) xml->xml_line;
  289: 	// if container is path
  290: 	if (*pos == '/') {
  291: 		xml->xml_node.path.value = pos;
  292: 		xml->xml_node.path.vallen = strlen(pos);
  293: 		if (!xml->xml_node.path.vallen)
  294: 			ret = 0;
  295: 		else
  296: 			ret |= 32;
  297: 		return ret;
  298: 	} else {
  299: 	// container
  300: 		xml->xml_node.container.value = pos;
  301: 		xml->xml_node.container.vallen = strlen(pos);
  302: 		if (!xml->xml_node.container.vallen)
  303: 			return 0;
  304: 		else
  305: 			ret |= 2;
  306: 	}
  307: 	end = strchr(pos, '?');
  308: 	// if attribute present
  309: 	if (pos && (p = strchr(pos, '|')) && (!end || end > p)) {
  310: 		pos = p;
  311: 		*pos++ = 0;
  312: 		xml->xml_node.container.vallen = strlen(xml->xml_node.container.value);
  313: 		if (!xml->xml_node.container.vallen)
  314: 			return 0;
  315: 
  316: 		xml->xml_attribute.value = pos;
  317: 		xml->xml_attribute.vallen = strlen(pos);
  318: 		if (xml->xml_attribute.vallen)
  319: 			ret |= 4;
  320: 	}
  321: 	// if value present
  322: 	if (pos && (p = strchr(pos, '=')) && (!end || end > p)) {
  323: 		if (!(ret & 4))
  324: 			return 0;
  325: 		else
  326: 			pos = p;
  327: 		*pos++ = 0;
  328: 		xml->xml_attribute.vallen = strlen(xml->xml_attribute.value);
  329: 		if (!xml->xml_attribute.vallen)
  330: 			return 0;
  331: 
  332: 		xml->xml_value.value = pos;
  333: 		xml->xml_value.vallen = strlen(pos);
  334: 		if (xml->xml_value.vallen)
  335: 			ret |= 8;
  336: 	}
  337: 	// if data present
  338: 	if (pos && end) {
  339: 		if (ret < 2)
  340: 			return 0;
  341: 		else
  342: 			pos = end;
  343: 		*pos++ = 0;
  344: 		if (ret & 8) {
  345: 			xml->xml_value.vallen = strlen(xml->xml_value.value);
  346: 			if (!xml->xml_value.vallen)
  347: 				return 0;
  348: 		} else if (ret & 4) {
  349: 			xml->xml_attribute.vallen = strlen(xml->xml_attribute.value);
  350: 			if (!xml->xml_attribute.vallen)
  351: 				return 0;
  352: 		} else if (ret & 2) {
  353: 			xml->xml_node.container.vallen = strlen(xml->xml_node.container.value);
  354: 			if (!xml->xml_node.container.vallen)
  355: 				return 0;
  356: 		} else
  357: 			return 0;
  358: 
  359: 		xml->xml_data.value = pos;
  360: 		xml->xml_data.vallen = strlen(pos);
  361: 		if (xml->xml_data.vallen)
  362: 			ret |= 16;
  363: 	}
  364: 
  365: 	return ret;
  366: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>