예제 #1
0
/**
 * Converts an stringified IPv4 address into the RTNETADDRIPV4 representation.
 *
 * @todo This should be move to some generic part of the runtime.
 *
 * @returns VINF_SUCCESS on success, VERR_GETOPT_INVALID_ARGUMENT_FORMAT on
 *          failure.
 *
 * @param   pszValue        The value to convert.
 * @param   pAddr           Where to store the result.
 */
static int rtgetoptConvertIPv4Addr(const char *pszValue, PRTNETADDRIPV4 pAddr)
{
    char *pszNext;
    int rc = RTStrToUInt8Ex(RTStrStripL(pszValue), &pszNext, 10, &pAddr->au8[0]);
    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS)
        return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
    if (*pszNext++ != '.')
        return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;

    rc = RTStrToUInt8Ex(pszNext, &pszNext, 10, &pAddr->au8[1]);
    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS)
        return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
    if (*pszNext++ != '.')
        return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;

    rc = RTStrToUInt8Ex(pszNext, &pszNext, 10, &pAddr->au8[2]);
    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS)
        return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
    if (*pszNext++ != '.')
        return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;

    rc = RTStrToUInt8Ex(pszNext, &pszNext, 10, &pAddr->au8[3]);
    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_SPACES)
        return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
    pszNext = RTStrStripL(pszNext);
    if (*pszNext)
        return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;

    return VINF_SUCCESS;
}
DECLHIDDEN(int) rtNetStrToIPv4AddrEx(const char *pcszAddr, PRTNETADDRIPV4 pAddr,
                                     char **ppszNext)
{
    char *pszNext;
    int rc;

    AssertPtrReturn(pcszAddr, VERR_INVALID_PARAMETER);
    AssertPtrReturn(pAddr, VERR_INVALID_PARAMETER);

    rc = RTStrToUInt8Ex(pcszAddr, &pszNext, 10, &pAddr->au8[0]);
    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS)
        return VERR_INVALID_PARAMETER;
    if (*pszNext++ != '.')
        return VERR_INVALID_PARAMETER;

    rc = RTStrToUInt8Ex(pszNext, &pszNext, 10, &pAddr->au8[1]);
    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS)
        return VERR_INVALID_PARAMETER;
    if (*pszNext++ != '.')
        return VERR_INVALID_PARAMETER;

    rc = RTStrToUInt8Ex(pszNext, &pszNext, 10, &pAddr->au8[2]);
    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS)
        return VERR_INVALID_PARAMETER;
    if (*pszNext++ != '.')
        return VERR_INVALID_PARAMETER;

    rc = RTStrToUInt8Ex(pszNext, &pszNext, 10, &pAddr->au8[3]);
    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_SPACES && rc != VWRN_TRAILING_CHARS)
        return VERR_INVALID_PARAMETER;

    if (ppszNext != NULL)
        *ppszNext = pszNext;
    return VINF_SUCCESS;
}
예제 #3
0
파일: netaddrstr.cpp 프로젝트: ryenus/vbox
RTDECL(bool) RTNetIsIPv4AddrStr(const char *pszAddress)
{
    static char const s_szIpV4Digits[] = "0123456789.";

    size_t cchAddress = strlen(pszAddress);
    if (cchAddress < 7 || cchAddress > 15)
        return false;

    const char *pStart, *pFrom, *pTo, *pNow;
    pStart = pNow = pFrom = pTo = pszAddress;

    unsigned cOctets = 0;
    while (*pNow != '\0')
    {
        const char *pChar  = (const char *)memchr(s_szIpV4Digits, *pNow, sizeof(s_szIpV4Digits) - 1);
        const char *pDigit = (const char *)memchr(s_szIpV4Digits, *pNow, sizeof(s_szIpV4Digits) - 2);
        const char *pNext  = pNow + 1;

        if (!pChar)
            return false;

        if (pDigit && *pNext != '\0')
        {
            pTo = pNow;
            pNow++;
            continue;
        }

        if (*pNow == '.' || *pNext == '\0')
        {
            if (*pNext == '\0')
                pTo = pNow;

            size_t cchSub = pTo - pFrom;
            if (cchSub > 2)
                return false;

            char szDummy[4] = { 0, 0, 0, 0 };
            memcpy(szDummy, pFrom, cchSub + 1);

            int rc = RTStrToUInt8Ex(szDummy, NULL, 10, NULL);
            if (rc != VINF_SUCCESS)
                return false;

            cOctets++;
            if (cOctets > 4)
                return false;
            pFrom = pNext;
        }
        pNow++;
    }

    if (cOctets != 4)
        return false;

    return true;
}
예제 #4
0
파일: macstr.cpp 프로젝트: mcenirm/vbox
/**
 * Converts an stringified Ethernet MAC address into the RTMAC representation.
 *
 * @returns VINF_SUCCESS on success.
 *
 * @param   pszValue        The value to convert.
 * @param   pAddr           Where to store the result.
 */
RTDECL(int) RTNetStrToMacAddr(const char *pszValue, PRTMAC pAddr)
{
    /*
     * Not quite sure if I should accept stuff like "08::27:::1" here...
     * The code is accepting "::" patterns now, except for for the first
     * and last parts.
     */

    /* first */
    char *pszNext;
    int rc = RTStrToUInt8Ex(RTStrStripL(pszValue), &pszNext, 16, &pAddr->au8[0]);
    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS)
        return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
    if (*pszNext++ != ':')
        return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;

    /* middle */
    for (unsigned i = 1; i < 5; i++)
    {
        if (*pszNext == ':')
            pAddr->au8[i] = 0;
        else
        {
            rc = RTStrToUInt8Ex(pszNext, &pszNext, 16, &pAddr->au8[i]);
            if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS)
                return rc;
            if (*pszNext != ':')
                return VERR_INVALID_PARAMETER;
        }
        pszNext++;
    }

    /* last */
    rc = RTStrToUInt8Ex(pszNext, &pszNext, 16, &pAddr->au8[5]);
    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_SPACES)
        return rc;
    pszNext = RTStrStripL(pszNext);
    if (*pszNext)
        return VERR_INVALID_PARAMETER;

    return VINF_SUCCESS;
}
예제 #5
0
static char *rtUriPercentDecodeN(const char *pszString, size_t cchMax)
{
    if (!pszString)
        return NULL;

    int rc = VINF_SUCCESS;
    size_t cbLen = RT_MIN(strlen(pszString), cchMax);
    /* The new string can only get smaller. */
    char *pszNew = (char*)RTMemAlloc(cbLen + 1);
    if (!pszNew)
        return NULL;
    char *pszRes = NULL;
    size_t iIn = 0;
    size_t iOut = 0;
    while(iIn < cbLen)
    {
        if (pszString[iIn] == '%')
        {
            /* % encoding means the percent sign and exactly 2 hexadecimal
             * digits describing the ASCII number of the character. */
            ++iIn;
            char szNum[3];
            szNum[0] = pszString[iIn++];
            szNum[1] = pszString[iIn++];
            szNum[2] = '\0';

            uint8_t u8;
            rc = RTStrToUInt8Ex(szNum, NULL, 16, &u8);
            if (RT_FAILURE(rc))
                break;
            pszNew[iOut] = u8;
        }
        else
            pszNew[iOut] = pszString[iIn++];
        ++iOut;
    }
    if (RT_SUCCESS(rc))
    {
        pszNew[iOut] = '\0';
        if (iOut != iIn)
        {
            /* If the source and target strings have different size, recreate
             * the target string with the correct size. */
            pszRes = RTStrDupN(pszNew, iOut);
            RTStrFree(pszNew);
        }
        else
            pszRes = pszNew;
    }
    else
        RTStrFree(pszNew);

    return pszRes;
}
예제 #6
0
/* static */
DECLCALLBACK(int)  Guest::i_staticEnumStatsCallback(const char *pszName, STAMTYPE enmType, void *pvSample,
                                                    STAMUNIT enmUnit, STAMVISIBILITY enmVisiblity,
                                                    const char *pszDesc, void *pvUser)
{
    AssertLogRelMsgReturn(enmType == STAMTYPE_COUNTER, ("Unexpected sample type %d ('%s')\n", enmType, pszName), VINF_SUCCESS);
    AssertLogRelMsgReturn(enmUnit == STAMUNIT_BYTES, ("Unexpected sample unit %d ('%s')\n", enmUnit, pszName), VINF_SUCCESS);

    /* Get the base name w/ slash. */
    const char *pszLastSlash = strrchr(pszName, '/');
    AssertLogRelMsgReturn(pszLastSlash, ("Unexpected sample '%s'\n", pszName), VINF_SUCCESS);

    /* Receive or transmit? */
    bool fRx;
    if (!strcmp(pszLastSlash, "/BytesReceived"))
        fRx = true;
    else if (!strcmp(pszLastSlash, "/BytesTransmitted"))
        fRx = false;
    else
        AssertLogRelMsgFailedReturn(("Unexpected sample '%s'\n", pszName), VINF_SUCCESS);

#if 0 /* not used for anything, so don't bother parsing it. */
    /* Find start of instance number. ASSUMES '/Public/Net/Name<Instance digits>/Bytes...' */
    do
        --pszLastSlash;
    while (pszLastSlash > pszName && RT_C_IS_DIGIT(*pszLastSlash));
    pszLastSlash++;

    uint8_t uInstance;
    int rc = RTStrToUInt8Ex(pszLastSlash, NULL, 10, &uInstance);
    AssertLogRelMsgReturn(RT_SUCCESS(rc) && rc != VWRN_NUMBER_TOO_BIG && rc != VWRN_NEGATIVE_UNSIGNED,
                          ("%Rrc '%s'\n", rc, pszName), VINF_SUCCESS)
#endif

    /* Add the bytes to our counters. */
    PSTAMCOUNTER pCnt   = (PSTAMCOUNTER)pvSample;
    Guest       *pGuest = (Guest *)pvUser;
    uint64_t     cb     = pCnt->c;
#if 0
    LogFlowFunc(("%s i=%u d=%s %llu bytes\n", pszName, uInstance, fRx ? "RX" : "TX", cb));
#else
    LogFlowFunc(("%s d=%s %llu bytes\n", pszName, fRx ? "RX" : "TX", cb));
#endif
    if (fRx)
        pGuest->mNetStatRx += cb;
    else
        pGuest->mNetStatTx += cb;

    return VINF_SUCCESS;
}
/*
 * XXX: TODO: Share decoding code with DHCPServer::addOption.
 */
static int parseDhcpOptionText(const char *pszText,
                               int *pOptCode, char **ppszOptText, int *pOptEncoding)
{
    uint8_t u8Code;
    uint32_t u32Enc;
    char *pszNext;
    int rc;

    rc = RTStrToUInt8Ex(pszText, &pszNext, 10, &u8Code);
    if (!RT_SUCCESS(rc))
        return VERR_PARSE_ERROR;

    switch (*pszNext)
    {
        case ':':           /* support legacy format too */
        {
            u32Enc = 0;
            break;
        }

        case '=':
        {
            u32Enc = 1;
            break;
        }

        case '@':
        {
            rc = RTStrToUInt32Ex(pszNext + 1, &pszNext, 10, &u32Enc);
            if (!RT_SUCCESS(rc))
                return VERR_PARSE_ERROR;
            if (*pszNext != '=')
                return VERR_PARSE_ERROR;
            break;
        }

        default:
            return VERR_PARSE_ERROR;
    }

    *pOptCode = u8Code;
    *ppszOptText = pszNext + 1;
    *pOptEncoding = (int)u32Enc;

    return VINF_SUCCESS;
}
예제 #8
0
/* static */
int Guest::staticEnumStatsCallback(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
                                          STAMVISIBILITY enmVisiblity, const char *pszDesc, void *pvUser)
{
    PSTAMCOUNTER pCnt = (PSTAMCOUNTER)pvSample;
    char *pszEnd = strrchr((char*)pszName, '/');
    if (pszEnd)
    {
        bool    fRx;
        uint8_t uInstance = 0;

        switch (pszEnd[1])
        {
            case 'R':
                fRx = true;
                break;
            case 'T':
                fRx = false;
                break;
            default:
                LogRel(("Failed to parse the name of network stat counter (unknown counter): %s\n", pszName));
                return VINF_SUCCESS;
        }
        do
            --pszEnd;
        while (pszEnd > pszName && RT_C_IS_DIGIT(*pszEnd));
        if (RT_SUCCESS(RTStrToUInt8Ex(pszEnd + 1, NULL, 10, &uInstance)))
        {
            Guest *pGuest = (Guest *)pvUser;
            LogFlowFunc(("%s i=%u d=%s %llu %s\n", pszName, uInstance, fRx ? "RX" : "TX",
                         pCnt->c, STAMR3GetUnit(enmUnit)));
            if (fRx)
                pGuest->mNetStatRx += pCnt->c;
            else
                pGuest->mNetStatTx += pCnt->c;
        }
        else
            LogRel(("Failed to extract the device instance from the name of network stat counter: %s\n", pszEnd));
    }
    else
        LogRel(("Failed to parse the name of network stat counter (no slash): %s\n", pszName));

    return VINF_SUCCESS;
}
static int fillDhcpOption(RawOption &opt, const std::string &OptText, int OptEncoding)
{
    int rc;
 
    if (OptEncoding == DhcpOptEncoding_Hex)
    {
        if (OptText.empty())
            return VERR_INVALID_PARAMETER;

        size_t cbRawOpt = 0;
        char *pszNext = const_cast<char *>(OptText.c_str());
        while (*pszNext != '\0')
        {
            if (cbRawOpt >= RT_ELEMENTS(opt.au8RawOpt))
                return VERR_INVALID_PARAMETER;

            uint8_t u8Byte;
            rc = RTStrToUInt8Ex(pszNext, &pszNext, 16, &u8Byte);
            if (!RT_SUCCESS(rc))
                return rc;

            if (*pszNext == ':')
                ++pszNext;
            else if (*pszNext != '\0')
                return VERR_PARSE_ERROR;

            opt.au8RawOpt[cbRawOpt] = u8Byte;
            ++cbRawOpt;
        }
        opt.cbRawOpt = (uint8_t)cbRawOpt;
    }
    else if (OptEncoding == DhcpOptEncoding_Legacy)
    {
        /*
         * XXX: TODO: encode "known" option opt.u8OptId
         */
        return VERR_INVALID_PARAMETER;
    }

    return VINF_SUCCESS;
}
예제 #10
0
파일: time.cpp 프로젝트: miguelinux/vbox
/**
 * Attempts to convert an ISO date string to a time structure.
 *
 * We're a little forgiving with zero padding, unspecified parts, and leading
 * and trailing spaces.
 *
 * @retval  pTime on success,
 * @retval  NULL on failure.
 * @param   pTime       Where to store the time on success.
 * @param   pszString   The ISO date string to convert.
 */
RTDECL(PRTTIME) RTTimeFromString(PRTTIME pTime, const char *pszString)
{
    /* Ignore leading spaces. */
    while (RT_C_IS_SPACE(*pszString))
        pszString++;

    /*
     * Init non date & time parts.
     */
    pTime->fFlags = RTTIME_FLAGS_TYPE_LOCAL;
    pTime->offUTC = 0;

    /*
     * The day part.
     */

    /* Year */
    int rc = RTStrToInt32Ex(pszString, (char **)&pszString, 10, &pTime->i32Year);
    if (rc != VWRN_TRAILING_CHARS)
        return NULL;

    bool const fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
    if (fLeapYear)
        pTime->fFlags |= RTTIME_FLAGS_LEAP_YEAR;

    if (*pszString++ != '-')
        return NULL;

    /* Month of the year. */
    rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Month);
    if (rc != VWRN_TRAILING_CHARS)
        return NULL;
    if (pTime->u8Month == 0 || pTime->u8Month > 12)
        return NULL;
    if (*pszString++ != '-')
        return NULL;

    /* Day of month.*/
    rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8MonthDay);
    if (rc != VWRN_TRAILING_CHARS && rc != VINF_SUCCESS)
        return NULL;
    unsigned const cDaysInMonth = fLeapYear
                                ? g_acDaysInMonthsLeap[pTime->u8Month - 1]
                                : g_acDaysInMonths[pTime->u8Month - 1];
    if (pTime->u8MonthDay == 0 || pTime->u8MonthDay > cDaysInMonth)
        return NULL;

    /* Calculate year day. */
    pTime->u16YearDay = pTime->u8MonthDay - 1
                      + (fLeapYear
                         ? g_aiDayOfYearLeap[pTime->u8Month - 1]
                         : g_aiDayOfYear[pTime->u8Month - 1]);

    /*
     * The time part.
     */
    if (*pszString++ != 'T')
        return NULL;

    /* Hour. */
    rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Hour);
    if (rc != VWRN_TRAILING_CHARS)
        return NULL;
    if (pTime->u8Hour > 23)
        return NULL;
    if (*pszString++ != ':')
        return NULL;

    /* Minute. */
    rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Minute);
    if (rc != VWRN_TRAILING_CHARS)
        return NULL;
    if (pTime->u8Minute > 59)
        return NULL;
    if (*pszString++ != ':')
        return NULL;

    /* Second. */
    rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Minute);
    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES)
        return NULL;
    if (pTime->u8Second > 59)
        return NULL;

    /* Nanoseconds is optional and probably non-standard. */
    if (*pszString == '.')
    {
        rc = RTStrToUInt32Ex(pszString + 1, (char **)&pszString, 10, &pTime->u32Nanosecond);
        if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES)
            return NULL;
        if (pTime->u32Nanosecond >= 1000000000)
            return NULL;
    }
    else
        pTime->u32Nanosecond = 0;

    /*
     * Time zone.
     */
    if (*pszString == 'Z')
    {
        pszString++;
        pTime->fFlags &= ~RTTIME_FLAGS_TYPE_MASK;
        pTime->fFlags |= ~RTTIME_FLAGS_TYPE_UTC;
        pTime->offUTC = 0;
    }
    else if (   *pszString == '+'
             || *pszString == '-')
    {
        rc = RTStrToInt32Ex(pszString, (char **)&pszString, 10, &pTime->offUTC);
        if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES)
            return NULL;
    }
    /* else: No time zone given, local with offUTC = 0. */

    /*
     * The rest of the string should be blanks.
     */
    char ch;
    while ((ch = *pszString++) != '\0')
        if (!RT_C_IS_BLANK(ch))
            return NULL;

    return pTime;
}
예제 #11
0
RTDECL(int) RTCidrStrToIPv4(const char *pszAddress, PRTIPV4ADDR pNetwork, PRTIPV4ADDR pNetmask)
{
    uint8_t cBits;
    uint8_t addr[4];
    uint32_t u32Netmask;
    uint32_t u32Network;
    const char *psz = pszAddress;
    const char *pszNetmask;
    char *pszNext;
    int  rc = VINF_SUCCESS;
    int cDelimiter = 0;
    int cDelimiterLimit = 0;

    AssertPtrReturn(pszAddress, VERR_INVALID_PARAMETER);
    AssertPtrReturn(pNetwork, VERR_INVALID_PARAMETER);
    AssertPtrReturn(pNetmask, VERR_INVALID_PARAMETER);

    pszNetmask = RTStrStr(psz, "/");
    *(uint32_t *)addr = 0;
    if (!pszNetmask)
        cBits = 32;
    else
    {
        rc = RTStrToUInt8Ex(pszNetmask + 1, &pszNext, 10, &cBits);
        if (   RT_FAILURE(rc)
            || cBits > 32
            || rc != VINF_SUCCESS) /* No trailing symbols are acceptable after the digit */
            return VERR_INVALID_PARAMETER;
    }
    u32Netmask = ~(uint32_t)((1<< (32 - cBits)) - 1);

    if (cBits <= 8)
        cDelimiterLimit = 0;
    else if (cBits <= 16)
        cDelimiterLimit = 1;
    else if (cBits <= 24)
        cDelimiterLimit = 2;
    else if (cBits <= 32)
        cDelimiterLimit = 3;

    for (;;)
    {
        rc = RTStrToUInt8Ex(psz, &pszNext, 10, &addr[cDelimiter]);
        if (   RT_FAILURE(rc)
            || rc == VWRN_NUMBER_TOO_BIG)
            return VERR_INVALID_PARAMETER;

        if (*pszNext == '.')
            cDelimiter++;
        else if (   cDelimiter >= cDelimiterLimit
                 && (   *pszNext == '\0'
                     || *pszNext == '/'))
            break;
        else
            return VERR_INVALID_PARAMETER;

        if (cDelimiter > 3)
            /* not more than four octets */
            return VERR_INVALID_PARAMETER;

        psz = pszNext + 1;
    }
    u32Network = RT_MAKE_U32_FROM_U8(addr[3], addr[2], addr[1], addr[0]);

    /* Corner case: see RFC 790 page 2 and RFC 4632 page 6. */
    if (   addr[0] == 0
        && (   *(uint32_t *)addr != 0
            || u32Netmask == (uint32_t)~0))
        return VERR_INVALID_PARAMETER;

    if ((u32Network & ~u32Netmask) != 0)
        return VERR_INVALID_PARAMETER;

    *pNetmask = u32Netmask;
    *pNetwork = u32Network;
    return VINF_SUCCESS;
}
예제 #12
0
bool writeQuoted(enum ENMFORMAT enmFormat, const char *pcszQuoted)
{
    /* Was the last character seen a back slash? */
    bool fEscaped = false;
    /* Was the last character seen an argument separator (an unescaped space)?
     */
    bool fNextArgument = false;

    if (enmFormat == FORMAT_SHELL)
        if (!outputCharacter('\''))
            return false;
    for (; *pcszQuoted; ++pcszQuoted)
    {
        if (fEscaped)
        {
            bool fRc = true;
            const char (*pachEscapes)[2];
            fEscaped = false;
            /* One-letter escapes. */
            for (pachEscapes = aachEscapes; (*pachEscapes)[0]; ++pachEscapes)
                if (*pcszQuoted == (*pachEscapes)[0])
                {
                    if (!escapeAndOutputCharacter(enmFormat, (*pachEscapes)[1]))
                        return false;
                    break;
                }
            if ((*pachEscapes)[0])
                continue;
            /* Octal. */
            if (*pcszQuoted >= '0' && *pcszQuoted <= '7')
            {
                uint8_t cNum;
                char *pchNext;
                char achDigits[4];
                int rc;
                RTStrCopy(achDigits, sizeof(achDigits), pcszQuoted);
                rc = RTStrToUInt8Ex(achDigits, &pchNext, 8, &cNum);
                if (rc == VWRN_NUMBER_TOO_BIG)
                {
                    RTStrmPrintf(g_pStdErr, "Invalid octal sequence at \"%.16s\"\n",
                                 pcszQuoted - 1);
                    return false;
                }
                if (!escapeAndOutputCharacter(enmFormat, cNum))
                    return false;
                pcszQuoted += pchNext - achDigits - 1;
                continue;
            }
            /* Hexadecimal. */
            if (*pcszQuoted == 'x')
            {
                uint8_t cNum;
                char *pchNext;
                char achDigits[3];
                int rc;
                RTStrCopy(achDigits, sizeof(achDigits), pcszQuoted + 1);
                rc = RTStrToUInt8Ex(achDigits, &pchNext, 16, &cNum);
                if (   rc == VWRN_NUMBER_TOO_BIG
                    || rc == VWRN_NEGATIVE_UNSIGNED
                    || RT_FAILURE(rc))
                {
                    RTStrmPrintf(g_pStdErr, "Invalid hexadecimal sequence at \"%.16s\"\n",
                                 pcszQuoted - 1);
                    return false;
                }
                if (!escapeAndOutputCharacter(enmFormat, cNum))
                    return false;
                pcszQuoted += pchNext - achDigits;
                continue;
            }
            /* Output anything else non-zero as is. */
            if (*pcszQuoted)
            {
                if (!escapeAndOutputCharacter(enmFormat, *pcszQuoted))
                    return false;
                continue;
            }
            RTStrmPrintf(g_pStdErr, "Trailing back slash in argument.\n");
            return false;
        }
        /* Argument separator. */
        if (*pcszQuoted == ' ')
        {
            if (!fNextArgument && !outputArgumentSeparator(enmFormat))
                return false;
            fNextArgument = true;
            continue;
        }
        else
            fNextArgument = false;
        /* Start of escape sequence. */
        if (*pcszQuoted == '\\')
        {
            fEscaped = true;
            continue;
        }
        /* Anything else. */
        if (!outputCharacter(*pcszQuoted))
            return false;
    }
    if (enmFormat == FORMAT_SHELL)
        if (!outputCharacter('\''))
            return false;
    return true;
}
예제 #13
0
int DHCPServer::addOption(settings::DhcpOptionMap &aMap,
                          DhcpOpt_T aOption, const com::Utf8Str &aValue)
{
    settings::DhcpOptValue OptValue;

    if (aOption != 0)
    {
        OptValue = settings::DhcpOptValue(aValue, DhcpOptEncoding_Legacy);
    }
    /*
     * This is a kludge to sneak in option encoding information
     * through existing API.  We use option 0 and supply the real
     * option/value in the same format that encodeOption() above
     * produces for getter methods.
     */
    else
    {
        uint8_t u8Code;
        uint32_t u32Enc;
        char *pszNext;
        int rc;

        rc = RTStrToUInt8Ex(aValue.c_str(), &pszNext, 10, &u8Code);
        if (!RT_SUCCESS(rc))
            return VERR_PARSE_ERROR;

        switch (*pszNext)
        {
            case ':':           /* support legacy format too */
            {
                u32Enc = DhcpOptEncoding_Legacy;
                break;
            }

            case '=':
            {
                u32Enc = DhcpOptEncoding_Hex;
                break;
            }

            case '@':
            {
                rc = RTStrToUInt32Ex(pszNext + 1, &pszNext, 10, &u32Enc);
                if (!RT_SUCCESS(rc))
                    return VERR_PARSE_ERROR;
                if (*pszNext != '=')
                    return VERR_PARSE_ERROR;
                break;
            }

            default:
                return VERR_PARSE_ERROR;
        }

        aOption = (DhcpOpt_T)u8Code;
        OptValue = settings::DhcpOptValue(pszNext + 1, (DhcpOptEncoding_T)u32Enc);
    }

    aMap[aOption] = OptValue;
    return VINF_SUCCESS;
}