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

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 $
1.3     ! misho       6: * $Id: url.c,v 1.2.2.1 2010/03/22 14:48:38 misho Exp $
1.2       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: }
                    116: 
                    117: /*
1.3     ! misho     118:  * io_MakeArray() Parse and make array of arguments values ... 
        !           119:  *     (input string will be modified! and output array must be free)
        !           120:  * @psArgs = Input arguments line, after execute string is modified!!!
1.2       misho     121:  * @csDelim = Delimiter(s) for separate
                    122:  * @args = Output array of arguments ... (must be free() after procced function!)
1.3     ! misho     123:  * @nargs = Maximum requested count of arguments from input string psArgs
1.2       misho     124:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
                    125: */
                    126: inline int io_MakeArray(char * __restrict psArgs, const char *csDelim, char *** __restrict args, int nargs)
                    127: {
                    128:        char **app;
                    129:        register int i;
                    130: 
                    131:        if (!psArgs || !csDelim || !args || !nargs)
                    132:                return -1;
                    133:        if (!(*args = malloc(sizeof(char*) * nargs))) {
                    134:                LOGERR;
                    135:                return -1;
                    136:        } else
                    137:                memset(*args, 0, sizeof(char*) * nargs);
                    138: 
                    139:        for (i = 0, app = *args; app < *args + nargs && (*app = strsep(&psArgs, csDelim)); 
                    140:                                **app ? i++ : i, **app ? app++ : app);
                    141:        return i;
                    142: }
                    143: /*
                    144:  * io_SizeArray() Parse and calculate size of array
                    145:  * @csArgs = Input arguments line
                    146:  * @csDelim = Delimiter(s) for separate
                    147:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of items
                    148: */
                    149: inline int io_SizeArray(const char *csArgs, const char *csDelim)
                    150: {
                    151:        register int res;
                    152:        char *pos;
                    153: 
                    154:        if (!csArgs || !csDelim)
                    155:                return -1;
                    156: 
                    157:        for (res = 1, pos = (char*) csArgs; (pos = strpbrk(pos, csDelim)); res++, pos++);
                    158:        return res;
                    159: }
                    160: /*
                    161:  * io_MakeAV() Parse and make attribute/value pair
                    162:  * @csArgs = Input argument line
                    163:  * @csDelim = Delimiter for separate
                    164:  * @psAttr = Output Attribute
                    165:  * @attrLen = Size of attribute array
                    166:  * @psValue = Output Value, if ==NULL this element not present value or not wanted for return
                    167:  * @valLen = Size of value array
                    168:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
                    169: */
                    170: inline int io_MakeAV(const char * __restrict csArgs, const char *csDelim, 
                    171:                char * __restrict psAttr, int attrLen, char * __restrict psValue, int valLen)
                    172: {
                    173:        register int ret = 0;
                    174:        char *pos, *psBuf;
                    175: 
                    176:        if (!csArgs || !csDelim || !psAttr || !attrLen)
                    177:                return -1;
                    178:        if (psValue && !valLen)
                    179:                return -1;
                    180:        else
                    181:                memset(psValue, 0, valLen);
                    182:        psBuf = strdup(csArgs);
                    183:        if (!psBuf) {
                    184:                LOGERR;
                    185:                return -1;
                    186:        }
                    187: 
                    188:        pos = strpbrk(psBuf, csDelim);
                    189:        if (pos)
                    190:                *pos++ = 0;
                    191:        ret++;
                    192:        strlcpy(psAttr, psBuf, attrLen);
                    193: 
                    194:        if (pos && *pos) {
                    195:                ret++;
                    196:                if (psValue)
                    197:                        strlcpy(psValue, pos, valLen);
                    198:        }
                    199: 
                    200:        free(psBuf);
                    201:        return ret;
                    202: }
                    203: 
                    204: /*
                    205:  * io_Path2File() Parse and make path/filename pair
                    206:  * @csArgs = Input argument line
                    207:  * @psPath = Output Path, if ==NULL path not returned
                    208:  * @pathLen = Size of path array
                    209:  * @psFile = Output File
                    210:  * @fileLen = Size of file array
                    211:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
                    212: */
                    213: inline int io_Path2File(const char * __restrict csArgs, char * __restrict psPath, int pathLen, 
                    214:                char * __restrict psFile, int fileLen)
                    215: {
                    216:        char *pos, *psBuf;
                    217: 
                    218:        if (!csArgs || !psFile || !fileLen)
                    219:                return -1;
                    220:        if (psPath && !pathLen)
                    221:                return -1;
                    222:        else
                    223:                memset(psPath, 0, pathLen);
                    224:        psBuf = strdup(csArgs);
                    225:        if (!psBuf) {
                    226:                LOGERR;
                    227:                return -1;
                    228:        }
                    229: 
                    230:        pos = strrchr(psBuf, '/');
                    231:        if (!pos) {
                    232:                strlcpy(psFile, psBuf, fileLen);
                    233: 
                    234:                free(psBuf);
                    235:                return 1;
                    236:        } else
                    237:                *pos++ = 0;
                    238: 
                    239:        strlcpy(psFile, pos, fileLen);
                    240:        if (psPath)
                    241:                strlcpy(psPath, psBuf, pathLen);
                    242: 
                    243:        free(psBuf);
                    244:        return 2;
                    245: }
                    246: 
                    247: /*
                    248:  * ioURLGetValue() Get value from parsed URL
                    249:  * @url = Input parsed URL
                    250:  * @csAttr = Attribute for search
                    251:  * @psValue = Return value of attribute, if ==NULL only check for existence of attribute
                    252:  * @valLen = Size of psValue array
                    253:  * return: 0 error attribute not find; -1 error:: can`t read; >0 ok, find at position
                    254: */
                    255: int ioURLGetValue(struct tagIOURL *url, const char *csAttr, char * __restrict psValue, int valLen)
                    256: {
                    257:        register int i, ret = 0;
                    258:        char szBuf[BUFSIZ], **items, szElem[2][BUFSIZ];
                    259:        int len;
                    260: 
                    261:        if (!url || !csAttr)
                    262:                return -1;
                    263: 
                    264:        strlcpy(szBuf, url->url_args.value, BUFSIZ);
                    265:        if (io_MakeArray(szBuf, "&", &items, (len = io_SizeArray(szBuf, "&"))) < 1)
                    266:                return ret;
                    267: 
                    268:        for (i = 0; i < len && items[i]; i++) {
                    269:                if (io_MakeAV(items[i], "=", szElem[0], BUFSIZ, szElem[1], BUFSIZ) < 1)
                    270:                        continue;
                    271: 
                    272:                if (!strcmp(szElem[0], csAttr)) {
                    273:                        ret = i + 1;
                    274:                        if (psValue && valLen)
                    275:                                strlcpy(psValue, szElem[1], valLen);
                    276:                        break;
                    277:                }
                    278:        }
                    279: 
                    280:        free(items);
                    281:        return ret;
                    282: }
                    283: 
                    284: /*
                    285:  * ioURLGetFile() Get file from parsed URL
                    286:  * @url = Input parsed URL
                    287:  * @psValue = Return filename, if not specified file in url path, replace with /
                    288:  * @valLen = Size of psValue array
                    289:  * return: -1 error:: can`t read; 0 ok
                    290: */
                    291: int ioURLGetFile(struct tagIOURL *url, char * __restrict psValue, int valLen)
                    292: {
                    293:        if (!url || !psValue || !valLen)
                    294:                return -1;
                    295: 
                    296:        if (io_Path2File(url->url_path.value, NULL, 0, psValue, valLen) < 1)
                    297:                return -1;
                    298: 
                    299:        // If not specified file in path, default replace to /
                    300:        if (!*psValue)
                    301:                strlcpy(psValue, "/", valLen);
                    302:        return 0;
                    303: }

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