示例#1
0
/**
 * @callback_method_impl{FNDBGCCMD, The '.injecterror' command.}
 */
static DECLCALLBACK(int) pdmacEpFileErrorInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR pArgs, unsigned cArgs)
{
    /*
     * Validate input.
     */
    DBGC_CMDHLP_REQ_UVM_RET(pCmdHlp, pCmd, pUVM);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 3);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, pArgs[0].enmType == DBGCVAR_TYPE_STRING);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pArgs[1].enmType == DBGCVAR_TYPE_STRING);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 2, pArgs[2].enmType == DBGCVAR_TYPE_NUMBER);

    PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile;
    pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE];

    /* Syntax is "read|write <filename> <status code>" */
    bool fWrite;
    if (!RTStrCmp(pArgs[0].u.pszString, "read"))
        fWrite = false;
    else if (!RTStrCmp(pArgs[0].u.pszString, "write"))
        fWrite = true;
    else
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "invalid transfer direction '%s'", pArgs[0].u.pszString);

    int32_t rcToInject = (int32_t)pArgs[2].u.u64Number;
    if ((uint64_t)rcToInject != pArgs[2].u.u64Number)
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "The status code '%lld' is out of range", pArgs[0].u.u64Number);

    /*
     * Search for the matching endpoint.
     */
    RTCritSectEnter(&pEpClassFile->Core.CritSect);

    PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
    while (pEpFile)
    {
        if (!RTStrCmp(pArgs[1].u.pszString, RTPathFilename(pEpFile->Core.pszUri)))
            break;
        pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext;
    }

    if (pEpFile)
    {
        /*
         * Do the job.
         */
        if (fWrite)
            ASMAtomicXchgS32(&pEpFile->rcReqWrite, rcToInject);
        else
            ASMAtomicXchgS32(&pEpFile->rcReqRead,  rcToInject);

        DBGCCmdHlpPrintf(pCmdHlp, "Injected %Rrc into '%s' for %s\n",
                         (int)rcToInject, pArgs[1].u.pszString, pArgs[0].u.pszString);
    }

    RTCritSectLeave(&pEpClassFile->Core.CritSect);

    if (!pEpFile)
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "No file with name '%s' found", pArgs[1].u.pszString);
    return VINF_SUCCESS;
}
/**
 * Delay inject callback.
 */
static DECLCALLBACK(int) pdmacEpFileDelayInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs)
{
    /*
     * Validate input.
     */
    DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 3);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, pArgs[0].enmType == DBGCVAR_TYPE_STRING);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pArgs[1].enmType == DBGCVAR_TYPE_STRING);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 2, pArgs[2].enmType == DBGCVAR_TYPE_NUMBER);

    PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile;
    pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pVM->pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE];

    /* Syntax is "read|write <filename> <status code>" */
    bool fWrite;
    if (!RTStrCmp(pArgs[0].u.pszString, "read"))
        fWrite = false;
    else if (!RTStrCmp(pArgs[0].u.pszString, "write"))
        fWrite = true;
    else
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "invalid transfer direction '%s'", pArgs[0].u.pszString);

    uint32_t msDelay = (uint32_t)pArgs[2].u.u64Number;
    if ((uint64_t)msDelay != pArgs[2].u.u64Number)
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "The delay '%lld' is out of range", pArgs[0].u.u64Number);


    /*
     * Search for the matching endpoint.
     */
    RTCritSectEnter(&pEpClassFile->Core.CritSect);

    PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
    while (pEpFile)
    {
        if (!RTStrCmp(pArgs[1].u.pszString, RTPathFilename(pEpFile->Core.pszUri)))
            break;
        pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext;
    }

    if (pEpFile)
    {
        bool fXchg = ASMAtomicCmpXchgU32(&pEpFile->msDelay, msDelay, 0);

        if (fXchg)
            DBGCCmdHlpPrintf(pCmdHlp, "Injected delay of %u ms into '%s' for %s\n",
                             msDelay, pArgs[1].u.pszString, pArgs[0].u.pszString);
        else
            DBGCCmdHlpPrintf(pCmdHlp, "Another delay for '%s' is still active, ignoring\n",
                             pArgs[1].u.pszString);
    }

    RTCritSectLeave(&pEpClassFile->Core.CritSect);

    if (!pEpFile)
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "No file with name '%s' found", pArgs[1].u.pszString);
    return VINF_SUCCESS;
}
示例#3
0
static int pdmacFileMgrTypeFromName(const char *pszVal, PPDMACEPFILEMGRTYPE penmMgrType)
{
    int rc = VINF_SUCCESS;

    if (!RTStrCmp(pszVal, "Simple"))
        *penmMgrType = PDMACEPFILEMGRTYPE_SIMPLE;
    else if (!RTStrCmp(pszVal, "Async"))
        *penmMgrType = PDMACEPFILEMGRTYPE_ASYNC;
    else
        rc = VERR_CFGM_CONFIG_UNKNOWN_VALUE;

    return rc;
}
示例#4
0
static int pdmacFileBackendTypeFromName(const char *pszVal, PPDMACFILEEPBACKEND penmBackendType)
{
    int rc = VINF_SUCCESS;

    if (!RTStrCmp(pszVal, "Buffered"))
        *penmBackendType = PDMACFILEEPBACKEND_BUFFERED;
    else if (!RTStrCmp(pszVal, "NonBuffered"))
        *penmBackendType = PDMACFILEEPBACKEND_NON_BUFFERED;
    else
        rc = VERR_CFGM_CONFIG_UNKNOWN_VALUE;

    return rc;
}
示例#5
0
void BusAssignmentManager::State::addMatchingRules(const char* pszName, PCIRulesList& aList)
{
    size_t iRuleset, iRule;
    const DeviceAssignmentRule* aArrays[2] = {aGenericRules, NULL};

    switch (mChipsetType)
    {
        case ChipsetType_PIIX3:
            aArrays[1] = aPiix3Rules;
            break;
        case ChipsetType_ICH9:
            aArrays[1] = aIch9Rules;
            break;
        default:
            Assert(false);
            break;
    }

    for (iRuleset = 0; iRuleset < RT_ELEMENTS(aArrays); iRuleset++)
    {
        if (aArrays[iRuleset] == NULL)
            continue;

        for (iRule = 0; aArrays[iRuleset][iRule].pszName != NULL; iRule++)
        {
            if (RTStrCmp(pszName, aArrays[iRuleset][iRule].pszName) == 0)
                aList.push_back(&aArrays[iRuleset][iRule]);
        }
    }
}
static void testInit(RTTEST hTest)
{
    RTTestSub(hTest, "Testing USBProxyLinuxChooseMethod");
    for (unsigned i = 0; i < RT_ELEMENTS(s_testEnvironment); ++i)
    {
        bool fUsingUsbfs = true;
        const char *pcszDevicesRoot = "";

        TestUSBSetEnv(s_testEnvironment[i].pcszEnvUsb,
                      s_testEnvironment[i].pcszEnvUsbRoot);
        TestUSBSetupInit(s_testEnvironment[i].pcszUsbfsRoot,
                         s_testEnvironment[i].fUsbfsAccessible,
                         s_testEnvironment[i].pcszDevicesRoot,
                         s_testEnvironment[i].fDevicesAccessible,
                         s_testEnvironment[i].rcMethodInit);
        int rc = USBProxyLinuxChooseMethod(&fUsingUsbfs, &pcszDevicesRoot);
        RTTESTI_CHECK_MSG(rc == s_testEnvironment[i].rcExpected,
                          ("rc=%Rrc (test index %i) instead of %Rrc!\n",
                           rc, i, s_testEnvironment[i].rcExpected));
        RTTESTI_CHECK_MSG(!RTStrCmp(pcszDevicesRoot,
                               s_testEnvironment[i].pcszDevicesRootExpected),
                          ("testGetDevicesRoot() returned %s (test index %i) instead of %s!\n",
                           pcszDevicesRoot, i,
                           s_testEnvironment[i].pcszDevicesRootExpected));
        RTTESTI_CHECK_MSG(   fUsingUsbfs
                          == s_testEnvironment[i].fUsingUsbfsExpected,
                          ("testGetUsingUsbfs() returned %RTbool (test index %i) instead of %RTbool!\n",
                           fUsingUsbfs, i,
                           s_testEnvironment[i].fUsingUsbfsExpected));
    }
}
示例#7
0
static int testSessionDataReadTestMsg(RTTEST hTest, RTLOCALIPCSESSION hSession,
                                      void *pvBuffer, size_t cbBuffer, const char *pszMsg)
{
    AssertPtrReturn(pvBuffer, VERR_INVALID_POINTER);
    AssertPtrReturn(pszMsg, VERR_INVALID_POINTER);

    void *pvBufCur = pvBuffer;
    size_t cbReadTotal = 0;
    for (;;)
    {
        size_t cbRead = RTRandU32Ex(1, sizeof(LOCALIPCTESTMSG) - cbReadTotal); /* Force a bit of fragmentation. */
        RTTEST_CHECK_BREAK(hTest, cbRead);
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionRead(hSession, pvBufCur,
                              cbBuffer,
                              &cbRead), VINF_SUCCESS);
        RTTEST_CHECK_BREAK(hTest, cbRead);
        pvBufCur     = (uint8_t *)pvBufCur + cbRead; /* Advance. */
        cbReadTotal += cbRead;
        RTTEST_CHECK_BREAK(hTest, cbReadTotal <= cbBuffer);
        if (cbReadTotal >= sizeof(LOCALIPCTESTMSG)) /* Got a complete test message? */
        {
            RTTEST_CHECK_BREAK(hTest, cbReadTotal == sizeof(LOCALIPCTESTMSG));
            PLOCALIPCTESTMSG pMsg = (PLOCALIPCTESTMSG)pvBuffer;
            RTTEST_CHECK_BREAK(hTest, pMsg != NULL);
            RTTEST_CHECK_BREAK(hTest, !RTStrCmp(pMsg->szOp, pszMsg));
            break;
        }
        /* Try receiving next part of the message in another round. */
    }

    return !RTTestErrorCount(hTest) ? VINF_SUCCESS : VERR_GENERAL_FAILURE /* Doesn't matter */;
}
static int tstRTCreateProcEx5Child(int argc, char **argv)
{
    int rc = RTR3InitExe(argc, &argv, 0);
    if (RT_FAILURE(rc))
        return RTMsgInitFailure(rc);

    uint32_t cErrors = 0;

    /* Check that the OS thinks we're running as the user we're supposed to. */
    char *pszUser;
    rc = RTProcQueryUsernameA(NIL_RTPROCESS, &pszUser);
    if (RT_SUCCESS(rc))
    {
#ifdef RT_OS_WINDOWS
        if (RTStrICmp(pszUser, argv[2]) != 0)
#else
        if (RTStrCmp(pszUser, argv[2]) != 0)
#endif
        {
            RTStrmPrintf(g_pStdErr, "child4: user name is '%s', expected '%s'\n", pszUser, argv[2]);
            cErrors++;
        }
        RTStrFree(pszUser);
    }
    else
    {
        RTStrmPrintf(g_pStdErr, "child4: RTProcQueryUsernameA failed: %Rrc\n", rc);
        cErrors++;
    }

    return cErrors == 0 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}
示例#9
0
 /** Check whether the sysfs block entry is valid for a floppy device and
  * initialise the string data members for the object.  Since we only
  * support floppies using the basic "floppy" driver, we check the driver
  * using the entry name and a driver-specific ioctl. */
 void validateAndInitForFloppy()
 {
     bool haveName = false;
     floppy_drive_name szName;
     char szDriver[8];
     if (   mpcszName[0] != 'f'
         || mpcszName[1] != 'd'
         || mpcszName[2] < '0'
         || mpcszName[2] > '7'
         || mpcszName[3] != '\0')
         return;
     if (!noProbe())
         haveName = floppyGetName(mszNode, mpcszName[2] - '0', szName);
     if (RTLinuxSysFsGetLinkDest(szDriver, sizeof(szDriver), "block/%s/%s",
                                 mpcszName, "device/driver") >= 0)
     {
         if (RTStrCmp(szDriver, "floppy"))
             return;
     }
     else if (!haveName)
         return;
     floppyCreateDeviceStrings(haveName ? szName : NULL,
                               mpcszName[2] - '0', mszDesc,
                               sizeof(mszDesc), mszUdi, sizeof(mszUdi));
     misValid = true;
 }
示例#10
0
/**
 * Performs a case insensitive string compare between two UTF-8 strings.
 *
 * This is a simplified compare, as only the simplified lower/upper case folding
 * specified by the unicode specs are used. It does not consider character pairs
 * as they are used in some languages, just simple upper & lower case compares.
 *
 * The result is the difference between the mismatching codepoints after they
 * both have been lower cased.
 *
 * If the string encoding is invalid the function will assert (strict builds)
 * and use RTStrCmp for the remainder of the string.
 *
 * @returns < 0 if the first string less than the second string.
 * @returns 0 if the first string identical to the second string.
 * @returns > 0 if the first string greater than the second string.
 * @param   psz1        First UTF-8 string. Null is allowed.
 * @param   psz2        Second UTF-8 string. Null is allowed.
 */
RTDECL(int) RTStrICmp(const char *psz1, const char *psz2)
{
    if (psz1 == psz2)
        return 0;
    if (!psz1)
        return -1;
    if (!psz2)
        return 1;

    const char *pszStart1 = psz1;
    for (;;)
    {
        /* Get the codepoints */
        RTUNICP uc1;
        int rc = RTStrGetCpEx(&psz1, &uc1);
        if (RT_FAILURE(rc))
        {
            AssertRC(rc);
            psz1--;
            break;
        }

        RTUNICP uc2;
        rc = RTStrGetCpEx(&psz2, &uc2);
        if (RT_FAILURE(rc))
        {
            AssertRC(rc);
            psz2--;
            psz1 = RTStrPrevCp(pszStart1, psz1);
            break;
        }

        /* compare */
        int iDiff = uc1 - uc2;
        if (iDiff)
        {
            iDiff = RTUniCpToUpper(uc1) != RTUniCpToUpper(uc2);
            if (iDiff)
            {
                iDiff = RTUniCpToLower(uc1) - RTUniCpToLower(uc2); /* lower case diff last! */
                if (iDiff)
                    return iDiff;
            }
        }

        /* hit the terminator? */
        if (!uc1)
            return 0;
    }

    /* Hit some bad encoding, continue in case sensitive mode. */
    return RTStrCmp(psz1, psz2);
}
DECLHIDDEN(PCFGAST) autostartConfigAstGetByName(PCFGAST pCfgAst, const char *pszName)
{
    if (!pCfgAst)
        return NULL;

    AssertReturn(pCfgAst->enmType == CFGASTNODETYPE_COMPOUND, NULL);

    for (unsigned i = 0; i < pCfgAst->u.Compound.cAstNodes; i++)
    {
        PCFGAST pNode = pCfgAst->u.Compound.apAstNodes[i];

        if (!RTStrCmp(pNode->pszKey, pszName))
            return pNode;
    }

    return NULL;
}
static PPDMNSBWGROUP pdmNsBwGroupFindById(PPDMNETSHAPER pShaper, const char *pszId)
{
    PPDMNSBWGROUP pBwGroup = NULL;

    if (RT_VALID_PTR(pszId))
    {
        LOCK_NETSHAPER(pShaper);

        pBwGroup = pShaper->pBwGroupsHead;
        while (   pBwGroup
               && RTStrCmp(pBwGroup->pszNameR3, pszId))
            pBwGroup = pBwGroup->pNextR3;

        UNLOCK_NETSHAPER(pShaper);
    }

    return pBwGroup;
}
示例#13
0
static PPDMNSBWGROUP pdmNsBwGroupFindById(PPDMNETSHAPER pShaper, const char *pcszId)
{
    PPDMNSBWGROUP pBwGroup = NULL;

    if (RT_VALID_PTR(pcszId))
    {
        int rc = RTCritSectEnter(&pShaper->cs); AssertRC(rc);

        pBwGroup = pShaper->pBwGroupsHead;
        while (   pBwGroup
               && RTStrCmp(pBwGroup->pszName, pcszId))
            pBwGroup = pBwGroup->pNext;

        rc = RTCritSectLeave(&pShaper->cs); AssertRC(rc);
    }

    return pBwGroup;
}
/**
 * Determine if the current Window manager is KWin (KDE)
 */
bool X11IsWindowManagerKWin()
{
    Atom typeReturned;
    Atom utf8Atom;
    int formatReturned;
    unsigned long ulNitemsReturned;
    unsigned long ulDummy;
    unsigned char *pcData = NULL;
    bool fIsKWinManaged = false;
    Display *display = QX11Info::display();
    Atom propNameAtom;
    Window WMWindow = None;

    propNameAtom = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", True);
    if (XGetWindowProperty(display, QX11Info::appRootWindow(), propNameAtom,
                           0, 512, False, XA_WINDOW, &typeReturned,
                           &formatReturned, &ulNitemsReturned, &ulDummy, &pcData)
                            == Success)
    {

        if (typeReturned == XA_WINDOW && formatReturned == 32)
            WMWindow = *((Window*) pcData);
        if (pcData)
            XFree(pcData);
        if (WMWindow != None)
        {
            propNameAtom = XInternAtom(display, "_NET_WM_NAME", True);
            utf8Atom = XInternAtom(display, "UTF8_STRING", True);
            if (XGetWindowProperty(QX11Info::display(), WMWindow, propNameAtom,
                                   0, 512, False, utf8Atom, &typeReturned,
                                   &formatReturned, &ulNitemsReturned, &ulDummy, &pcData)
                    == Success)
            {
                fIsKWinManaged = RTStrCmp((const char*)pcData, "KWin") == 0;
                if (pcData)
                    XFree(pcData);
            }
        }
    }
    return fIsKWinManaged;
}
RTDECL(int) RTKrnlModLoadedQueryInfo(const char *pszName, PRTKRNLMODINFO phKrnlModInfo)
{
    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
    AssertPtrReturn(phKrnlModInfo, VERR_INVALID_POINTER);

    int rc = VERR_NOT_FOUND;
    int iId = -1;
    struct modinfo ModInfo;

    ModInfo.mi_info   = MI_INFO_ALL | MI_INFO_CNT;
    ModInfo.mi_id     = iId;
    ModInfo.mi_nextid = iId;
    do
    {
        int rcSol = modctl(MODINFO, iId, &ModInfo);
        if (rcSol < 0)
        {
            rc = RTErrConvertFromErrno(errno);
            break;
        }

        if (ModInfo.mi_id != -1)
        {
            ModInfo.mi_name[MODMAXNAMELEN - 1] = '\0'; /* Paranoia. */
            if (!RTStrCmp(pszName, &ModInfo.mi_name[0]))
            {
                rc = rtKrnlModSolInfoCreate(&ModInfo, phKrnlModInfo);
                break;
            }
        }

        iId = ModInfo.mi_id;
    } while (iId != -1);

    return rc;
}
示例#16
0
RTR3DECL(int) RTFileModeToFlagsEx(const char *pszAccess, const char *pszDisposition,
                                  const char *pszSharing, uint64_t *puMode)
{
    AssertPtrReturn(pszAccess, VERR_INVALID_POINTER);
    AssertPtrReturn(pszDisposition, VERR_INVALID_POINTER);
    /* pszSharing is not used yet. */
    AssertPtrReturn(puMode, VERR_INVALID_POINTER);

    int rc = VINF_SUCCESS;

    const char *pszCur = pszAccess;
    uint64_t uMode = 0;
    char chPrev = 0;

    if (*pszCur == '\0')
        return VERR_INVALID_PARAMETER;

    /*
     * Handle access mode.
     */
    while (    pszCur
           && *pszCur != '\0')
    {
        bool fSkip = false;
        switch (*pszCur)
        {
            case 'b': /* Binary mode. */
                /* Just skip as being valid. */
                fSkip = true;
                break;

            case 'r': /* Read. */
                uMode |= RTFILE_O_READ;
                break;

            case 't': /* Text mode. */
                /* Just skip as being valid. */
                fSkip = true;
                break;

            case 'w': /* Write. */
                uMode |= RTFILE_O_WRITE;
                break;

            case '+':
            {
                switch (chPrev)
                {
                    case 'w':
                        /* Also use read access in write mode. */
                        uMode |= RTFILE_O_READ;
                        break;

                    case 'r':
                        /* Also use write access in read mode. */
                        uMode |= RTFILE_O_WRITE;
                        break;

                    case 'b':
                    case 't':
                        /* Silently eat skipped parameters. */
                        fSkip = true;
                        break;

                    case 0: /* No previous character yet. */
                    case '+':
                        /* Eat plusses which don't belong to a command. */
                        fSkip = true;
                        break;

                    default:
                        rc = VERR_INVALID_PARAMETER;
                        break;
                }

                break;
            }

            default:
                rc = VERR_INVALID_PARAMETER;
                break;
        }

        if (RT_FAILURE(rc))
            break;

        if (!fSkip)
            chPrev = *pszCur;
        pszCur++;
    }

    if (RT_FAILURE(rc))
        return rc;

    /*
     * Handle disposition.
     */
    pszCur = pszDisposition;

    /* Create a new file, always, overwrite an existing file. */
    if (!RTStrCmp(pszCur, "ca"))
        uMode |= RTFILE_O_CREATE_REPLACE;
    /* Create a new file if it does not exist, fail if exist. */
    else if (!RTStrCmp(pszCur, "ce"))
        uMode |= RTFILE_O_CREATE;
    /* Open existing file, create file if does not exist. */
    else if (!RTStrCmp(pszCur, "oc"))
        uMode |= RTFILE_O_OPEN_CREATE;
    /* Open existing file and place the file pointer at
     * the end of the file, if opened with write access.
     * Create the file if does not exist. */
    else if (!RTStrCmp(pszCur, "oa"))
        uMode |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND;
    /* Open existing, fail if does not exist. */
    else if (!RTStrCmp(pszCur, "oe"))
        uMode |= RTFILE_O_OPEN;
    /* Open and truncate existing, fail of not exist. */
    else if (!RTStrCmp(pszCur, "ot"))
        uMode |= RTFILE_O_OPEN | RTFILE_O_TRUNCATE;
    else
        rc = VERR_INVALID_PARAMETER;

    /* No action mask set? */
    if (   RT_SUCCESS(rc)
        && (uMode & RTFILE_O_ACTION_MASK) == 0)
        rc = VERR_INVALID_PARAMETER;

    /** @todo Handle sharing mode. */
    uMode |= RTFILE_O_DENY_NONE;

    if (RT_SUCCESS(rc))
        *puMode = uMode;

    return rc;
}
示例#17
0
/**
 * Run once function that initializes the kstats we need here.
 *
 * @returns IPRT status code.
 * @param   pvUser      Unused.
 */
static DECLCALLBACK(int) rtMpSolarisOnce(void *pvUser)
{
    int rc = VINF_SUCCESS;
    NOREF(pvUser);

    /*
     * Open kstat and find the cpu_info entries for each of the CPUs.
     */
    g_pKsCtl = kstat_open();
    if (g_pKsCtl)
    {
        g_capCpuInfo = RTMpGetCount();
        g_papCpuInfo = (kstat_t **)RTMemAllocZ(g_capCpuInfo * sizeof(kstat_t *));
        if (g_papCpuInfo)
        {
            g_cu64CoreIds = g_capCpuInfo;
            g_pu64CoreIds = (uint64_t *)RTMemAllocZ(g_cu64CoreIds * sizeof(uint64_t));
            if (g_pu64CoreIds)
            {
                rc = RTCritSectInit(&g_MpSolarisCritSect);
                if (RT_SUCCESS(rc))
                {
                    RTCPUID i = 0;
                    for (kstat_t *pKsp = g_pKsCtl->kc_chain; pKsp != NULL; pKsp = pKsp->ks_next)
                    {
                        if (!RTStrCmp(pKsp->ks_module, "cpu_info"))
                        {
                            AssertBreak(i < g_capCpuInfo);
                            g_papCpuInfo[i++] = pKsp;
                            /** @todo ks_instance == cpu_id (/usr/src/uts/common/os/cpu.c)? Check this and fix it ASAP. */
                        }
                    }

                    rc = rtMpSolarisGetCoreIds();
                    if (RT_SUCCESS(rc))
                        return VINF_SUCCESS;
                    else
                        Log(("rtMpSolarisGetCoreIds failed. rc=%Rrc\n", rc));
                }

                RTMemFree(g_pu64CoreIds);
                g_pu64CoreIds = NULL;
            }
            else
                rc = VERR_NO_MEMORY;

            /* bail out, we failed. */
            RTMemFree(g_papCpuInfo);
            g_papCpuInfo = NULL;
        }
        else
            rc = VERR_NO_MEMORY;
        kstat_close(g_pKsCtl);
        g_pKsCtl = NULL;
    }
    else
    {
        rc = RTErrConvertFromErrno(errno);
        if (RT_SUCCESS(rc))
            rc = VERR_INTERNAL_ERROR;
        Log(("kstat_open() -> %d (%Rrc)\n", errno, rc));
    }

    return rc;
}
示例#18
0
文件: manifest.cpp 项目: ryenus/vbox
RTR3DECL(int) RTManifestVerifyFilesBuf(void *pvBuf, size_t cbSize, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed)
{
    /* Validate input */
    AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
    AssertReturn(cbSize > 0, VERR_INVALID_PARAMETER);
    AssertPtrReturn(paTests, VERR_INVALID_POINTER);
    AssertReturn(cTests > 0, VERR_INVALID_PARAMETER);
    AssertPtrNullReturn(piFailed, VERR_INVALID_POINTER);

    int rc = VINF_SUCCESS;

    PRTMANIFESTFILEENTRY paFiles = (PRTMANIFESTFILEENTRY)RTMemTmpAllocZ(sizeof(RTMANIFESTFILEENTRY) * cTests);
    if (!paFiles)
        return VERR_NO_MEMORY;

    /* Fill our compare list */
    for (size_t i = 0; i < cTests; ++i)
        paFiles[i].pTestPattern = &paTests[i];

    char *pcBuf = (char*)pvBuf;
    size_t cbRead = 0;
    /* Parse the manifest file line by line */
    for (;;)
    {
        if (cbRead >= cbSize)
            break;

        size_t cch = rtManifestIndexOfCharInBuf(pcBuf, cbSize - cbRead, '\n') + 1;

        /* Skip empty lines (UNIX/DOS format) */
        if (   (   cch == 1
                && pcBuf[0] == '\n')
            || (   cch == 2
                && pcBuf[0] == '\r'
                && pcBuf[1] == '\n'))
        {
            pcBuf += cch;
            cbRead += cch;
            continue;
        }

        /** @todo r=bird:
         *  -# Better deal with this EOF line platform dependency
         *  -# The SHA1 test should probably include a blank space check.
         *  -# If there is a specific order to the elements in the string, it would be
         *     good if the delimiter searching checked for it.
         *  -# Deal with filenames containing delimiter characters.
         */

        /* Check for the digest algorithm */
        if (   cch < 4
            || !(   pcBuf[0] == 'S'
                 && pcBuf[1] == 'H'
                 && pcBuf[2] == 'A'
                 && pcBuf[3] == '1'))
        {
            /* Digest unsupported */
            rc = VERR_MANIFEST_UNSUPPORTED_DIGEST_TYPE;
            break;
        }

        /* Try to find the filename */
        char *pszNameStart = rtManifestPosOfCharInBuf(pcBuf, cch, '(');
        if (!pszNameStart)
        {
            rc = VERR_MANIFEST_WRONG_FILE_FORMAT;
            break;
        }
        char *pszNameEnd = rtManifestPosOfCharInBuf(pcBuf, cch, ')');
        if (!pszNameEnd)
        {
            rc = VERR_MANIFEST_WRONG_FILE_FORMAT;
            break;
        }

        /* Copy the filename part */
        size_t cchName = pszNameEnd - pszNameStart - 1;
        char *pszName = (char *)RTMemTmpAlloc(cchName + 1);
        if (!pszName)
        {
            rc = VERR_NO_MEMORY;
            break;
        }
        memcpy(pszName, pszNameStart + 1, cchName);
        pszName[cchName] = '\0';

        /* Try to find the digest sum */
        char *pszDigestStart = rtManifestPosOfCharInBuf(pcBuf, cch, '=') + 1;
        if (!pszDigestStart)
        {
            RTMemTmpFree(pszName);
            rc = VERR_MANIFEST_WRONG_FILE_FORMAT;
            break;
        }
        char *pszDigestEnd = rtManifestPosOfCharInBuf(pcBuf, cch, '\r');
        if (!pszDigestEnd)
            pszDigestEnd = rtManifestPosOfCharInBuf(pcBuf, cch, '\n');
        if (!pszDigestEnd)
        {
            rc = VERR_MANIFEST_WRONG_FILE_FORMAT;
            break;
        }
        /* Copy the digest part */
        size_t cchDigest = pszDigestEnd - pszDigestStart - 1;
        char *pszDigest = (char *)RTMemTmpAlloc(cchDigest + 1);
        if (!pszDigest)
        {
            rc = VERR_NO_MEMORY;
            break;
        }
        memcpy(pszDigest, pszDigestStart + 1, cchDigest);
        pszDigest[cchDigest] = '\0';

        /* Check our file list against the extracted data */
        bool fFound = false;
        for (size_t i = 0; i < cTests; ++i)
        {
            if (!RTStrCmp(RTPathFilename(paFiles[i].pTestPattern->pszTestFile), RTStrStrip(pszName)))
            {
                /* Add the data of the manifest file to the file list */
                paFiles[i].pszManifestFile = RTStrDup(RTStrStrip(pszName));
                paFiles[i].pszManifestDigest = RTStrDup(RTStrStrip(pszDigest));
                fFound = true;
                break;
            }
        }
        RTMemTmpFree(pszName);
        RTMemTmpFree(pszDigest);
        if (!fFound)
        {
            /* There have to be an entry in the file list */
            rc = VERR_MANIFEST_FILE_MISMATCH;
            break;
        }

        pcBuf += cch;
        cbRead += cch;
    }

    if (   rc == VINF_SUCCESS
        || rc == VERR_EOF)
    {
        rc = VINF_SUCCESS;
        for (size_t i = 0; i < cTests; ++i)
        {
            /* If there is an entry in the file list, which hasn't an
             * equivalent in the manifest file, its an error. */
            if (   !paFiles[i].pszManifestFile
                || !paFiles[i].pszManifestDigest)
            {
                rc = VERR_MANIFEST_FILE_MISMATCH;
                break;
            }

            /* Do the manifest SHA1 digest match against the actual digest? */
            if (RTStrICmp(paFiles[i].pszManifestDigest, paFiles[i].pTestPattern->pszTestDigest))
            {
                if (piFailed)
                    *piFailed = i;
                rc = VERR_MANIFEST_DIGEST_MISMATCH;
                break;
            }
        }
    }

    /* Cleanup */
    for (size_t i = 0; i < cTests; ++i)
    {
        if (paFiles[i].pszManifestFile)
            RTStrFree(paFiles[i].pszManifestFile);
        if (paFiles[i].pszManifestDigest)
            RTStrFree(paFiles[i].pszManifestDigest);
    }
    RTMemTmpFree(paFiles);

    RTPrintf("rc = %Rrc\n", rc);
    return rc;
}
示例#19
0
/**
 * Checks if two DBGC variables are identical
 *
 * @returns
 * @param   pVar1               .
 * @param   pVar2               .
 */
bool DBGCVarAreIdentical(PCDBGCVAR pVar1, PCDBGCVAR pVar2)
{
    if (!pVar1)
        return false;
    if (pVar1 == pVar2)
        return true;

    if (pVar1->enmType != pVar2->enmType)
        return false;
    switch (pVar1->enmType)
    {
        case DBGCVAR_TYPE_GC_FLAT:
            if (pVar1->u.GCFlat != pVar2->u.GCFlat)
                return false;
            break;
        case DBGCVAR_TYPE_GC_FAR:
            if (pVar1->u.GCFar.off != pVar2->u.GCFar.off)
                return false;
            if (pVar1->u.GCFar.sel != pVar2->u.GCFar.sel)
                return false;
            break;
        case DBGCVAR_TYPE_GC_PHYS:
            if (pVar1->u.GCPhys != pVar2->u.GCPhys)
                return false;
            break;
        case DBGCVAR_TYPE_HC_FLAT:
            if (pVar1->u.pvHCFlat != pVar2->u.pvHCFlat)
                return false;
            break;
        case DBGCVAR_TYPE_HC_PHYS:
            if (pVar1->u.HCPhys != pVar2->u.HCPhys)
                return false;
            break;
        case DBGCVAR_TYPE_NUMBER:
            if (pVar1->u.u64Number != pVar2->u.u64Number)
                return false;
            break;
        case DBGCVAR_TYPE_STRING:
        case DBGCVAR_TYPE_SYMBOL:
            if (RTStrCmp(pVar1->u.pszString, pVar2->u.pszString) != 0)
                return false;
            break;
        default:
            AssertFailedReturn(false);
    }

    if (pVar1->enmRangeType != pVar2->enmRangeType)
        return false;
    switch (pVar1->enmRangeType)
    {
        case DBGCVAR_RANGE_NONE:
            break;

        case DBGCVAR_RANGE_ELEMENTS:
        case DBGCVAR_RANGE_BYTES:
            if (pVar1->u64Range != pVar2->u64Range)
                return false;
            break;
        default:
            AssertFailedReturn(false);
    }

    return true;
}
示例#20
0
int DnDURIList::appendPathRecursive(const char *pcszSrcPath,
                                    const char *pcszDstPath, const char *pcszDstBase, size_t cchDstBase, uint32_t fFlags)
{
    AssertPtrReturn(pcszSrcPath, VERR_INVALID_POINTER);
    AssertPtrReturn(pcszDstBase, VERR_INVALID_POINTER);
    AssertPtrReturn(pcszDstPath, VERR_INVALID_POINTER);

    LogFlowFunc(("pcszSrcPath=%s, pcszDstPath=%s, pcszDstBase=%s, cchDstBase=%zu\n",
                 pcszSrcPath, pcszDstPath, pcszDstBase, cchDstBase));

    RTFSOBJINFO objInfo;
    int rc = RTPathQueryInfo(pcszSrcPath, &objInfo, RTFSOBJATTRADD_NOTHING);
    if (RT_SUCCESS(rc))
    {
        if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
        {
            rc = addEntry(pcszSrcPath, &pcszDstPath[cchDstBase], fFlags);

            if (RT_SUCCESS(rc))
            {
                PRTDIR hDir;
                rc = RTDirOpen(&hDir, pcszSrcPath);
                if (RT_SUCCESS(rc))
                {
                    do
                    {
                        RTDIRENTRY DirEntry;
                        rc = RTDirRead(hDir, &DirEntry, NULL);
                        if (RT_FAILURE(rc))
                        {
                            if (rc == VERR_NO_MORE_FILES)
                                rc = VINF_SUCCESS;
                            break;
                        }

                        switch (DirEntry.enmType)
                        {
                            case RTDIRENTRYTYPE_DIRECTORY:
                            {
                                /* Skip "." and ".." entries. */
                                if (   RTStrCmp(DirEntry.szName, ".")  == 0
                                    || RTStrCmp(DirEntry.szName, "..") == 0)
                                    break;

                                char *pszSrc = RTPathJoinA(pcszSrcPath, DirEntry.szName);
                                if (pszSrc)
                                {
                                    char *pszDst = RTPathJoinA(pcszDstPath, DirEntry.szName);
                                    if (pszDst)
                                    {
                                        rc = appendPathRecursive(pszSrc, pszDst, pcszDstBase, cchDstBase, fFlags);
                                        RTStrFree(pszDst);
                                    }
                                    else
                                        rc = VERR_NO_MEMORY;

                                    RTStrFree(pszSrc);
                                }
                                else
                                    rc = VERR_NO_MEMORY;
                                break;
                            }

                            case RTDIRENTRYTYPE_FILE:
                            {
                                char *pszSrc = RTPathJoinA(pcszSrcPath, DirEntry.szName);
                                if (pszSrc)
                                {
                                    char *pszDst = RTPathJoinA(pcszDstPath, DirEntry.szName);
                                    if (pszDst)
                                    {
                                        rc = addEntry(pszSrc, &pszDst[cchDstBase], fFlags);
                                        RTStrFree(pszDst);
                                    }
                                    else
                                        rc = VERR_NO_MEMORY;
                                    RTStrFree(pszSrc);
                                }
                                else
                                    rc = VERR_NO_MEMORY;
                                break;
                            }
                            case RTDIRENTRYTYPE_SYMLINK:
                            {
                                if (fFlags & DNDURILIST_FLAGS_RESOLVE_SYMLINKS)
                                {
                                    char *pszSrc = RTPathRealDup(pcszDstBase);
                                    if (pszSrc)
                                    {
                                        rc = RTPathQueryInfo(pszSrc, &objInfo, RTFSOBJATTRADD_NOTHING);
                                        if (RT_SUCCESS(rc))
                                        {
                                            if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
                                            {
                                                LogFlowFunc(("Directory entry is symlink to directory\n"));
                                                rc = appendPathRecursive(pszSrc, pcszDstPath, pcszDstBase, cchDstBase, fFlags);
                                            }
                                            else if (RTFS_IS_FILE(objInfo.Attr.fMode))
                                            {
                                                LogFlowFunc(("Directory entry is symlink to file\n"));
                                                rc = addEntry(pszSrc, &pcszDstPath[cchDstBase], fFlags);
                                            }
                                            else
                                                rc = VERR_NOT_SUPPORTED;
                                        }

                                        RTStrFree(pszSrc);
                                    }
                                    else
                                        rc = VERR_NO_MEMORY;
                                }
                                break;
                            }

                            default:
                                break;
                        }

                    } while (RT_SUCCESS(rc));

                    RTDirClose(hDir);
                }
            }
        }
        else if (RTFS_IS_FILE(objInfo.Attr.fMode))
        {
            rc = addEntry(pcszSrcPath, &pcszDstPath[cchDstBase], fFlags);
        }
        else if (RTFS_IS_SYMLINK(objInfo.Attr.fMode))
        {
            if (fFlags & DNDURILIST_FLAGS_RESOLVE_SYMLINKS)
            {
                char *pszSrc = RTPathRealDup(pcszSrcPath);
                if (pszSrc)
                {
                    rc = RTPathQueryInfo(pszSrc, &objInfo, RTFSOBJATTRADD_NOTHING);
                    if (RT_SUCCESS(rc))
                    {
                        if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
                        {
                            LogFlowFunc(("Symlink to directory\n"));
                            rc = appendPathRecursive(pszSrc, pcszDstPath, pcszDstBase, cchDstBase, fFlags);
                        }
                        else if (RTFS_IS_FILE(objInfo.Attr.fMode))
                        {
                            LogFlowFunc(("Symlink to file\n"));
                            rc = addEntry(pszSrc, &pcszDstPath[cchDstBase], fFlags);
                        }
                        else
                            rc = VERR_NOT_SUPPORTED;
                    }

                    RTStrFree(pszSrc);
                }
                else
                    rc = VERR_NO_MEMORY;
            }
        }
        else
            rc = VERR_NOT_SUPPORTED;
    }

    LogFlowFuncLeaveRC(rc);
    return rc;
}
示例#21
0
static int rcp_get_token(struct rcp_parser *parser)
{
    char tok = ' ';
    char *ptr;
    size_t ptr_len;

    while (isspace(tok))
        tok = GETCHAR(parser);

    ptr = parser->rcpp_str_buffer;

    /* tok can't be ipv4 */
    if (isalnum(tok)) {
        int xdigit, digit, dot_number;
        RT_ZERO(parser->rcpp_str_buffer);

        dot_number = 0;
        xdigit = 1;
        digit = 1;
        do {
            *ptr++ = tok;
            tok = GETCHAR(parser);

            if (!isalnum(tok) && tok != ':' && tok != '.' && tok != '-' && tok != '_')
                break;

            /**
             * if before ':' there were only [0-9][a-f][A-F],
             * then it can't be option.
             */
            xdigit &= (isxdigit(tok) || (tok == ':'));
            /**
             * We want hint to differ ipv4 and network name.
             */
            digit &= (isdigit(tok) || (tok == '.'));

            if (tok == ':')
            {
                if (xdigit == 1)
                {
                    int port = 0;
                    do
                    {
                        *ptr++ = tok;
                        tok = GETCHAR(parser);

                        if (tok == '.')
                            port++;

                    } while(PARSER_STOP(tok, parser, ptr) && (tok == ':' || tok == '.' || isxdigit(tok)));

                    PARSER_BUFFER_EXCEEDED(parser, ptr);

                    if (port == 0)
                        return tok_ipv6;
                    else if (port == 1)
                        return tok_ipv6_port;
                    else
                    {
                        /* eats rest of the token */
                        do
                        {
                            *ptr++ = tok;
                            tok = GETCHAR(parser);
                        } while(   PARSER_STOP(tok, parser, ptr)
                                && (isalnum(tok) || tok == '.'  || tok == '_' || tok == '-'));

                        PARSER_BUFFER_EXCEEDED(parser, ptr);

                        return tok_string;
                    }
                }
                else {
                    /* XXX: need further experiments */
                    return tok_option; /* option with value */
                }
            }

            if (tok == '.')
            {
                do {
                    if (tok == '.') dot_number++;

                    *ptr++ = tok;
                    digit &= (isdigit(tok) || (tok == '.'));
                    tok = GETCHAR(parser);
                } while(   PARSER_STOP(tok, parser, ptr)
                        && (isalnum(tok) || tok == '.' || tok == '_' || tok == '-'));

                PARSER_BUFFER_EXCEEDED(parser, ptr);

                if (dot_number == 3 && digit)
                    return tok_ipv4;
                else if (dot_number == 4 && digit)
                    return tok_ipv4_port;
                else
                    return tok_string;
            }
        } while(   PARSER_STOP(tok, parser, ptr)
                && (isalnum(tok) || tok == ':' || tok == '.' || tok == '-' || tok == '_'));

        PARSER_BUFFER_EXCEEDED(parser, ptr);

        if (digit || xdigit)
            return tok_number;
        if (RTStrCmp(parser->rcpp_str_buffer, "nameserver") == 0)
            return tok_nameserver;
        if (RTStrCmp(parser->rcpp_str_buffer, "port") == 0)
            return tok_port;
        if (RTStrCmp(parser->rcpp_str_buffer, "domain") == 0)
            return tok_domain;
        if (RTStrCmp(parser->rcpp_str_buffer, "search") == 0)
            return tok_search;
        if (RTStrCmp(parser->rcpp_str_buffer, "search_order") == 0)
            return tok_search_order;
        if (RTStrCmp(parser->rcpp_str_buffer, "sortlist") == 0)
            return tok_sortlist;
        if (RTStrCmp(parser->rcpp_str_buffer, "timeout") == 0)
            return tok_timeout;
        if (RTStrCmp(parser->rcpp_str_buffer, "options") == 0)
            return tok_options;

        return tok_string;
    }

    if (tok == EOF) return tok_eof;

    if (tok == '#')
    {
        do{
            tok = GETCHAR(parser);
        } while (tok != EOF && tok != '\r' && tok != '\n');

        if (tok == EOF) return tok_eof;

        return tok_comment;
    }
    return tok;
}
示例#22
0
int DnDURIList::appendPathRecursive(const char *pcszPath, size_t cbBaseLen,
                                    uint32_t fFlags)
{
    AssertPtrReturn(pcszPath, VERR_INVALID_POINTER);

    RTFSOBJINFO objInfo;
    int rc = RTPathQueryInfo(pcszPath, &objInfo, RTFSOBJATTRADD_NOTHING);
    if (RT_FAILURE(rc))
        return rc;

    /*
     * These are the types we currently support. Symlinks are not directly
     * supported. First the guest could be an OS which doesn't support it and
     * second the symlink could point to a file which is out of the base tree.
     * Both things are hard to support. For now we just copy the target file in
     * this case.
     */
    if (!(   RTFS_IS_DIRECTORY(objInfo.Attr.fMode)
          || RTFS_IS_FILE(objInfo.Attr.fMode)
          || RTFS_IS_SYMLINK(objInfo.Attr.fMode)))
        return VINF_SUCCESS;

    uint64_t cbSize = 0;
    rc = RTFileQuerySize(pcszPath, &cbSize);
    if (rc == VERR_IS_A_DIRECTORY)
        rc = VINF_SUCCESS;

    if (RT_FAILURE(rc))
        return rc;

    m_lstTree.append(DnDURIObject(  RTFS_IS_DIRECTORY(objInfo.Attr.fMode)
                                  ? DnDURIObject::Directory
                                  : DnDURIObject::File,
                                  pcszPath, &pcszPath[cbBaseLen],
                                  objInfo.Attr.fMode, cbSize));
    m_cbTotal += cbSize;
#ifdef DEBUG_andy
    LogFlowFunc(("strSrcPath=%s, strDstPath=%s, fMode=0x%x, cbSize=%RU64, cbTotal=%zu\n",
                 pcszPath, &pcszPath[cbBaseLen], objInfo.Attr.fMode, cbSize, m_cbTotal));
#endif

    PRTDIR hDir;
    /* We have to try to open even symlinks, cause they could
     * be symlinks to directories. */
    rc = RTDirOpen(&hDir, pcszPath);
    /* The following error happens when this was a symlink
     * to an file or a regular file. */
    if (   rc == VERR_PATH_NOT_FOUND
        || rc == VERR_NOT_A_DIRECTORY)
        return VINF_SUCCESS;
    if (RT_FAILURE(rc))
        return rc;

    while (RT_SUCCESS(rc))
    {
        RTDIRENTRY DirEntry;
        rc = RTDirRead(hDir, &DirEntry, NULL);
        if (RT_FAILURE(rc))
        {
            if (rc == VERR_NO_MORE_FILES)
                rc = VINF_SUCCESS;
            break;
        }
        switch (DirEntry.enmType)
        {
            case RTDIRENTRYTYPE_DIRECTORY:
            {
                /* Skip "." and ".." entries. */
                if (   RTStrCmp(DirEntry.szName, ".")  == 0
                    || RTStrCmp(DirEntry.szName, "..") == 0)
                    break;

                char *pszRecDir = RTPathJoinA(pcszPath, DirEntry.szName);
                if (pszRecDir)
                {
                    rc = appendPathRecursive(pszRecDir, cbBaseLen, fFlags);
                    RTStrFree(pszRecDir);
                }
                else
                    rc = VERR_NO_MEMORY;
                break;
            }
            case RTDIRENTRYTYPE_SYMLINK:
            case RTDIRENTRYTYPE_FILE:
            {
                char *pszNewFile = RTPathJoinA(pcszPath, DirEntry.szName);
                if (pszNewFile)
                {
                    /* We need the size and the mode of the file. */
                    RTFSOBJINFO objInfo1;
                    rc = RTPathQueryInfo(pszNewFile, &objInfo1, RTFSOBJATTRADD_NOTHING);
                    if (RT_FAILURE(rc))
                        return rc;
                    rc = RTFileQuerySize(pszNewFile, &cbSize);
                    if (rc == VERR_IS_A_DIRECTORY) /* Happens for symlinks. */
                        rc = VINF_SUCCESS;

                    if (RT_FAILURE(rc))
                        break;

                    if (RTFS_IS_FILE(objInfo.Attr.fMode))
                    {
                        m_lstTree.append(DnDURIObject(DnDURIObject::File,
                                                      pszNewFile, &pszNewFile[cbBaseLen],
                                                      objInfo1.Attr.fMode, cbSize));
                        m_cbTotal += cbSize;
                    }
                    else /* Handle symlink directories. */
                        rc = appendPathRecursive(pszNewFile, cbBaseLen, fFlags);
#ifdef DEBUG_andy
                    LogFlowFunc(("strSrcPath=%s, strDstPath=%s, fMode=0x%x, cbSize=%RU64, cbTotal=%zu\n",
                                 pszNewFile, &pszNewFile[cbBaseLen], objInfo1.Attr.fMode, cbSize, m_cbTotal));
#endif
                    RTStrFree(pszNewFile);
                }
                else
                    rc = VERR_NO_MEMORY;
                break;
            }

            default:
                break;
        }
    }

    RTDirClose(hDir);
    return rc;
}
示例#23
0
文件: tar.cpp 项目: mcenirm/vbox
RTR3DECL(int) RTTarFileOpen(RTTAR hTar, PRTTARFILE phFile, const char *pszFilename, uint32_t fOpen)
{
    /* Write only interface now. */
    AssertReturn(fOpen & RTFILE_O_WRITE, VERR_INVALID_PARAMETER);

    PRTTARINTERNAL pInt = hTar;
    RTTAR_VALID_RETURN(pInt);

    if (!pInt->hTarFile)
        return VERR_INVALID_HANDLE;

    if (fOpen & RTFILE_O_WRITE)
    {
        if (!(pInt->fOpenMode & RTFILE_O_WRITE))
            return VERR_WRITE_PROTECT;
        if (pInt->fFileOpenForWrite)
            return VERR_TOO_MANY_OPEN_FILES;
    }

    int rc = VINF_SUCCESS;
    if (!(fOpen & RTFILE_O_WRITE))
    {
        /*
         * Rewind the stream if necessary.
         */
        if (!pInt->fFssAtStart)
        {
            if (pInt->hVfsFss != NIL_RTVFSFSSTREAM)
            {
                uint32_t cRefs = RTVfsFsStrmRelease(pInt->hVfsFss); Assert(cRefs != UINT32_MAX);
                pInt->hVfsFss  = NIL_RTVFSFSSTREAM;
            }

            if (pInt->hVfsFile == NIL_RTVFSFILE)
            {
                rc = RTVfsFileFromRTFile(pInt->hTarFile, RTFILE_O_READ, true /*fLeaveOpen*/, &pInt->hVfsFile);
                if (RT_FAILURE(rc))
                    return rc;
            }

            RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(pInt->hVfsFile);
            rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &pInt->hVfsFss);
            RTVfsIoStrmRelease(hVfsIos);
            if (RT_FAILURE(rc))
                return rc;
        }

        /*
         * Search the file system stream.
         */
        pInt->fFssAtStart = false;
        for (;;)
        {
            char           *pszName;
            RTVFSOBJTYPE    enmType;
            RTVFSOBJ        hVfsObj;
            rc = RTVfsFsStrmNext(pInt->hVfsFss, &pszName, &enmType, &hVfsObj);
            if (rc == VERR_EOF)
                return VERR_FILE_NOT_FOUND;
            if (RT_FAILURE(rc))
                return rc;

            if (!RTStrCmp(pszName, pszFilename))
            {
                if (enmType == RTVFSOBJTYPE_FILE || enmType == RTVFSOBJTYPE_IO_STREAM)
                    rc = rtTarFileCreateHandleForReadOnly(pszName, RTVfsObjToIoStream(hVfsObj), fOpen, phFile);
                else
                {
                    rc = VERR_UNEXPECTED_FS_OBJ_TYPE;
                    RTStrFree(pszName);
                }
                RTVfsObjRelease(hVfsObj);
                break;
            }
            RTStrFree(pszName);
            RTVfsObjRelease(hVfsObj);
        } /* Search loop. */
    }
    else
    {
        PRTTARFILEINTERNAL pFileInt = rtTarFileCreateForWrite(pInt, pszFilename, fOpen);
        if (!pFileInt)
            return VERR_NO_MEMORY;

        pInt->fFileOpenForWrite = true;

        /* If we are in write mode, we also in append mode. Add an dummy
         * header at the end of the current file. It will be filled by the
         * close operation. */
        rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_END, &pFileInt->offStart);
        if (RT_SUCCESS(rc))
        {
            RTTARRECORD record;
            RT_ZERO(record);
            rc = RTFileWrite(pFileInt->pTar->hTarFile, &record, sizeof(RTTARRECORD), NULL);
        }

        if (RT_SUCCESS(rc))
            *phFile = (RTTARFILE)pFileInt;
        else
        {
            /* Cleanup on failure */
            if (pFileInt->pszFilename)
                RTStrFree(pFileInt->pszFilename);
            RTMemFree(pFileInt);
        }
    }

    return rc;
}
/**
 * Value string -> Value union.
 *
 * @returns IPRT status code.
 * @param   fFlags              The value flags.
 * @param   pszValue            The value string.
 * @param   pValueUnion         Where to return the processed value.
 */
static int rtGetOptProcessValue(uint32_t fFlags, const char *pszValue, PRTGETOPTUNION pValueUnion)
{
    /*
     * Transform into a option value as requested.
     * If decimal conversion fails, we'll check for "0x<xdigit>" and
     * try a 16 based conversion. We will not interpret any of the
     * generic ints as octals.
     */
    uint32_t const fSwitchValue =  fFlags & (  RTGETOPT_REQ_MASK
                                             | RTGETOPT_FLAG_HEX
                                             | RTGETOPT_FLAG_DEC
                                             | RTGETOPT_FLAG_OCT);
    switch (fSwitchValue)
    {
        case RTGETOPT_REQ_STRING:
            pValueUnion->psz = pszValue;
            break;

        case RTGETOPT_REQ_BOOL:
            if (   !RTStrICmp(pszValue, "true")
                || !RTStrICmp(pszValue, "t")
                || !RTStrICmp(pszValue, "yes")
                || !RTStrICmp(pszValue, "y")
                || !RTStrICmp(pszValue, "enabled")
                || !RTStrICmp(pszValue, "enable")
                || !RTStrICmp(pszValue, "en")
                || !RTStrICmp(pszValue, "e")
                || !RTStrICmp(pszValue, "on")
                || !RTStrCmp(pszValue, "1")
                )
                pValueUnion->f = true;
            else if (   !RTStrICmp(pszValue, "false")
                     || !RTStrICmp(pszValue, "f")
                     || !RTStrICmp(pszValue, "no")
                     || !RTStrICmp(pszValue, "n")
                     || !RTStrICmp(pszValue, "disabled")
                     || !RTStrICmp(pszValue, "disable")
                     || !RTStrICmp(pszValue, "dis")
                     || !RTStrICmp(pszValue, "d")
                     || !RTStrICmp(pszValue, "off")
                     || !RTStrCmp(pszValue, "0")
                     )
                pValueUnion->f = false;
            else
            {
                pValueUnion->psz = pszValue;
                return VERR_GETOPT_UNKNOWN_OPTION;
            }
            break;

        case RTGETOPT_REQ_BOOL_ONOFF:
            if (!RTStrICmp(pszValue, "on"))
                pValueUnion->f = true;
            else if (!RTStrICmp(pszValue, "off"))
                pValueUnion->f = false;
            else
            {
                pValueUnion->psz = pszValue;
                return VERR_GETOPT_UNKNOWN_OPTION;
            }
            break;

#define MY_INT_CASE(req, type, memb, convfn) \
            case req: \
            { \
                type Value; \
                if (    convfn(pszValue, 10, &Value) != VINF_SUCCESS \
                    &&  (   pszValue[0] != '0' \
                         || (pszValue[1] != 'x' && pszValue[1] != 'X') \
                         || !RT_C_IS_XDIGIT(pszValue[2]) \
                         || convfn(pszValue, 16, &Value) != VINF_SUCCESS ) ) \
                    return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
                pValueUnion->memb = Value; \
                break; \
            }
#define MY_BASE_INT_CASE(req, type, memb, convfn, base) \
            case req: \
            { \
                type Value; \
                if (convfn(pszValue, base, &Value) != VINF_SUCCESS) \
                    return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
                pValueUnion->memb = Value; \
                break; \
            }

        MY_INT_CASE(RTGETOPT_REQ_INT8,   int8_t,   i8,  RTStrToInt8Full)
        MY_INT_CASE(RTGETOPT_REQ_INT16,  int16_t,  i16, RTStrToInt16Full)
        MY_INT_CASE(RTGETOPT_REQ_INT32,  int32_t,  i32, RTStrToInt32Full)
        MY_INT_CASE(RTGETOPT_REQ_INT64,  int64_t,  i64, RTStrToInt64Full)
        MY_INT_CASE(RTGETOPT_REQ_UINT8,  uint8_t,  u8,  RTStrToUInt8Full)
        MY_INT_CASE(RTGETOPT_REQ_UINT16, uint16_t, u16, RTStrToUInt16Full)
        MY_INT_CASE(RTGETOPT_REQ_UINT32, uint32_t, u32, RTStrToUInt32Full)
        MY_INT_CASE(RTGETOPT_REQ_UINT64, uint64_t, u64, RTStrToUInt64Full)

        MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_HEX, int8_t,   i8,  RTStrToInt8Full,   16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_HEX, int16_t,  i16, RTStrToInt16Full,  16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_HEX, int32_t,  i32, RTStrToInt32Full,  16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_HEX, int64_t,  i64, RTStrToInt64Full,  16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_HEX, uint8_t,  u8,  RTStrToUInt8Full,  16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_HEX, uint16_t, u16, RTStrToUInt16Full, 16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX, uint32_t, u32, RTStrToUInt32Full, 16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX, uint64_t, u64, RTStrToUInt64Full, 16)

        MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_DEC, int8_t,   i8,  RTStrToInt8Full,   10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_DEC, int16_t,  i16, RTStrToInt16Full,  10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_DEC, int32_t,  i32, RTStrToInt32Full,  10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_DEC, int64_t,  i64, RTStrToInt64Full,  10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_DEC, uint8_t,  u8,  RTStrToUInt8Full,  10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_DEC, uint16_t, u16, RTStrToUInt16Full, 10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_DEC, uint32_t, u32, RTStrToUInt32Full, 10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_DEC, uint64_t, u64, RTStrToUInt64Full, 10)

        MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_OCT, int8_t,   i8,  RTStrToInt8Full,   8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_OCT, int16_t,  i16, RTStrToInt16Full,  8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_OCT, int32_t,  i32, RTStrToInt32Full,  8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_OCT, int64_t,  i64, RTStrToInt64Full,  8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_OCT, uint8_t,  u8,  RTStrToUInt8Full,  8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_OCT, uint16_t, u16, RTStrToUInt16Full, 8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT, uint32_t, u32, RTStrToUInt32Full, 8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_OCT, uint64_t, u64, RTStrToUInt64Full, 8)

#undef MY_INT_CASE
#undef MY_BASE_INT_CASE

        case RTGETOPT_REQ_IPV4ADDR:
        {
            RTNETADDRIPV4 Addr;
            if (rtgetoptConvertIPv4Addr(pszValue, &Addr) != VINF_SUCCESS)
                return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
            pValueUnion->IPv4Addr = Addr;
            break;
        }

        case RTGETOPT_REQ_IPV4CIDR:
        {
            RTNETADDRIPV4 network;
            RTNETADDRIPV4 netmask;
            if (RT_FAILURE(RTCidrStrToIPv4(pszValue, &network, &netmask)))
              return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
            pValueUnion->CidrIPv4.IPv4Network.u = network.u;
            pValueUnion->CidrIPv4.IPv4Netmask.u = netmask.u;
            break;
        }

        case RTGETOPT_REQ_MACADDR:
        {
            RTMAC Addr;
            if (rtgetoptConvertMacAddr(pszValue, &Addr) != VINF_SUCCESS)
                return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
            pValueUnion->MacAddr = Addr;
            break;
        }

        case RTGETOPT_REQ_UUID:
        {
            RTUUID Uuid;
            if (RTUuidFromStr(&Uuid, pszValue) != VINF_SUCCESS)
                return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
            pValueUnion->Uuid = Uuid;
            break;
        }

#define MY_INT_PAIR_CASE(a_fReqValue, a_fReqValueOptional, a_Type, a_MemberPrefix, a_fnConv, a_ConvBase, a_DefaultValue) \
            case a_fReqValue: \
            case a_fReqValueOptional: \
            { \
                /* First value: */ \
                a_Type Value1; \
                char *pszNext = NULL; \
                unsigned uBase =   pszValue[0] == '0' \
                                && (pszValue[1] == 'x' || pszValue[1] == 'X') \
                                && RT_C_IS_XDIGIT(pszValue[2]) \
                              ? 16 : a_ConvBase; \
                int rc = a_fnConv(pszValue, &pszNext, uBase, &Value1); \
                if (rc == VINF_SUCCESS || rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES) \
                { \
                    /* The second value, could be optional: */ \
                    a_Type Value2 = a_DefaultValue; \
                    pszValue = pszNext;\
                    if (pszValue) \
                    { \
                        while (RT_C_IS_BLANK(*pszValue)) \
                            pszValue++; \
                        if (*pszValue == ':' || *pszValue == '/' || *pszValue == '|') \
                            do pszValue++; \
                            while (RT_C_IS_BLANK(*pszValue)); \
                        if (pszValue != pszNext) \
                        { \
                            uBase =    pszValue[0] == '0' \
                                    && (pszValue[1] == 'x' || pszValue[1] == 'X') \
                                    && RT_C_IS_XDIGIT(pszValue[2]) \
                                  ? 16 : a_ConvBase; \
                            rc = a_fnConv(pszValue, &pszNext, uBase, &Value2); \
                            if (rc == VINF_SUCCESS) \
                            { /* likely */ } \
                            else \
                               { RTAssertMsg2("z rc=%Rrc: '%s' '%s' uBase=%d\n", rc, pszValue, pszNext, uBase); return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; } \
                        } \
                        else if (fSwitchValue != (a_fReqValueOptional)) \
                        { RTAssertMsg2("x\n"); return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; } \
                    } \
                    else if (fSwitchValue != (a_fReqValueOptional)) \
                        { RTAssertMsg2("y\n"); return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; } \
                    pValueUnion->a_MemberPrefix##Second = Value2; \
                    pValueUnion->a_MemberPrefix##First  = Value1; \
                    break; \
                } \
                return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
            }

        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT32_PAIR,                      RTGETOPT_REQ_UINT32_OPTIONAL_PAIR,
                         uint32_t, PairU32.u, RTStrToUInt32Ex, 10, UINT32_MAX)
        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT32_PAIR | RTGETOPT_FLAG_DEC,  RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_DEC,
                         uint32_t, PairU32.u, RTStrToUInt32Ex, 10, UINT32_MAX)
        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT32_PAIR | RTGETOPT_FLAG_HEX,  RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX,
                         uint32_t, PairU32.u, RTStrToUInt32Ex, 16, UINT32_MAX)
        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT32_PAIR | RTGETOPT_FLAG_OCT,  RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_OCT,
                         uint32_t, PairU32.u, RTStrToUInt32Ex,  8, UINT32_MAX)

        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT64_PAIR,                      RTGETOPT_REQ_UINT64_OPTIONAL_PAIR,
                         uint64_t, PairU64.u, RTStrToUInt64Ex, 10, UINT64_MAX)
        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT64_PAIR | RTGETOPT_FLAG_DEC,  RTGETOPT_REQ_UINT64_OPTIONAL_PAIR | RTGETOPT_FLAG_DEC,
                         uint64_t, PairU64.u, RTStrToUInt64Ex, 10, UINT64_MAX)
        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT64_PAIR | RTGETOPT_FLAG_HEX,  RTGETOPT_REQ_UINT64_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX,
                         uint64_t, PairU64.u, RTStrToUInt64Ex, 16, UINT64_MAX)
        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT64_PAIR | RTGETOPT_FLAG_OCT,  RTGETOPT_REQ_UINT64_OPTIONAL_PAIR | RTGETOPT_FLAG_OCT,
                         uint64_t, PairU64.u, RTStrToUInt64Ex,  8, UINT64_MAX)

        default:
            AssertMsgFailed(("f=%#x\n", fFlags));
            return VERR_INTERNAL_ERROR;
    }

    return VINF_SUCCESS;
}
RTDECL(int) RTPathCalcRelative(char *pszPathDst, size_t cbPathDst,
                               const char *pszPathFrom,
                               const char *pszPathTo)
{
    int rc = VINF_SUCCESS;

    AssertPtrReturn(pszPathDst, VERR_INVALID_POINTER);
    AssertReturn(cbPathDst, VERR_INVALID_PARAMETER);
    AssertPtrReturn(pszPathFrom, VERR_INVALID_POINTER);
    AssertPtrReturn(pszPathTo, VERR_INVALID_POINTER);
    AssertReturn(RTPathStartsWithRoot(pszPathFrom), VERR_INVALID_PARAMETER);
    AssertReturn(RTPathStartsWithRoot(pszPathTo), VERR_INVALID_PARAMETER);
    AssertReturn(RTStrCmp(pszPathFrom, pszPathTo), VERR_INVALID_PARAMETER);

    /*
     * Check for different root specifiers (drive letters), creating a relative path doesn't work here.
     * @todo: How to handle case insensitive root specifiers correctly?
     */
    size_t offRootFrom = rtPathRootSpecLen(pszPathFrom);
    size_t offRootTo   = rtPathRootSpecLen(pszPathTo);

    if (   offRootFrom != offRootTo
        || RTStrNCmp(pszPathFrom, pszPathTo, offRootFrom))
        return VERR_NOT_SUPPORTED;

    /* Filter out the parent path which is equal to both paths. */
    while (   *pszPathFrom == *pszPathTo
           && *pszPathFrom != '\0'
           && *pszPathTo != '\0')
    {
        pszPathFrom++;
        pszPathTo++;
    }

    /*
     * Because path components can start with an equal string but differ afterwards we
     * need to go back to the beginning of the current component.
     */
    while (!RTPATH_IS_SEP(*pszPathFrom))
        pszPathFrom--;

    pszPathFrom++; /* Skip path separator. */

    while (!RTPATH_IS_SEP(*pszPathTo))
        pszPathTo--;

    pszPathTo++; /* Skip path separator. */

    /* Paths point to the first non equal component now. */
    char aszPathTmp[RTPATH_MAX + 1];
    unsigned offPathTmp = 0;

    /* Create the part to go up from pszPathFrom. */
    while (*pszPathFrom != '\0')
    {
        while (   !RTPATH_IS_SEP(*pszPathFrom)
               && *pszPathFrom != '\0')
            pszPathFrom++;

        if (RTPATH_IS_SEP(*pszPathFrom))
        {
            if (offPathTmp + 3 >= sizeof(aszPathTmp) - 1)
                return VERR_FILENAME_TOO_LONG;
            aszPathTmp[offPathTmp++] = '.';
            aszPathTmp[offPathTmp++] = '.';
            aszPathTmp[offPathTmp++] = RTPATH_SLASH;
            pszPathFrom++;
        }
    }

    aszPathTmp[offPathTmp] = '\0';

    /* Now append the rest of pszPathTo to the final path. */
    char *pszPathTmp = &aszPathTmp[offPathTmp];
    size_t cbPathTmp = sizeof(aszPathTmp) - offPathTmp - 1;
    rc = RTStrCatP(&pszPathTmp, &cbPathTmp, pszPathTo);
    if (RT_SUCCESS(rc))
    {
        *pszPathTmp = '\0';

        size_t cchPathTmp = strlen(aszPathTmp);
        if (cchPathTmp >= cbPathDst)
           return VERR_BUFFER_OVERFLOW;
        memcpy(pszPathDst, aszPathTmp, cchPathTmp + 1);
    }
    else
        rc = VERR_FILENAME_TOO_LONG;

    return rc;
}
示例#26
0
int DnDHGSendDataMessage::buildFileTree(const char *pcszPath, size_t cbBaseLen)
{
    RTFSOBJINFO objInfo;
    int rc = RTPathQueryInfo(pcszPath, &objInfo, RTFSOBJATTRADD_NOTHING);
    if (RT_FAILURE(rc))
        return rc;

    /* These are the types we currently support. Symlinks are not directly
     * supported. First the guest could be an OS which doesn't support it and
     * second the symlink could point to a file which is out of the base tree.
     * Both things are hard to support. For now we just copy the target file in
     * this case. */
    if (!(   RTFS_IS_DIRECTORY(objInfo.Attr.fMode)
          || RTFS_IS_FILE(objInfo.Attr.fMode)
          || RTFS_IS_SYMLINK(objInfo.Attr.fMode)))
        return VINF_SUCCESS;

    uint64_t cbSize = 0;
    rc = RTFileQuerySize(pcszPath, &cbSize);
    if (rc == VERR_IS_A_DIRECTORY)
        rc = VINF_SUCCESS;
    if (RT_FAILURE(rc))
        return rc;
    m_uriList.append(PathEntry(pcszPath, &pcszPath[cbBaseLen], objInfo.Attr.fMode, cbSize));
    m_cbAll += cbSize;
    DO(("cbFile: %u\n", cbSize));

    PRTDIR hDir;
    /* We have to try to open even symlinks, cause they could be symlinks
     * to directories. */
    rc = RTDirOpen(&hDir, pcszPath);
    /* The following error happens when this was a symlink to an file or a
     * regular file. */
    if (rc == VERR_PATH_NOT_FOUND)
        return VINF_SUCCESS;
    if (RT_FAILURE(rc))
        return rc;

    while (RT_SUCCESS(rc))
    {
        RTDIRENTRY DirEntry;
        rc = RTDirRead(hDir, &DirEntry, NULL);
        if (RT_FAILURE(rc))
        {
            if (rc == VERR_NO_MORE_FILES)
                rc = VINF_SUCCESS;
            break;
        }
        switch (DirEntry.enmType)
        {
            case RTDIRENTRYTYPE_DIRECTORY:
            {
                /* Skip "." and ".." entries. */
                if (   RTStrCmp(DirEntry.szName, ".")  == 0
                    || RTStrCmp(DirEntry.szName, "..") == 0)
                    break;
                if (char *pszRecDir = RTStrAPrintf2("%s%c%s", pcszPath, RTPATH_DELIMITER, DirEntry.szName))
                {
                    rc = buildFileTree(pszRecDir, cbBaseLen);
                    RTStrFree(pszRecDir);
                }
                else
                    rc = VERR_NO_MEMORY;
                break;
            }
            case RTDIRENTRYTYPE_SYMLINK:
            case RTDIRENTRYTYPE_FILE:
            {
                if (char *pszNewFile = RTStrAPrintf2("%s%c%s", pcszPath, RTPATH_DELIMITER, DirEntry.szName))
                {
                    /* We need the size and the mode of the file. */
                    RTFSOBJINFO objInfo1;
                    rc = RTPathQueryInfo(pszNewFile, &objInfo1, RTFSOBJATTRADD_NOTHING);
                    if (RT_FAILURE(rc))
                        return rc;
                    rc = RTFileQuerySize(pszNewFile, &cbSize);
                    if (RT_FAILURE(rc))
                        break;
                    m_uriList.append(PathEntry(pszNewFile, &pszNewFile[cbBaseLen], objInfo1.Attr.fMode, cbSize));
                    m_cbAll += cbSize;
                    RTStrFree(pszNewFile);
                }
                else
                    rc = VERR_NO_MEMORY;
                break;
            }
            default: break;
        }
    }
    RTDirClose(hDir);

    return rc;
}
示例#27
0
/**
 * Basic API checks.
 * We'll return if any of these fails.
 */
static void tst1(void)
{
    RTTestISub("Basics");
    char *psz;
    int rc = VINF_SUCCESS;

    /* RTStrAlloc */
    RTTESTI_CHECK(psz = RTStrAlloc(0));
    RTTESTI_CHECK(psz && !*psz);
    RTStrFree(psz);

    RTTESTI_CHECK(psz = RTStrAlloc(1));
    RTTESTI_CHECK(psz && !*psz);
    RTStrFree(psz);

    RTTESTI_CHECK(psz = RTStrAlloc(128));
    RTTESTI_CHECK(psz && !*psz);
    RTStrFree(psz);

    /* RTStrAllocEx */
    psz = (char*)"asdfasdf";
    RTTESTI_CHECK_RC(RTStrAllocEx(&psz, 0), VINF_SUCCESS);
    RTTESTI_CHECK(psz && !*psz);
    RTStrFree(psz);

    RTTESTI_CHECK_RC(RTStrAllocEx(&psz, 1), VINF_SUCCESS);
    RTTESTI_CHECK(psz && !*psz);
    RTStrFree(psz);

    RTTESTI_CHECK_RC(RTStrAllocEx(&psz, 128), VINF_SUCCESS);
    RTTESTI_CHECK(psz && !*psz);
    RTStrFree(psz);

    /* RTStrRealloc */
    psz = NULL;
    RTTESTI_CHECK_RC(RTStrRealloc(&psz, 10), VINF_SUCCESS);
    RTTESTI_CHECK(psz && !psz[0]);
    RTTESTI_CHECK(psz && !psz[9]);
    RTStrFree(psz);

    psz = NULL;
    RTTESTI_CHECK_RC(RTStrRealloc(&psz, 0), VINF_SUCCESS);
    RTTESTI_CHECK(!psz);

    psz = NULL;
    RTTESTI_CHECK_RC(RTStrRealloc(&psz, 128), VINF_SUCCESS);
    RTTESTI_CHECK(psz && !psz[0]);
    RTTESTI_CHECK(psz && !psz[127]);
    if (psz)
    {
        memset(psz, 'a', 127);
        RTTESTI_CHECK_RC(rc = RTStrRealloc(&psz, 160), VINF_SUCCESS);
        if (RT_SUCCESS(rc) && psz)
        {
            RTTESTI_CHECK(!psz[127]);
            RTTESTI_CHECK(!psz[159]);
            RTTESTI_CHECK(ASMMemIsAll8(psz, 127, 'a') == NULL);
            memset(psz, 'b', 159);

            RTTESTI_CHECK_RC(rc = RTStrRealloc(&psz, 79), VINF_SUCCESS);
            if (RT_SUCCESS(rc))
            {
                RTTESTI_CHECK(!psz[78]);
                RTTESTI_CHECK(ASMMemIsAll8(psz, 78, 'b') == NULL);

                RTTESTI_CHECK_RC(rc = RTStrRealloc(&psz, 0), VINF_SUCCESS);
                RTTESTI_CHECK(!psz);
            }
        }
    }
    RTStrFree(psz);

    /* RTStrDup */
    RTTESTI_CHECK(psz = RTStrDup(""));
    RTTESTI_CHECK(psz && *psz == '\0');
    RTStrFree(psz);

    RTTESTI_CHECK(psz = RTStrDup("abcdefghijklmnop"));
    RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnop"));
    RTStrFree(psz);

    /* RTStrDupEx */
    psz = NULL;
    RTTESTI_CHECK_RC(RTStrDupEx(&psz, ""), VINF_SUCCESS);
    RTTESTI_CHECK(RT_FAILURE(rc) || *psz == '\0');
    if (RT_SUCCESS(rc))
        RTStrFree(psz);

    psz = (char*)"asdfasdfasdfasdf";
    RTTESTI_CHECK_RC(rc = RTStrDupEx(&psz, "abcdefghijklmnop"), VINF_SUCCESS);
    RTTESTI_CHECK(RT_FAILURE(rc) || !RTStrCmp(psz, "abcdefghijklmnop"));
    if (RT_SUCCESS(rc))
        RTStrFree(psz);

    /* RTStrDupN */
    RTTESTI_CHECK(psz = RTStrDupN("abcdefg", 3));
    RTTESTI_CHECK(!RTStrCmp(psz, "abc"));
    RTStrFree(psz);

    RTTESTI_CHECK(psz = RTStrDupN("abc", 100000));
    RTTESTI_CHECK(!RTStrCmp(psz, "abc"));
    RTStrFree(psz);

    RTTESTI_CHECK(psz = RTStrDupN("abc", 0));
    RTTESTI_CHECK(psz && *psz == '\0');
    RTStrFree(psz);

    /* RTStrAAppend */
    RTTESTI_CHECK(psz = RTStrDup("abc"));
    RTTESTI_CHECK_RC(RTStrAAppend(&psz, "def"), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abcdef"));
    RTStrFree(psz);

    RTTESTI_CHECK(psz = RTStrDup("abc"));
    RTTESTI_CHECK_RC(RTStrAAppend(&psz, ""), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abc"));
    RTTESTI_CHECK_RC(RTStrAAppend(&psz, NULL), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abc"));
    RTStrFree(psz);

    psz = NULL;
    RTTESTI_CHECK_RC(RTStrAAppend(&psz, "xyz"), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "xyz"));
    RTStrFree(psz);

    /* RTStrAAppendN */
    RTTESTI_CHECK(psz = RTStrDup("abc"));
    RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "def", 1), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abcd"));
    RTStrFree(psz);

    RTTESTI_CHECK(psz = RTStrDup("abc"));
    RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "", 0), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abc"));
    RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "", RTSTR_MAX), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abc"));
    RTTESTI_CHECK_RC(RTStrAAppendN(&psz, NULL, 0), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abc"));
    RTStrFree(psz);

    psz = NULL;
    RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "abc", 2), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "ab"));
    RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "cdefghijklm", 1), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abc"));
    RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "defghijklm", RTSTR_MAX), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklm"));
    RTStrFree(psz);

    /* RTStrAAppendExN / RTStrAAppendExNV */
    psz = NULL;
    RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 5, "a", (size_t)1, "bc", (size_t)1, "cdefg", RTSTR_MAX, "hijkl", (size_t)2, "jklmnopqrstuvwxyz", RTSTR_MAX), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz"));
    RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 0), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz"));
    RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 2, NULL, (size_t)0, "", (size_t)0), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz"));
    RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 1, "-", (size_t)1), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz-"));
    RTStrFree(psz);

    /* RTStrATruncate */
    psz = NULL;
    RTTESTI_CHECK_RC(RTStrATruncate(&psz, 0), VINF_SUCCESS);
    RTTESTI_CHECK(!psz);

    RTTESTI_CHECK(psz = RTStrDup(""));
    RTTESTI_CHECK_RC(RTStrATruncate(&psz, 0), VINF_SUCCESS);
    RTStrFree(psz);

    RTTESTI_CHECK(psz = RTStrDup("1234567890"));
    RTTESTI_CHECK_RC(RTStrATruncate(&psz, 5), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "12345"));
    RTStrFree(psz);

    psz = NULL;
    for (uint32_t i = 0; i < 128; i++)
        RTTESTI_CHECK_RC_RETV(RTStrAAppend(&psz, "abcdefghijklmnopqrstuvwxyz"), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTStrATruncate(&psz, sizeof("abcdefghijklmnopqrstuvwxyz") - 1), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz"));
    RTTESTI_CHECK_RC(RTStrATruncate(&psz, 6), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "abcdef"));
    RTTESTI_CHECK_RC(RTStrATruncate(&psz, 1), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, "a"));
    RTTESTI_CHECK_RC(RTStrATruncate(&psz, 0), VINF_SUCCESS);
    RTTESTI_CHECK(!RTStrCmp(psz, ""));
    RTStrFree(psz);

}
示例#28
0
/**
 * @callback_method_impl{FNDBGCCMD, The '.injectdelay' command.}
 */
static DECLCALLBACK(int) pdmacEpFileDelayInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR pArgs, unsigned cArgs)
{
    /*
     * Validate input.
     */
    DBGC_CMDHLP_REQ_UVM_RET(pCmdHlp, pCmd, pUVM);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs >= 3);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, pArgs[0].enmType == DBGCVAR_TYPE_STRING);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pArgs[1].enmType == DBGCVAR_TYPE_STRING);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 2, pArgs[2].enmType == DBGCVAR_TYPE_NUMBER);

    PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile;
    pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE];

    /* Syntax is "read|write|flush|any <filename> <delay> [reqs]" */
    PDMACFILEREQTYPEDELAY enmDelayType = PDMACFILEREQTYPEDELAY_ANY;
    if (!RTStrCmp(pArgs[0].u.pszString, "read"))
        enmDelayType = PDMACFILEREQTYPEDELAY_READ;
    else if (!RTStrCmp(pArgs[0].u.pszString, "write"))
        enmDelayType = PDMACFILEREQTYPEDELAY_WRITE;
    else if (!RTStrCmp(pArgs[0].u.pszString, "flush"))
        enmDelayType = PDMACFILEREQTYPEDELAY_FLUSH;
    else if (!RTStrCmp(pArgs[0].u.pszString, "any"))
        enmDelayType = PDMACFILEREQTYPEDELAY_ANY;
    else
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "invalid transfer direction '%s'", pArgs[0].u.pszString);

    uint32_t msDelay = (uint32_t)pArgs[2].u.u64Number;
    if ((uint64_t)msDelay != pArgs[2].u.u64Number)
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "The delay '%lld' is out of range", pArgs[0].u.u64Number);

    uint32_t cReqsDelay = 1;
    uint32_t msJitter = 0;
    if (cArgs >= 4)
        msJitter = (uint32_t)pArgs[3].u.u64Number;
    if (cArgs == 5)
        cReqsDelay = (uint32_t)pArgs[4].u.u64Number;

    /*
     * Search for the matching endpoint.
     */
    RTCritSectEnter(&pEpClassFile->Core.CritSect);

    PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
    while (pEpFile)
    {
        if (!RTStrCmp(pArgs[1].u.pszString, RTPathFilename(pEpFile->Core.pszUri)))
            break;
        pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext;
    }

    if (pEpFile)
    {
        ASMAtomicWriteSize(&pEpFile->enmTypeDelay, enmDelayType);
        ASMAtomicWriteU32(&pEpFile->msDelay, msDelay);
        ASMAtomicWriteU32(&pEpFile->msJitter, msJitter);
        ASMAtomicWriteU32(&pEpFile->cReqsDelay, cReqsDelay);

        DBGCCmdHlpPrintf(pCmdHlp, "Injected delay for the next %u requests of %u ms into '%s' for %s\n",
                         cReqsDelay, msDelay, pArgs[1].u.pszString, pArgs[0].u.pszString);
    }

    RTCritSectLeave(&pEpClassFile->Core.CritSect);

    if (!pEpFile)
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "No file with name '%s' found", pArgs[1].u.pszString);
    return VINF_SUCCESS;
}
RTR3DECL(bool) RTProcIsRunningByName(const char *pszName)
{
    /*
     * Quick validation.
     */
    if (!pszName)
        return false;

    bool const fWithPath = RTPathHavePath(pszName);

    /*
     * Enumerate /proc.
     */
    RTDIR hDir;
    int rc = RTDirOpen(&hDir, "/proc");
    AssertMsgRCReturn(rc, ("RTDirOpen on /proc failed: rc=%Rrc\n", rc), false);
    if (RT_SUCCESS(rc))
    {
        RTDIRENTRY DirEntry;
        while (RT_SUCCESS(RTDirRead(hDir, &DirEntry, NULL)))
        {
            /*
             * Filter numeric directory entries only.
             */
            if (   (   DirEntry.enmType == RTDIRENTRYTYPE_DIRECTORY
                    || DirEntry.enmType == RTDIRENTRYTYPE_UNKNOWN)
                && RTStrToUInt32(DirEntry.szName) > 0)
            {
                /*
                 * Try readlink on exe first since it's more faster and reliable.
                 * Fall back on reading the first line in cmdline if that fails
                 * (access errors typically). cmdline is unreliable as it might
                 * contain whatever the execv caller passes as argv[0].
                 */
                char szName[RTPATH_MAX];
                RTStrPrintf(szName, sizeof(szName), "/proc/%s/exe", &DirEntry.szName[0]);
                char szExe[RTPATH_MAX];
                int cchLink = readlink(szName, szExe, sizeof(szExe) - 1);
                if (    cchLink > 0
                    &&  (size_t)cchLink < sizeof(szExe))
                {
                    szExe[cchLink] = '\0';
                    rc = VINF_SUCCESS;
                }
                else
                {
                    RTStrPrintf(szName, sizeof(szName), "/proc/%s/cmdline", &DirEntry.szName[0]);
                    PRTSTREAM pStream;
                    rc = RTStrmOpen(szName, "r", &pStream);
                    if (RT_SUCCESS(rc))
                    {
                        rc = RTStrmGetLine(pStream, szExe, sizeof(szExe));
                        RTStrmClose(pStream);
                    }
                }
                if (RT_SUCCESS(rc))
                {
                    /*
                     * We are interested on the file name part only.
                     */
                    char const *pszProcName = fWithPath ? szExe : RTPathFilename(szExe);
                    if (RTStrCmp(pszProcName, pszName) == 0)
                    {
                        /* Found it! */
                        RTDirClose(hDir);
                        return true;
                    }
                }
            }
        }
        RTDirClose(hDir);
    }

    return false;
}
示例#30
0
/**
 * Value string -> Value union.
 *
 * @returns IPRT status code.
 * @param   fFlags              The value flags.
 * @param   pszValue            The value string.
 * @param   pValueUnion         Where to return the processed value.
 */
static int rtGetOptProcessValue(uint32_t fFlags, const char *pszValue, PRTGETOPTUNION pValueUnion)
{
    /*
     * Transform into a option value as requested.
     * If decimal conversion fails, we'll check for "0x<xdigit>" and
     * try a 16 based conversion. We will not interpret any of the
     * generic ints as octals.
     */
    switch (fFlags & (  RTGETOPT_REQ_MASK
                      | RTGETOPT_FLAG_HEX
                      | RTGETOPT_FLAG_DEC
                      | RTGETOPT_FLAG_OCT))
    {
        case RTGETOPT_REQ_STRING:
            pValueUnion->psz = pszValue;
            break;

        case RTGETOPT_REQ_BOOL:
            if (   !RTStrICmp(pszValue, "true")
                || !RTStrICmp(pszValue, "t")
                || !RTStrICmp(pszValue, "yes")
                || !RTStrICmp(pszValue, "y")
                || !RTStrICmp(pszValue, "enabled")
                || !RTStrICmp(pszValue, "enable")
                || !RTStrICmp(pszValue, "en")
                || !RTStrICmp(pszValue, "e")
                || !RTStrICmp(pszValue, "on")
                || !RTStrCmp(pszValue, "1")
                )
                pValueUnion->f = true;
            else if (   !RTStrICmp(pszValue, "false")
                     || !RTStrICmp(pszValue, "f")
                     || !RTStrICmp(pszValue, "no")
                     || !RTStrICmp(pszValue, "n")
                     || !RTStrICmp(pszValue, "disabled")
                     || !RTStrICmp(pszValue, "disable")
                     || !RTStrICmp(pszValue, "dis")
                     || !RTStrICmp(pszValue, "d")
                     || !RTStrICmp(pszValue, "off")
                     || !RTStrCmp(pszValue, "0")
                     )
                pValueUnion->f = false;
            else
            {
                pValueUnion->psz = pszValue;
                return VERR_GETOPT_UNKNOWN_OPTION;
            }
            break;

        case RTGETOPT_REQ_BOOL_ONOFF:
            if (!RTStrICmp(pszValue, "on"))
                pValueUnion->f = true;
            else if (!RTStrICmp(pszValue, "off"))
                pValueUnion->f = false;
            else
            {
                pValueUnion->psz = pszValue;
                return VERR_GETOPT_UNKNOWN_OPTION;
            }
            break;

#define MY_INT_CASE(req, type, memb, convfn) \
            case req: \
            { \
                type Value; \
                if (    convfn(pszValue, 10, &Value) != VINF_SUCCESS \
                    &&  (   pszValue[0] != '0' \
                         || (pszValue[1] != 'x' && pszValue[1] != 'X') \
                         || !RT_C_IS_XDIGIT(pszValue[2]) \
                         || convfn(pszValue, 16, &Value) != VINF_SUCCESS ) ) \
                    return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
                pValueUnion->memb = Value; \
                break; \
            }
#define MY_BASE_INT_CASE(req, type, memb, convfn, base) \
            case req: \
            { \
                type Value; \
                if (convfn(pszValue, base, &Value) != VINF_SUCCESS) \
                    return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
                pValueUnion->memb = Value; \
                break; \
            }

        MY_INT_CASE(RTGETOPT_REQ_INT8,   int8_t,   i8,  RTStrToInt8Full)
        MY_INT_CASE(RTGETOPT_REQ_INT16,  int16_t,  i16, RTStrToInt16Full)
        MY_INT_CASE(RTGETOPT_REQ_INT32,  int32_t,  i32, RTStrToInt32Full)
        MY_INT_CASE(RTGETOPT_REQ_INT64,  int64_t,  i64, RTStrToInt64Full)
        MY_INT_CASE(RTGETOPT_REQ_UINT8,  uint8_t,  u8,  RTStrToUInt8Full)
        MY_INT_CASE(RTGETOPT_REQ_UINT16, uint16_t, u16, RTStrToUInt16Full)
        MY_INT_CASE(RTGETOPT_REQ_UINT32, uint32_t, u32, RTStrToUInt32Full)
        MY_INT_CASE(RTGETOPT_REQ_UINT64, uint64_t, u64, RTStrToUInt64Full)

        MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_HEX, int8_t,   i8,  RTStrToInt8Full,   16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_HEX, int16_t,  i16, RTStrToInt16Full,  16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_HEX, int32_t,  i32, RTStrToInt32Full,  16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_HEX, int64_t,  i64, RTStrToInt64Full,  16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_HEX, uint8_t,  u8,  RTStrToUInt8Full,  16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_HEX, uint16_t, u16, RTStrToUInt16Full, 16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX, uint32_t, u32, RTStrToUInt32Full, 16)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX, uint64_t, u64, RTStrToUInt64Full, 16)

        MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_DEC, int8_t,   i8,  RTStrToInt8Full,   10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_DEC, int16_t,  i16, RTStrToInt16Full,  10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_DEC, int32_t,  i32, RTStrToInt32Full,  10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_DEC, int64_t,  i64, RTStrToInt64Full,  10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_DEC, uint8_t,  u8,  RTStrToUInt8Full,  10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_DEC, uint16_t, u16, RTStrToUInt16Full, 10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_DEC, uint32_t, u32, RTStrToUInt32Full, 10)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_DEC, uint64_t, u64, RTStrToUInt64Full, 10)

        MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_OCT, int8_t,   i8,  RTStrToInt8Full,   8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_OCT, int16_t,  i16, RTStrToInt16Full,  8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_OCT, int32_t,  i32, RTStrToInt32Full,  8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_OCT, int64_t,  i64, RTStrToInt64Full,  8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_OCT, uint8_t,  u8,  RTStrToUInt8Full,  8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_OCT, uint16_t, u16, RTStrToUInt16Full, 8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT, uint32_t, u32, RTStrToUInt32Full, 8)
        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_OCT, uint64_t, u64, RTStrToUInt64Full, 8)

#undef MY_INT_CASE
#undef MY_BASE_INT_CASE

        case RTGETOPT_REQ_IPV4ADDR:
        {
            RTNETADDRIPV4 Addr;
            if (rtgetoptConvertIPv4Addr(pszValue, &Addr) != VINF_SUCCESS)
                return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
            pValueUnion->IPv4Addr = Addr;
            break;
        }

        case RTGETOPT_REQ_IPV4CIDR:
        {
            RTNETADDRIPV4 network;
            RTNETADDRIPV4 netmask;
            if (RT_FAILURE(RTCidrStrToIPv4(pszValue, &network, &netmask)))
              return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
            pValueUnion->CidrIPv4.IPv4Network.u = network.u;
            pValueUnion->CidrIPv4.IPv4Netmask.u = netmask.u;
            break;
        }

        case RTGETOPT_REQ_MACADDR:
        {
            RTMAC Addr;
            if (rtgetoptConvertMacAddr(pszValue, &Addr) != VINF_SUCCESS)
                return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
            pValueUnion->MacAddr = Addr;
            break;
        }

        case RTGETOPT_REQ_UUID:
        {
            RTUUID Uuid;
            if (RTUuidFromStr(&Uuid, pszValue) != VINF_SUCCESS)
                return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
            pValueUnion->Uuid = Uuid;
            break;
        }

        default:
            AssertMsgFailed(("f=%#x\n", fFlags));
            return VERR_INTERNAL_ERROR;
    }

    return VINF_SUCCESS;
}