/** * @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; }
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; }
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; }
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)); } }
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; }
/** 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; }
/** * 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; }
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; }
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; }
/** * 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; }
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; }
/** * 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; }
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; }
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; }
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; }
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; }
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; }
/** * 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); }
/** * @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; }
/** * 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; }