Annotation of libaitio/src/url.c, revision 1.2

1.2     ! misho       1: /*************************************************************************
        !             2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
        !             3: *  by Michael Pounov <misho@openbsd-bg.org>
        !             4: *
        !             5: * $Author: misho $
        !             6: * $Id: url.c,v 1.1.2.5 2010/03/04 12:16:39 misho Exp $
        !             7: *
        !             8: *************************************************************************/
        !             9: #include "global.h"
        !            10: 
        !            11: 
        !            12: /*
        !            13:  * ioURLGet() Parse and get data from input URL
        !            14:  * @csURL = Input URL line
        !            15:  * @url = Output parsed URL
        !            16:  * return: 0 error format not find tech:// and return URL like path; 
        !            17:                -1 error:: can`t read; >0 ok, up bits for known elements
        !            18: */
        !            19: int ioURLGet(const char *csURL, struct tagIOURL *url)
        !            20: {
        !            21:        char *pos, *at, *cl, *sl;
        !            22:        int ret = 0;
        !            23: 
        !            24:        if (!url)
        !            25:                return -1;
        !            26:        else
        !            27:                memset(url, 0, sizeof(*url));
        !            28: 
        !            29:        strlcpy((char*) url->url_line, csURL, BUFSIZ);
        !            30:        // Tech
        !            31:        if (!(pos = strstr((char*) url->url_line, "://"))) {
        !            32:                url->url_path.vallen = strlen((char*) url->url_line);
        !            33:                url->url_path.value = (char*) url->url_line;
        !            34:                return ret;
        !            35:        } else {
        !            36:                url->url_tech.value = (char*) url->url_line;
        !            37:                url->url_tech.vallen = pos - (char*) url->url_line;
        !            38:                if (url->url_tech.vallen)
        !            39:                        ret |= 1;
        !            40: 
        !            41:                *pos = 0;
        !            42:                pos += 3;
        !            43:        }
        !            44: 
        !            45:        // User
        !            46:        if ((at = strchr(pos, '@'))) {
        !            47:                *at++ = 0;
        !            48:                // Pass
        !            49:                if ((cl = strchr(pos, ':'))) {
        !            50:                        *cl++ = 0;
        !            51: 
        !            52:                        url->url_pass.value = cl;
        !            53:                        url->url_pass.vallen = at - cl - 1;
        !            54:                        if (url->url_pass.vallen)
        !            55:                                ret |= 4;
        !            56:                } else
        !            57:                        cl = at;
        !            58: 
        !            59:                url->url_user.value = pos;
        !            60:                url->url_user.vallen = cl - pos - 1;
        !            61:                if (url->url_user.vallen)
        !            62:                        ret |= 2;
        !            63: 
        !            64:                pos = at;
        !            65:        }
        !            66: 
        !            67:        // Host
        !            68:        if ((sl = strchr(pos, '/')))
        !            69:                *sl++ = 0;
        !            70:        else
        !            71:                sl = pos + strlen(pos) + 1;
        !            72:        // Port
        !            73:        if ((cl = strchr(pos, ':'))) {
        !            74:                *cl++ = 0;
        !            75: 
        !            76:                url->url_port.value = cl;
        !            77:                url->url_port.vallen = sl - cl - 1;
        !            78:                if (url->url_port.vallen)
        !            79:                        ret |= 16;
        !            80:        } else
        !            81:                cl = sl;
        !            82: 
        !            83:        url->url_host.value = pos;
        !            84:        url->url_host.vallen = cl - pos - 1;
        !            85:        if (url->url_host.vallen)
        !            86:                ret |= 8;
        !            87: 
        !            88:        pos = sl;
        !            89: 
        !            90:        // Args
        !            91:        if ((at = strchr(pos, '?'))) {
        !            92:                *at++ = 0;
        !            93: 
        !            94:                url->url_args.value = at;
        !            95:                url->url_args.vallen = strlen(at);
        !            96:                if (url->url_args.vallen)
        !            97:                        ret |= 64;
        !            98:        } else
        !            99:                at = pos + strlen(pos) + 1;
        !           100: 
        !           101:        // Path
        !           102:        url->url_path.value = pos;
        !           103:        url->url_path.vallen = at - pos - 1;
        !           104:        if (url->url_path.vallen)
        !           105:                ret |= 32;
        !           106: 
        !           107:        pos = at + strlen(at);
        !           108: 
        !           109:        // Reserved
        !           110:        url->url_reserved = pos;
        !           111:        if (*pos)
        !           112:                ret |= 128;
        !           113: 
        !           114:        return ret;
        !           115: }
        !           116: 
        !           117: /*
        !           118:  * io_MakeArray() Parse and make array of arguments values
        !           119:  * @psArgs = Input arguments line
        !           120:  * @csDelim = Delimiter(s) for separate
        !           121:  * @args = Output array of arguments ... (must be free() after procced function!)
        !           122:  * @nargs = Requested count of arguments
        !           123:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
        !           124: */
        !           125: inline int io_MakeArray(char * __restrict psArgs, const char *csDelim, char *** __restrict args, int nargs)
        !           126: {
        !           127:        char **app;
        !           128:        register int i;
        !           129: 
        !           130:        if (!psArgs || !csDelim || !args || !nargs)
        !           131:                return -1;
        !           132:        if (!(*args = malloc(sizeof(char*) * nargs))) {
        !           133:                LOGERR;
        !           134:                return -1;
        !           135:        } else
        !           136:                memset(*args, 0, sizeof(char*) * nargs);
        !           137: 
        !           138:        for (i = 0, app = *args; app < *args + nargs && (*app = strsep(&psArgs, csDelim)); 
        !           139:                                **app ? i++ : i, **app ? app++ : app);
        !           140:        return i;
        !           141: }
        !           142: /*
        !           143:  * io_SizeArray() Parse and calculate size of array
        !           144:  * @csArgs = Input arguments line
        !           145:  * @csDelim = Delimiter(s) for separate
        !           146:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of items
        !           147: */
        !           148: inline int io_SizeArray(const char *csArgs, const char *csDelim)
        !           149: {
        !           150:        register int res;
        !           151:        char *pos;
        !           152: 
        !           153:        if (!csArgs || !csDelim)
        !           154:                return -1;
        !           155: 
        !           156:        for (res = 1, pos = (char*) csArgs; (pos = strpbrk(pos, csDelim)); res++, pos++);
        !           157:        return res;
        !           158: }
        !           159: /*
        !           160:  * io_MakeAV() Parse and make attribute/value pair
        !           161:  * @csArgs = Input argument line
        !           162:  * @csDelim = Delimiter for separate
        !           163:  * @psAttr = Output Attribute
        !           164:  * @attrLen = Size of attribute array
        !           165:  * @psValue = Output Value, if ==NULL this element not present value or not wanted for return
        !           166:  * @valLen = Size of value array
        !           167:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
        !           168: */
        !           169: inline int io_MakeAV(const char * __restrict csArgs, const char *csDelim, 
        !           170:                char * __restrict psAttr, int attrLen, char * __restrict psValue, int valLen)
        !           171: {
        !           172:        register int ret = 0;
        !           173:        char *pos, *psBuf;
        !           174: 
        !           175:        if (!csArgs || !csDelim || !psAttr || !attrLen)
        !           176:                return -1;
        !           177:        if (psValue && !valLen)
        !           178:                return -1;
        !           179:        else
        !           180:                memset(psValue, 0, valLen);
        !           181:        psBuf = strdup(csArgs);
        !           182:        if (!psBuf) {
        !           183:                LOGERR;
        !           184:                return -1;
        !           185:        }
        !           186: 
        !           187:        pos = strpbrk(psBuf, csDelim);
        !           188:        if (pos)
        !           189:                *pos++ = 0;
        !           190:        ret++;
        !           191:        strlcpy(psAttr, psBuf, attrLen);
        !           192: 
        !           193:        if (pos && *pos) {
        !           194:                ret++;
        !           195:                if (psValue)
        !           196:                        strlcpy(psValue, pos, valLen);
        !           197:        }
        !           198: 
        !           199:        free(psBuf);
        !           200:        return ret;
        !           201: }
        !           202: 
        !           203: /*
        !           204:  * io_Path2File() Parse and make path/filename pair
        !           205:  * @csArgs = Input argument line
        !           206:  * @psPath = Output Path, if ==NULL path not returned
        !           207:  * @pathLen = Size of path array
        !           208:  * @psFile = Output File
        !           209:  * @fileLen = Size of file array
        !           210:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
        !           211: */
        !           212: inline int io_Path2File(const char * __restrict csArgs, char * __restrict psPath, int pathLen, 
        !           213:                char * __restrict psFile, int fileLen)
        !           214: {
        !           215:        char *pos, *psBuf;
        !           216: 
        !           217:        if (!csArgs || !psFile || !fileLen)
        !           218:                return -1;
        !           219:        if (psPath && !pathLen)
        !           220:                return -1;
        !           221:        else
        !           222:                memset(psPath, 0, pathLen);
        !           223:        psBuf = strdup(csArgs);
        !           224:        if (!psBuf) {
        !           225:                LOGERR;
        !           226:                return -1;
        !           227:        }
        !           228: 
        !           229:        pos = strrchr(psBuf, '/');
        !           230:        if (!pos) {
        !           231:                strlcpy(psFile, psBuf, fileLen);
        !           232: 
        !           233:                free(psBuf);
        !           234:                return 1;
        !           235:        } else
        !           236:                *pos++ = 0;
        !           237: 
        !           238:        strlcpy(psFile, pos, fileLen);
        !           239:        if (psPath)
        !           240:                strlcpy(psPath, psBuf, pathLen);
        !           241: 
        !           242:        free(psBuf);
        !           243:        return 2;
        !           244: }
        !           245: 
        !           246: /*
        !           247:  * ioURLGetValue() Get value from parsed URL
        !           248:  * @url = Input parsed URL
        !           249:  * @csAttr = Attribute for search
        !           250:  * @psValue = Return value of attribute, if ==NULL only check for existence of attribute
        !           251:  * @valLen = Size of psValue array
        !           252:  * return: 0 error attribute not find; -1 error:: can`t read; >0 ok, find at position
        !           253: */
        !           254: int ioURLGetValue(struct tagIOURL *url, const char *csAttr, char * __restrict psValue, int valLen)
        !           255: {
        !           256:        register int i, ret = 0;
        !           257:        char szBuf[BUFSIZ], **items, szElem[2][BUFSIZ];
        !           258:        int len;
        !           259: 
        !           260:        if (!url || !csAttr)
        !           261:                return -1;
        !           262: 
        !           263:        strlcpy(szBuf, url->url_args.value, BUFSIZ);
        !           264:        if (io_MakeArray(szBuf, "&", &items, (len = io_SizeArray(szBuf, "&"))) < 1)
        !           265:                return ret;
        !           266: 
        !           267:        for (i = 0; i < len && items[i]; i++) {
        !           268:                if (io_MakeAV(items[i], "=", szElem[0], BUFSIZ, szElem[1], BUFSIZ) < 1)
        !           269:                        continue;
        !           270: 
        !           271:                if (!strcmp(szElem[0], csAttr)) {
        !           272:                        ret = i + 1;
        !           273:                        if (psValue && valLen)
        !           274:                                strlcpy(psValue, szElem[1], valLen);
        !           275:                        break;
        !           276:                }
        !           277:        }
        !           278: 
        !           279:        free(items);
        !           280:        return ret;
        !           281: }
        !           282: 
        !           283: /*
        !           284:  * ioURLGetFile() Get file from parsed URL
        !           285:  * @url = Input parsed URL
        !           286:  * @psValue = Return filename, if not specified file in url path, replace with /
        !           287:  * @valLen = Size of psValue array
        !           288:  * return: -1 error:: can`t read; 0 ok
        !           289: */
        !           290: int ioURLGetFile(struct tagIOURL *url, char * __restrict psValue, int valLen)
        !           291: {
        !           292:        if (!url || !psValue || !valLen)
        !           293:                return -1;
        !           294: 
        !           295:        if (io_Path2File(url->url_path.value, NULL, 0, psValue, valLen) < 1)
        !           296:                return -1;
        !           297: 
        !           298:        // If not specified file in path, default replace to /
        !           299:        if (!*psValue)
        !           300:                strlcpy(psValue, "/", valLen);
        !           301:        return 0;
        !           302: }

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