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

1.1.2.1   misho       1: /*************************************************************************
                      2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
                      3: *  by Michael Pounov <misho@openbsd-bg.org>
                      4: *
                      5: * $Author: misho $
1.1.2.5 ! misho       6: * $Id: url.c,v 1.1.2.4 2010/03/04 09:54:23 misho Exp $
1.1.2.1   misho       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: }
1.1.2.2   misho     116: 
                    117: /*
                    118:  * io_MakeArray() Parse and make array of arguments values
1.1.2.3   misho     119:  * @psArgs = Input arguments line
1.1.2.2   misho     120:  * @csDelim = Delimiter(s) for separate
1.1.2.3   misho     121:  * @args = Output array of arguments ... (must be free() after procced function!)
1.1.2.2   misho     122:  * @nargs = Requested count of arguments
                    123:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
                    124: */
1.1.2.4   misho     125: inline int io_MakeArray(char * __restrict psArgs, const char *csDelim, char *** __restrict args, int nargs)
1.1.2.2   misho     126: {
                    127:        char **app;
                    128:        register int i;
                    129: 
1.1.2.4   misho     130:        if (!psArgs || !csDelim || !args || !nargs)
1.1.2.2   misho     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: }
1.1.2.4   misho     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
1.1.2.5 ! misho     164:  * @attrLen = Size of attribute array
1.1.2.4   misho     165:  * @psValue = Output Value, if ==NULL this element not present value or not wanted for return
1.1.2.5 ! misho     166:  * @valLen = Size of value array
1.1.2.4   misho     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;
1.1.2.5 ! misho     173:        char *pos, *psBuf;
1.1.2.4   misho     174: 
                    175:        if (!csArgs || !csDelim || !psAttr || !attrLen)
                    176:                return -1;
                    177:        if (psValue && !valLen)
                    178:                return -1;
                    179:        else
                    180:                memset(psValue, 0, valLen);
1.1.2.5 ! misho     181:        psBuf = strdup(csArgs);
        !           182:        if (!psBuf) {
        !           183:                LOGERR;
        !           184:                return -1;
        !           185:        }
1.1.2.4   misho     186: 
1.1.2.5 ! misho     187:        pos = strpbrk(psBuf, csDelim);
1.1.2.4   misho     188:        if (pos)
                    189:                *pos++ = 0;
                    190:        ret++;
1.1.2.5 ! misho     191:        strlcpy(psAttr, psBuf, attrLen);
1.1.2.4   misho     192: 
                    193:        if (pos && *pos) {
                    194:                ret++;
                    195:                if (psValue)
                    196:                        strlcpy(psValue, pos, valLen);
                    197:        }
                    198: 
1.1.2.5 ! misho     199:        free(psBuf);
1.1.2.4   misho     200:        return ret;
                    201: }
                    202: 
                    203: /*
1.1.2.5 ! misho     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: /*
1.1.2.4   misho     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];
1.1.2.5 ! misho     258:        int len;
1.1.2.4   misho     259: 
                    260:        if (!url || !csAttr)
                    261:                return -1;
                    262: 
                    263:        strlcpy(szBuf, url->url_args.value, BUFSIZ);
1.1.2.5 ! misho     264:        if (io_MakeArray(szBuf, "&", &items, (len = io_SizeArray(szBuf, "&"))) < 1)
1.1.2.4   misho     265:                return ret;
                    266: 
1.1.2.5 ! misho     267:        for (i = 0; i < len && items[i]; i++) {
1.1.2.4   misho     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: }
1.1.2.5 ! misho     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>