/* Parse string up to a delimiter. * * Input: * cDelim - the delimiter * The following two are for whitespace stripping, * 0 means "no", 1 "yes" * - bTrimLeading * - bTrimTrailing * * Output: * ppCStr Pointer to the parsed string - must be freed by caller! */ rsRetVal parsDelimCStr(rsParsObj *pThis, cstr_t **ppCStr, char cDelim, int bTrimLeading, int bTrimTrailing) { DEFiRet; register unsigned char *pC; cstr_t *pCStr; rsCHECKVALIDOBJECT(pThis, OIDrsPars); CHKiRet(rsCStrConstruct(&pCStr)); if(bTrimLeading) parsSkipWhitespace(pThis); pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos; while(pThis->iCurrPos < rsCStrLen(pThis->pCStr) && *pC != cDelim) { if((iRet = rsCStrAppendChar(pCStr, *pC)) != RS_RET_OK) { rsCStrDestruct(&pCStr); FINALIZE; } ++pThis->iCurrPos; ++pC; } if(*pC == cDelim) { ++pThis->iCurrPos; /* eat delimiter */ } /* We got the string, now take it and see if we need to * remove anything at its end. */ if((iRet = rsCStrFinish(pCStr)) != RS_RET_OK) { rsCStrDestruct (&pCStr); FINALIZE; } if(bTrimTrailing) { if((iRet = rsCStrTrimTrailingWhiteSpace(pCStr)) != RS_RET_OK) { rsCStrDestruct (&pCStr); FINALIZE; } } /* done! */ *ppCStr = pCStr; finalize_it: RETiRet; }
/* Parse string up to a delimiter. * * Input: * cDelim - the delimiter. Note that SP within a value always is a delimiter, * so cDelim is actually an *additional* delimiter. * The following two are for whitespace stripping, * 0 means "no", 1 "yes" * - bTrimLeading * - bTrimTrailing * - bConvLower - convert string to lower case? * * Output: * ppCStr Pointer to the parsed string - must be freed by caller! */ rsRetVal parsDelimCStr(rsParsObj *pThis, cstr_t **ppCStr, char cDelim, int bTrimLeading, int bTrimTrailing, int bConvLower) { DEFiRet; register unsigned char *pC; cstr_t *pCStr = NULL; rsCHECKVALIDOBJECT(pThis, OIDrsPars); CHKiRet(rsCStrConstruct(&pCStr)); if(bTrimLeading) parsSkipWhitespace(pThis); pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos; while(pThis->iCurrPos < rsCStrLen(pThis->pCStr) && *pC != cDelim) { CHKiRet(cstrAppendChar(pCStr, bConvLower ? tolower(*pC) : *pC)); ++pThis->iCurrPos; ++pC; } if(pThis->iCurrPos < cstrLen(pThis->pCStr)) { //BUGFIX!! ++pThis->iCurrPos; /* eat delimiter */ } /* We got the string, now take it and see if we need to * remove anything at its end. */ CHKiRet(cstrFinalize(pCStr)); if(bTrimTrailing) { CHKiRet(cstrTrimTrailingWhiteSpace(pCStr)); } /* done! */ *ppCStr = pCStr; finalize_it: if(iRet != RS_RET_OK) { if(pCStr != NULL) rsCStrDestruct(&pCStr); } RETiRet; }
rsRetVal parsAddrWithBits(rsParsObj *pThis, struct NetAddr **pIP, int *pBits) { register uchar *pC; uchar *pszIP; uchar *pszTmp; struct addrinfo hints, *res = NULL; cstr_t *pCStr; DEFiRet; rsCHECKVALIDOBJECT(pThis, OIDrsPars); assert(pIP != NULL); assert(pBits != NULL); CHKiRet(cstrConstruct(&pCStr)); parsSkipWhitespace(pThis); pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos; /* we parse everything until either '/', ',' or * whitespace. Validity will be checked down below. */ while(pThis->iCurrPos < rsCStrLen(pThis->pCStr) && *pC != '/' && *pC != ',' && !isspace((int)*pC)) { if((iRet = cstrAppendChar(pCStr, *pC)) != RS_RET_OK) { cstrDestruct (&pCStr); FINALIZE; } ++pThis->iCurrPos; ++pC; } /* We got the string, let's finish it... */ if((iRet = cstrFinalize(pCStr)) != RS_RET_OK) { cstrDestruct(&pCStr); FINALIZE; } /* now we have the string and must check/convert it to * an NetAddr structure. */ CHKiRet(cstrConvSzStrAndDestruct(pCStr, &pszIP, 0)); *pIP = calloc(1, sizeof(struct NetAddr)); if (*((char*)pszIP) == '[') { pszTmp = (uchar*)strchr ((char*)pszIP, ']'); if (pszTmp == NULL) { free (pszIP); ABORT_FINALIZE(RS_RET_INVALID_IP); } *pszTmp = '\0'; memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_INET6; # ifdef AI_ADDRCONFIG hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST; # else hints.ai_flags = AI_NUMERICHOST; # endif switch(getaddrinfo ((char*)pszIP+1, NULL, &hints, &res)) { case 0: (*pIP)->addr.NetAddr = MALLOC (res->ai_addrlen); memcpy ((*pIP)->addr.NetAddr, res->ai_addr, res->ai_addrlen); freeaddrinfo (res); break; case EAI_NONAME: F_SET((*pIP)->flags, ADDR_NAME|ADDR_PRI6); (*pIP)->addr.HostWildcard = strdup ((const char*)pszIP+1); break; default: free (pszIP); free (*pIP); ABORT_FINALIZE(RS_RET_ERR); } if(*pC == '/') { /* mask bits follow, let's parse them! */ ++pThis->iCurrPos; /* eat slash */ if((iRet = parsInt(pThis, pBits)) != RS_RET_OK) { free (pszIP); free (*pIP); FINALIZE; } /* we need to refresh pointer (changed by parsInt()) */ pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos; } else { /* no slash, so we assume a single host (/128) */ *pBits = 128; } } else { /* now parse IPv4 */ memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_INET; # ifdef AI_ADDRCONFIG hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST; # else hints.ai_flags = AI_NUMERICHOST; # endif switch(getaddrinfo ((char*)pszIP, NULL, &hints, &res)) { case 0: (*pIP)->addr.NetAddr = MALLOC (res->ai_addrlen); memcpy ((*pIP)->addr.NetAddr, res->ai_addr, res->ai_addrlen); freeaddrinfo (res); break; case EAI_NONAME: F_SET((*pIP)->flags, ADDR_NAME); (*pIP)->addr.HostWildcard = strdup ((const char*)pszIP); break; default: free (pszIP); free (*pIP); ABORT_FINALIZE(RS_RET_ERR); } if(*pC == '/') { /* mask bits follow, let's parse them! */ ++pThis->iCurrPos; /* eat slash */ if((iRet = parsInt(pThis, pBits)) != RS_RET_OK) { free (pszIP); free (*pIP); FINALIZE; } /* we need to refresh pointer (changed by parsInt()) */ pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos; } else { /* no slash, so we assume a single host (/32) */ *pBits = 32; } } free(pszIP); /* no longer needed */ /* skip to next processable character */ while(pThis->iCurrPos < rsCStrLen(pThis->pCStr) && (*pC == ',' || isspace((int)*pC))) { ++pThis->iCurrPos; ++pC; } iRet = RS_RET_OK; finalize_it: RETiRet; }