Annotation of libaitio/src/tools.c, revision 1.10

1.2       misho       1: /*************************************************************************
1.4       misho       2: * (C) 2008 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
                      3: *  by Michael Pounov <misho@elwix.org>
1.2       misho       4: *
                      5: * $Author: misho $
1.10    ! misho       6: * $Id: tools.c,v 1.9.2.1 2012/03/27 21:37:56 misho Exp $
1.2       misho       7: *
1.4       misho       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.9       misho      15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
1.4       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: */
1.2       misho      46: #include "global.h"
                     47: #include "aitio.h"
                     48: 
                     49: 
                     50: /*
                     51:  * io_LTrimStr() Remove left whitespaces from text string
1.10    ! misho      52:  *
1.2       misho      53:  * @psLine = Text string
                     54:  * return: 0 nothing to do; !=0 Removed bytes
                     55: */
1.5       misho      56: inline int
                     57: io_LTrimStr(u_char * __restrict psLine)
1.2       misho      58: {
                     59:        int pos = 0;
                     60:        u_char *s;
                     61: 
                     62:        if (!psLine || !*psLine)
                     63:                return 0;
                     64: 
                     65:        for (s = psLine; isspace(*s); s++);
                     66:        pos = s - psLine;
                     67: 
                     68:        memmove(psLine, s, (strlen((char*) psLine) - pos) + 1);
                     69:        return pos;
                     70: }
                     71: 
                     72: /*
                     73:  * io_RTrimStr() Remove right whitespaces from text string
1.10    ! misho      74:  *
1.2       misho      75:  * @psLine = Text string
                     76:  * return: 0 nothing to do; !=0 Removed bytes
                     77: */
1.5       misho      78: inline int
                     79: io_RTrimStr(u_char * __restrict psLine)
1.2       misho      80: {
                     81:        u_char *t, *pos;
                     82: 
                     83:        if (!psLine || !*psLine)
                     84:                return 0;
                     85: 
                     86:        pos = psLine + strlen((char*) psLine);
                     87:        for (t = pos - 1; t > psLine && isspace(*t); t--);
                     88:        *++t = 0;
                     89: 
                     90:        return pos - t;
                     91: }
                     92: 
                     93: /*
                     94:  * io_TrimStr() Remove left and right whitespaces from text string
1.10    ! misho      95:  *
1.2       misho      96:  * @psLine = Text string
                     97:  * return: 0 nothing to do; !=0 Removed bytes
                     98: */
1.5       misho      99: inline int
                    100: io_TrimStr(u_char * __restrict psLine)
1.2       misho     101: {
                    102:        int ret = 0;
                    103: 
                    104:        ret = io_LTrimStr(psLine);
                    105:        ret += io_RTrimStr(psLine);
                    106: 
                    107:        return ret;
                    108: }
                    109: 
                    110: /*
                    111:  * io_UnquotStr() Remove quots from input text string 
1.10    ! misho     112:  *
1.2       misho     113:  * @psLine = Text string
                    114:  * return: 0 nothing to do; 1 successful unquoted string
                    115: */
1.5       misho     116: inline int
                    117: io_UnquotStr(u_char * __restrict psLine)
1.2       misho     118: {
                    119:        char *pos, *str = NULL;
                    120:        int flg;
                    121: 
                    122:        if (!psLine)
                    123:                return 0;
                    124: 
                    125:        switch (*psLine) {
                    126:                case '`':
                    127:                case '"':
                    128:                case '\'':
                    129:                        str = strdup((char*) psLine + 1);
                    130:                        for (pos = str, flg = 0; *pos; flg = ('\\' == *pos), pos++) {
                    131:                                if (!flg && *pos == *psLine) {
                    132:                                        *pos = 0;
                    133:                                        strlcpy((char*) psLine, str, strlen((char*) psLine) + 1);
                    134:                                        break;
                    135:                                }
                    136:                        }
                    137:                        free(str);
                    138:                        return 1;
                    139:        }
                    140: 
                    141:        return 0;
                    142: }
                    143: 
                    144: /*
1.3       misho     145:  * io_Ch2Hex() Convert from Char string to Hex string
1.10    ! misho     146:  *
1.2       misho     147:  * @psLine = Text string
                    148:  * @lineLen = Length of Text string
1.3       misho     149:  * return: NULL nothing to do or error; !=0 Allocated new converted data without term\0 (must be free)
1.2       misho     150: */
1.5       misho     151: inline u_char *
                    152: io_Ch2Hex(u_char *psLine, int lineLen)
1.2       misho     153: {
                    154:        register int i;
1.3       misho     155:        char szWork[3];
                    156:        u_char *str;
1.2       misho     157: 
                    158:        if (!psLine || !*psLine || !lineLen)
                    159:                return NULL;
                    160: 
1.3       misho     161:        str = malloc(lineLen / 2);
1.2       misho     162:        if (!str) {
                    163:                LOGERR;
                    164:                return NULL;
                    165:        } else
1.3       misho     166:                memset(str, 0, lineLen / 2);
1.2       misho     167: 
1.3       misho     168:        for (i = 0; i < lineLen && psLine[i * 2]; i++) {
                    169:                strlcpy(szWork, (char*) &psLine[i * 2], 3);
                    170:                str[i] = (u_char) strtol(szWork, NULL, 16);
1.2       misho     171:        }
                    172: 
                    173:        return str;
                    174: }
                    175: 
                    176: 
                    177: /*
1.3       misho     178:  * io_Hex2Ch() Convert from Hex string to Char string
1.10    ! misho     179:  *
1.2       misho     180:  * @psLine = Text string
                    181:  * @lineLen = Length of Text string
                    182:  * return: NULL nothing to do or error; !=0 Allocated new converted string(must be free)
                    183: */
1.5       misho     184: inline char *
                    185: io_Hex2Ch(u_char *psLine, int lineLen)
1.2       misho     186: {
                    187:        register int i;
                    188:        char szWork[3], *str;
                    189: 
                    190:        if (!psLine || !*psLine || !lineLen)
                    191:                return NULL;
                    192: 
1.3       misho     193:        str = malloc(lineLen * 2 + 1);
1.2       misho     194:        if (!str) {
                    195:                LOGERR;
                    196:                return NULL;
                    197:        } else
1.3       misho     198:                memset(str, 0, lineLen * 2 + 1);
1.2       misho     199: 
1.3       misho     200:        for (i = 0; i <= lineLen; i++) {
                    201:                memset(szWork, 0, 3);
                    202:                snprintf(szWork, 3, "%02X", (u_char) psLine[i]);
                    203:                strncat(str, szWork, 2);
1.2       misho     204:        }
                    205: 
                    206:        return str;
                    207: }
1.5       misho     208: 
                    209: /*
                    210:  * io_CopyEnv() Copy environment to new environment array;
1.10    ! misho     211:  *
1.5       misho     212:  * @oldenv = Environment array
                    213:  * return: NULL error; !=NULL Allocated new environment array(must be free)
                    214: */
                    215: char **
                    216: io_CopyEnv(const char **oldenv)
                    217: {
                    218:        char **newenv, **el;
                    219:        register int i, num;
                    220: 
                    221:        if (!oldenv)
                    222:                return NULL;
                    223:        else
                    224:                newenv = el = NULL;
                    225: 
                    226:        /* count items environment */
                    227:        for (i = num = 0; oldenv[i]; i++)
                    228:                if (*strchr(oldenv[i], '='))
                    229:                        num++;
                    230: 
                    231:        /* create and copy new environment */
                    232:        newenv = calloc(num + 1, sizeof(char*));
                    233:        if (!newenv) {
                    234:                LOGERR;
                    235:                return NULL;
                    236:        } else
                    237:                el = newenv;
                    238: 
                    239:        for (i = 0; oldenv[i]; i++)
                    240:                if (*strchr(oldenv[i], '=')) {
                    241:                        *el = strdup(oldenv[i]);
                    242:                        el++;
                    243:                }
                    244:        *el = NULL;
                    245: 
                    246:        return newenv;
                    247: }
                    248: 
                    249: /*
                    250:  * io_ExecArgs() Build exec arguments from other array
1.10    ! misho     251:  *
1.5       misho     252:  * @psProg = Program name for execute
                    253:  * @oldarg = Arguments array
                    254:  * return: NULL error; !=NULL Allocated execution array(must be free)
                    255: */
                    256: char **
                    257: io_ExecArgs(const char *psProg, const char **oldarg)
                    258: {
                    259:        char **newarg, **el;
                    260:        register int i, num;
                    261: 
                    262:        if (!psProg || !oldarg)
                    263:                return NULL;
                    264:        else
                    265:                newarg = el = NULL;
                    266: 
                    267:        /* count items arguments */
                    268:        for (num = 0; oldarg[num]; num++);
                    269: 
                    270:        /* create and copy new arguments */
                    271:        newarg = calloc(num + 2, sizeof(char*));
                    272:        if (!newarg) {
                    273:                LOGERR;
                    274:                return NULL;
                    275:        } else
                    276:                el = newarg;
                    277: 
                    278:        *el = strdup(psProg);
                    279:        el++;
                    280: 
                    281:        for (i = 0; oldarg[i]; i++, el++)
                    282:                *el = strdup(oldarg[i]);
                    283:        *el = NULL;
                    284: 
                    285:        return newarg;
                    286: }
                    287: 
                    288: /*
                    289:  * io_FreeNullTerm() Free dynamic allocated null terminated array with strings
1.10    ! misho     290:  *
1.5       misho     291:  * @arr = Pointer to array for free
                    292:  * return: none
                    293: */
                    294: inline void
                    295: io_FreeNullTerm(char *** __restrict arr)
                    296: {
                    297:        char **a;
                    298: 
                    299:        if (arr && *arr) {
                    300:                a = *arr;
                    301:                while (a && *a)
                    302:                        free(*a++);
                    303:                free(*arr);
                    304:                *arr = NULL;
                    305:        }
                    306: }
1.6       misho     307: 
                    308: /*
1.9       misho     309:  * io_Path2File() - Parse and make path/filename pair
                    310:  *
                    311:  * @csArgs = Input argument line
                    312:  * @psPath = Output Path, if ==NULL path not returned
                    313:  * @pathLen = Size of path array
                    314:  * @psFile = Output File
                    315:  * @fileLen = Size of file array
                    316:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
                    317:  */
                    318: inline int
                    319: io_Path2File(const char * __restrict csArgs, char * __restrict psPath, 
                    320:                int pathLen, char * __restrict psFile, int fileLen)
                    321: {
                    322:        char *pos, *psBuf;
                    323: 
                    324:        if (!csArgs || !psFile || !fileLen)
                    325:                return -1;
                    326:        if (psPath && !pathLen)
                    327:                return -1;
                    328: 
                    329:        psBuf = strdup(csArgs);
                    330:        if (!psBuf) {
                    331:                LOGERR;
                    332:                return -1;
                    333:        }
                    334: 
                    335:        pos = strrchr(psBuf, '/');
                    336:        if (!pos) {
                    337:                strlcpy(psFile, psBuf, fileLen);
                    338: 
                    339:                free(psBuf);
                    340:                return 1;
                    341:        } else
                    342:                *pos++ = 0;
                    343: 
                    344:        strlcpy(psFile, pos, fileLen);
                    345:        if (psPath)
                    346:                strlcpy(psPath, psBuf, pathLen);
                    347: 
                    348:        free(psBuf);
                    349:        return 2;
                    350: }
                    351: 
                    352: /*
1.6       misho     353:  * io_ether_ntoa() Convert ethernet address to string
1.10    ! misho     354:  *
1.6       misho     355:  * @n = ethernet address structure, like struct ether_addr
                    356:  * @a = string
                    357:  * @len = string length
                    358:  * return: NULL error or !=NULL string a
                    359:  */
                    360: inline char *
                    361: io_ether_ntoa(const struct io_ether_addr *n, char * __restrict a, int len)
                    362: {
                    363:        if (!n || !a)
                    364:                return NULL;
                    365: 
                    366:        memset(a, 0, len);
                    367:        if (snprintf(a, len, "%02x:%02x:%02x:%02x:%02x:%02x", 
                    368:                        n->ether_addr_octet[0], n->ether_addr_octet[1], 
                    369:                        n->ether_addr_octet[2], n->ether_addr_octet[3], 
                    370:                        n->ether_addr_octet[4], n->ether_addr_octet[5]) < 17)
                    371:                return NULL;
                    372: 
                    373:        return a;
                    374: }
                    375: 
                    376: /*
                    377:  * io_ether_aton() Convert string to ethernet address
1.10    ! misho     378:  *
1.6       misho     379:  * @a = string
                    380:  * @e = ethernet address structure, like struct ether_addr
                    381:  * return: NULL error or !=NULL ethernet address structure
                    382:  */
                    383: inline struct io_ether_addr *
                    384: io_ether_aton(const char *a, struct io_ether_addr *e)
                    385: {                       
                    386:        int i;
                    387:        u_int o0, o1, o2, o3, o4, o5;
                    388: 
                    389:        if (!a || !e)
                    390:                return NULL;
                    391: 
                    392:        i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5);
                    393:        if (i != 6)
                    394:                return NULL;
                    395: 
                    396:        e->ether_addr_octet[0] = o0;
                    397:        e->ether_addr_octet[1] = o1;
                    398:        e->ether_addr_octet[2] = o2;
                    399:        e->ether_addr_octet[3] = o3;
                    400:        e->ether_addr_octet[4] = o4;
                    401:        e->ether_addr_octet[5] = o5;
                    402: 
                    403:        return e;
                    404: }
1.7       misho     405: 
                    406: /*
                    407:  * io_n2port() Extract port from network structure
1.10    ! misho     408:  *
1.7       misho     409:  * @addr = Address
                    410:  * return: 0 not supported family type or port number
                    411:  */
                    412: inline u_short
                    413: io_n2port(io_sockaddr_t * __restrict addr)
                    414: {
                    415:        u_short port = 0;
                    416: 
                    417:        if (!addr)
                    418:                return port;
                    419: 
                    420:        switch (addr->sa.sa_family) {
                    421:                case AF_INET:
                    422:                        return ntohs(addr->sin.sin_port);
                    423:                case AF_INET6:
                    424:                        return ntohs(addr->sin6.sin6_port);
                    425:                default:
                    426:                        io_SetErr(ESOCKTNOSUPPORT, "Unsuported address family %d", 
                    427:                                        addr->sa.sa_family);
                    428:                        break;
                    429:        }
                    430: 
                    431:        return port;
                    432: }
                    433: 
                    434: /*
                    435:  * io_n2addr() Extract address from network structure
1.10    ! misho     436:  *
1.7       misho     437:  * @addr = Address
                    438:  * @val = Value for store string address
                    439:  * return: NULL error or !=NULL string address from val
                    440:  */
                    441: const char *
                    442: io_n2addr(io_sockaddr_t * __restrict addr, ait_val_t * __restrict val)
                    443: {
                    444:        char str[INET6_ADDRSTRLEN] = { 0 };
                    445:        const char *ret = NULL;
                    446: 
                    447:        if (!addr || !val)
                    448:                return ret;
                    449: 
                    450:        switch (addr->sa.sa_family) {
                    451:                case AF_INET:
                    452:                        if (!inet_ntop(AF_INET, &addr->sin.sin_addr, str, INET_ADDRSTRLEN)) {
                    453:                                LOGERR;
                    454:                                return ret;
                    455:                        } else
                    456:                                ret = str;
                    457:                        break;
                    458:                case AF_INET6:
                    459:                        if (!inet_ntop(AF_INET6, &addr->sin6.sin6_addr, str, INET6_ADDRSTRLEN)) {
                    460:                                LOGERR;
                    461:                                return ret;
                    462:                        } else
                    463:                                ret = str;
                    464:                        break;
                    465:                default:
                    466:                        io_SetErr(EPROTONOSUPPORT, "Unsuported address family %d", 
                    467:                                        addr->sa.sa_family);
                    468:                        return ret;
                    469:        }
                    470: 
1.8       misho     471:        if (!AIT_ISEMPTY(val))
                    472:                AIT_FREE_VAL(val);
1.7       misho     473:        AIT_SET_STR(val, ret);
1.8       misho     474:        return (const char*) AIT_GET_STR(val);
1.7       misho     475: }
                    476: 
                    477: /*
                    478:  * io_gethostbyname() Get host and port and make network structure
1.10    ! misho     479:  *
1.7       misho     480:  * @psHost = Hostname
                    481:  * @port = Port
                    482:  * @addr = Network address structure
                    483:  * return: NULL error or !=NULL network structure
                    484:  */
                    485: io_sockaddr_t *
                    486: io_gethostbyname(const char *psHost, u_short port, io_sockaddr_t * __restrict addr)
                    487: {
                    488:        struct hostent *host;
                    489: 
                    490:        if (!psHost || !addr)
                    491:                return NULL;
                    492: 
                    493:        /* resolver */
                    494:        if (!addr->sa.sa_family)
                    495:                host = gethostbyname(psHost);
                    496:        else
                    497:                host = gethostbyname2(psHost, addr->sa.sa_family);
                    498:        if (!host) {
                    499:                io_SetErr(EINVAL, "Resolver #%d - %s", h_errno, hstrerror(h_errno));
                    500:                return NULL;
                    501:        }
                    502: 
                    503:        memset(addr, 0, sizeof(io_sockaddr_t));
                    504:        switch (host->h_addrtype) {
                    505:                case AF_INET:
                    506:                        addr->sin.sin_len = sizeof(struct sockaddr_in);
                    507:                        addr->sin.sin_family = AF_INET;
                    508:                        addr->sin.sin_port = htons(port);
                    509:                        memcpy(&addr->sin.sin_addr, host->h_addr, sizeof addr->sin.sin_addr);
                    510:                        return addr;
                    511:                case AF_INET6:
                    512:                        addr->sin6.sin6_len = sizeof(struct sockaddr_in6);
                    513:                        addr->sin6.sin6_family = AF_INET6;
                    514:                        addr->sin6.sin6_port = htons(port);
                    515:                        memcpy(&addr->sin6.sin6_addr, host->h_addr, sizeof addr->sin6.sin6_addr);
                    516:                        return addr;
                    517:                default:
                    518:                        io_SetErr(EPROTONOSUPPORT, "Unsuported address family %d", 
                    519:                                        host->h_addrtype);
                    520:                        break;
                    521:        }
                    522: 
                    523:        return NULL;
                    524: }

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