/* static */
int getDriveInfoFromSysfs(DriveInfoList *pList, bool isDVD, bool *pfSuccess)
{
    AssertPtrReturn(pList, VERR_INVALID_POINTER);
    AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); /* Valid or Null */
    LogFlowFunc (("pList=%p, isDVD=%u, pfSuccess=%p\n",
                  pList, (unsigned) isDVD, pfSuccess));
    RTDIR hDir;
    int rc;
    bool fSuccess = false;
    unsigned cFound = 0;

    if (!RTPathExists("/sys"))
        return VINF_SUCCESS;
    rc = RTDirOpen(&hDir, "/sys/block");
    /* This might mean that sysfs semantics have changed */
    AssertReturn(rc != VERR_FILE_NOT_FOUND, VINF_SUCCESS);
    fSuccess = true;
    if (RT_SUCCESS(rc))
    {
        for (;;)
        {
            RTDIRENTRY entry;
            rc = RTDirRead(hDir, &entry, NULL);
            Assert(rc != VERR_BUFFER_OVERFLOW);  /* Should never happen... */
            if (RT_FAILURE(rc))  /* Including overflow and no more files */
                break;
            if (entry.szName[0] == '.')
                continue;
            sysfsBlockDev dev(entry.szName, isDVD);
            /* This might mean that sysfs semantics have changed */
            AssertBreakStmt(dev.isConsistent(), fSuccess = false);
            if (!dev.isValid())
                continue;
            try
            {
                pList->push_back(DriveInfo(dev.getNode(), dev.getUdi(), dev.getDesc()));
            }
            catch(std::bad_alloc &e)
            {
                rc = VERR_NO_MEMORY;
                break;
            }
            ++cFound;
        }
        RTDirClose(hDir);
    }
    if (rc == VERR_NO_MORE_FILES)
        rc = VINF_SUCCESS;
    if (RT_FAILURE(rc))
        /* Clean up again */
        for (unsigned i = 0; i < cFound; ++i)
            pList->pop_back();
    if (pfSuccess)
        *pfSuccess = fSuccess;
    LogFlow (("rc=%Rrc, fSuccess=%u\n", rc, (unsigned) fSuccess));
    return rc;
}
Exemplo n.º 2
0
static int tstDirOpenFiltered(const char *pszFilter, unsigned *pcFilesMatch, int *pRc)
{
    int rcRet = 0;
    unsigned cFilesMatch = 0;
    PRTDIR pDir;
    int rc = RTDirOpenFiltered(&pDir, pszFilter, RTDIRFILTER_WINNT, 0);
    if (RT_SUCCESS(rc))
    {
        for (;;)
        {
            RTDIRENTRY DirEntry;
            rc = RTDirRead(pDir, &DirEntry, NULL);
            if (RT_FAILURE(rc))
                break;
            cFilesMatch++;
        }

        if (rc != VERR_NO_MORE_FILES)
        {
            RTPrintf("tstDir-3: Enumeration '%s' failed! rc=%Rrc\n", pszFilter, rc);
            rcRet = 1;
        }

        /* close up */
        rc = RTDirClose(pDir);
        if (RT_FAILURE(rc))
        {
            RTPrintf("tstDir-3: Failed to close dir '%s'! rc=%Rrc\n", pszFilter, rc);
            rcRet = 1;
        }
    }
    else
    {
        RTPrintf("tstDir-3: Failed to open '%s', rc=%Rrc\n", pszFilter, rc);
        rcRet = 1;
    }

    *pcFilesMatch = cFilesMatch;
    *pRc = rc;
    return rcRet;
}
Exemplo n.º 3
0
int main(int argc, char **argv)
{
    int rcRet = 0;
    RTR3InitExe(argc, &argv, 0);

    /*
     * Iterate arguments.
     */
    bool fLong = false;
    bool fShortName = false;
    for (int i = 1; i < argc; i++)
    {
        if (argv[i][0] == '-')
        {
            for (int j = 1; argv[i][j]; j++)
            {
                switch (argv[i][j])
                {
                    case 'l':
                        fLong = true;
                        break;
                    case 's':
                        fShortName = true;
                        break;
                    default:
                        RTPrintf("Unknown option '%c' ignored!\n", argv[i][j]);
                        break;
                }
            }
        }
        else
        {
            /* open */
            PRTDIR pDir;
            int rc = RTDirOpen(&pDir, argv[i]);
            if (RT_SUCCESS(rc))
            {
                /* list */
                if (!fLong)
                {
                    for (;;)
                    {
                        RTDIRENTRY DirEntry;
                        rc = RTDirRead(pDir, &DirEntry, NULL);
                        if (RT_FAILURE(rc))
                            break;
                        switch (DirEntry.enmType)
                        {
                            case RTDIRENTRYTYPE_UNKNOWN:     RTPrintf("u"); break;
                            case RTDIRENTRYTYPE_FIFO:        RTPrintf("f"); break;
                            case RTDIRENTRYTYPE_DEV_CHAR:    RTPrintf("c"); break;
                            case RTDIRENTRYTYPE_DIRECTORY:   RTPrintf("d"); break;
                            case RTDIRENTRYTYPE_DEV_BLOCK:   RTPrintf("b"); break;
                            case RTDIRENTRYTYPE_FILE:        RTPrintf("-"); break;
                            case RTDIRENTRYTYPE_SYMLINK:     RTPrintf("l"); break;
                            case RTDIRENTRYTYPE_SOCKET:      RTPrintf("s"); break;
                            case RTDIRENTRYTYPE_WHITEOUT:    RTPrintf("w"); break;
                            default:
                                rcRet = 1;
                                RTPrintf("?");
                                break;
                        }
                        RTPrintf(" %#18llx  %3d %s\n", (uint64_t)DirEntry.INodeId,
                                 DirEntry.cbName, DirEntry.szName);
                    }
                }
                else
                {
                    for (;;)
                    {
                        RTDIRENTRYEX DirEntry;
                        rc = RTDirReadEx(pDir, &DirEntry, NULL, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
                        if (RT_FAILURE(rc))
                            break;

                        RTFMODE fMode = DirEntry.Info.Attr.fMode;
                        switch (fMode & RTFS_TYPE_MASK)
                        {
                            case RTFS_TYPE_FIFO:        RTPrintf("f"); break;
                            case RTFS_TYPE_DEV_CHAR:    RTPrintf("c"); break;
                            case RTFS_TYPE_DIRECTORY:   RTPrintf("d"); break;
                            case RTFS_TYPE_DEV_BLOCK:   RTPrintf("b"); break;
                            case RTFS_TYPE_FILE:        RTPrintf("-"); break;
                            case RTFS_TYPE_SYMLINK:     RTPrintf("l"); break;
                            case RTFS_TYPE_SOCKET:      RTPrintf("s"); break;
                            case RTFS_TYPE_WHITEOUT:    RTPrintf("w"); break;
                            default:
                                rcRet = 1;
                                RTPrintf("?");
                                break;
                        }
                        /** @todo sticy bits++ */
                        RTPrintf("%c%c%c",
                                 fMode & RTFS_UNIX_IRUSR ? 'r' : '-',
                                 fMode & RTFS_UNIX_IWUSR ? 'w' : '-',
                                 fMode & RTFS_UNIX_IXUSR ? 'x' : '-');
                        RTPrintf("%c%c%c",
                                 fMode & RTFS_UNIX_IRGRP ? 'r' : '-',
                                 fMode & RTFS_UNIX_IWGRP ? 'w' : '-',
                                 fMode & RTFS_UNIX_IXGRP ? 'x' : '-');
                        RTPrintf("%c%c%c",
                                 fMode & RTFS_UNIX_IROTH ? 'r' : '-',
                                 fMode & RTFS_UNIX_IWOTH ? 'w' : '-',
                                 fMode & RTFS_UNIX_IXOTH ? 'x' : '-');
                        RTPrintf(" %c%c%c%c%c%c%c%c%c%c%c%c%c%c",
                                 fMode & RTFS_DOS_READONLY          ? 'R' : '-',
                                 fMode & RTFS_DOS_HIDDEN            ? 'H' : '-',
                                 fMode & RTFS_DOS_SYSTEM            ? 'S' : '-',
                                 fMode & RTFS_DOS_DIRECTORY         ? 'D' : '-',
                                 fMode & RTFS_DOS_ARCHIVED          ? 'A' : '-',
                                 fMode & RTFS_DOS_NT_DEVICE         ? 'd' : '-',
                                 fMode & RTFS_DOS_NT_NORMAL         ? 'N' : '-',
                                 fMode & RTFS_DOS_NT_TEMPORARY      ? 'T' : '-',
                                 fMode & RTFS_DOS_NT_SPARSE_FILE    ? 'P' : '-',
                                 fMode & RTFS_DOS_NT_REPARSE_POINT  ? 'J' : '-',
                                 fMode & RTFS_DOS_NT_COMPRESSED     ? 'C' : '-',
                                 fMode & RTFS_DOS_NT_OFFLINE        ? 'O' : '-',
                                 fMode & RTFS_DOS_NT_NOT_CONTENT_INDEXED ? 'I' : '-',
                                 fMode & RTFS_DOS_NT_ENCRYPTED      ? 'E' : '-');
                        RTPrintf(" %d %4d %4d %10lld %10lld %#llx %#llx %#llx %#llx",
                                 DirEntry.Info.Attr.u.Unix.cHardlinks,
                                 DirEntry.Info.Attr.u.Unix.uid,
                                 DirEntry.Info.Attr.u.Unix.gid,
                                 DirEntry.Info.cbObject,
                                 DirEntry.Info.cbAllocated,
                                 DirEntry.Info.BirthTime,
                                 DirEntry.Info.ChangeTime,
                                 DirEntry.Info.ModificationTime,
                                 DirEntry.Info.AccessTime);
                        if (fShortName && DirEntry.cwcShortName)
                            RTPrintf(" %2d %ls\n", DirEntry.cwcShortName, DirEntry.wszShortName);
                        else
                            RTPrintf(" %2d %s\n", DirEntry.cbName, DirEntry.szName);
                        if (rc != VINF_SUCCESS)
                            RTPrintf("^^ %Rrc\n", rc);
                    }
                }

                if (rc != VERR_NO_MORE_FILES)
                {
                    RTPrintf("tstDir: Enumeration failed! rc=%Rrc\n", rc);
                    rcRet = 1;
                }

                /* close up */
                rc = RTDirClose(pDir);
                if (RT_FAILURE(rc))
                {
                    RTPrintf("tstDir: Failed to close dir! rc=%Rrc\n", rc);
                    rcRet = 1;
                }
            }
            else
            {
                RTPrintf("tstDir: Failed to open '%s', rc=%Rrc\n", argv[i], rc);
                rcRet = 1;
            }
        }
    }

    return rcRet;
}
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;
}
Exemplo n.º 5
0
/**
 * Recursive worker function to walk the /dev tree looking for DVD or floppy
 * devices.
 * @returns true if we have already found MAX_DEVICE_NODES devices, false
 *          otherwise
 * @param   pszPath   the path to start recursing.  The function can modify
 *                    this string at and after the terminating zero
 * @param   cchPath   the size of the buffer (not the string!) in @a pszPath
 * @param   aDevices  where to fill in information about devices that we have
 *                    found
 * @param   wantDVD   are we looking for DVD devices (or floppies)?
 */
static bool devFindDeviceRecursive(char *pszPath, size_t cchPath,
                                   deviceNodeArray aDevices, bool wantDVD)
{
    /*
     * Check assumptions made by the code below.
     */
    size_t const cchBasePath = strlen(pszPath);
    AssertReturn(cchBasePath < RTPATH_MAX - 10U, false);
    AssertReturn(pszPath[cchBasePath - 1] != '/', false);

    PRTDIR  pDir;
    if (RT_FAILURE(RTDirOpen(&pDir, pszPath)))
        return false;
    for (;;)
    {
        RTDIRENTRY Entry;
        RTFSOBJINFO ObjInfo;
        int rc = RTDirRead(pDir, &Entry, NULL);
        if (RT_FAILURE(rc))
            break;
        if (Entry.enmType == RTDIRENTRYTYPE_UNKNOWN)
        {
            if (RT_FAILURE(RTPathQueryInfo(pszPath, &ObjInfo,
                           RTFSOBJATTRADD_UNIX)))
                continue;
            if (RTFS_IS_SYMLINK(ObjInfo.Attr.fMode))
                continue;
        }

        if (Entry.enmType == RTDIRENTRYTYPE_SYMLINK)
            continue;
        pszPath[cchBasePath] = '\0';
        if (RT_FAILURE(RTPathAppend(pszPath, cchPath, Entry.szName)))
            break;

        /* Do the matching. */
        dev_t DevNode;
        char szDesc[256], szUdi[256];
        if (!devValidateDevice(pszPath, wantDVD, &DevNode, szDesc,
                               sizeof(szDesc), szUdi, sizeof(szUdi)))
            continue;
        unsigned i;
        for (i = 0; i < MAX_DEVICE_NODES; ++i)
            if (!aDevices[i].Device || (aDevices[i].Device == DevNode))
                break;
        AssertBreak(i < MAX_DEVICE_NODES);
        if (aDevices[i].Device)
            continue;
        aDevices[i].Device = DevNode;
        RTStrPrintf(aDevices[i].szPath, sizeof(aDevices[i].szPath),
                    "%s", pszPath);
        AssertCompile(sizeof(aDevices[i].szDesc) == sizeof(szDesc));
        strcpy(aDevices[i].szDesc, szDesc);
        AssertCompile(sizeof(aDevices[i].szUdi) == sizeof(szUdi));
        strcpy(aDevices[i].szUdi, szUdi);
        if (i == MAX_DEVICE_NODES - 1)
            break;
        continue;

        /* Recurse into subdirectories. */
        if (   (Entry.enmType == RTDIRENTRYTYPE_UNKNOWN)
            && !RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
            continue;
        if (Entry.enmType != RTDIRENTRYTYPE_DIRECTORY)
            continue;
        if (Entry.szName[0] == '.')
            continue;

        if (devFindDeviceRecursive(pszPath, cchPath, aDevices, wantDVD))
            break;
    }
    RTDirClose(pDir);
    return aDevices[MAX_DEVICE_NODES - 1].Device ? true : false;
}
Exemplo n.º 6
0
int main(int argc, char **argv)
{
    int rcRet = 0;
    RTR3InitExe(argc, &argv, 0);

    /*
     * Iterate arguments.
     */
    for (int i = 1; i < argc; i++)
    {
        /* open */
        PRTDIR pDir;
        int rc = RTDirOpenFiltered(&pDir, argv[i], RTDIRFILTER_WINNT, 0);
        if (RT_SUCCESS(rc))
        {
            for (;;)
            {
                RTDIRENTRY DirEntry;
                rc = RTDirRead(pDir, &DirEntry, NULL);
                if (RT_FAILURE(rc))
                    break;
                switch (DirEntry.enmType)
                {
                    case RTDIRENTRYTYPE_UNKNOWN:     RTPrintf("u"); break;
                    case RTDIRENTRYTYPE_FIFO:        RTPrintf("f"); break;
                    case RTDIRENTRYTYPE_DEV_CHAR:    RTPrintf("c"); break;
                    case RTDIRENTRYTYPE_DIRECTORY:   RTPrintf("d"); break;
                    case RTDIRENTRYTYPE_DEV_BLOCK:   RTPrintf("b"); break;
                    case RTDIRENTRYTYPE_FILE:        RTPrintf("-"); break;
                    case RTDIRENTRYTYPE_SYMLINK:     RTPrintf("l"); break;
                    case RTDIRENTRYTYPE_SOCKET:      RTPrintf("s"); break;
                    case RTDIRENTRYTYPE_WHITEOUT:    RTPrintf("w"); break;
                    default:
                        rcRet = 1;
                        RTPrintf("?");
                        break;
                }
                RTPrintf(" %#18llx  %3d %s\n", (uint64_t)DirEntry.INodeId,
                         DirEntry.cbName, DirEntry.szName);
            }

            if (rc != VERR_NO_MORE_FILES)
            {
                RTPrintf("tstDir-2: Enumeration failed! rc=%Rrc\n", rc);
                rcRet = 1;
            }

            /* close up */
            rc = RTDirClose(pDir);
            if (RT_FAILURE(rc))
            {
                RTPrintf("tstDir-2: Failed to close dir! rc=%Rrc\n", rc);
                rcRet = 1;
            }
        }
        else
        {
            RTPrintf("tstDir-2: Failed to open '%s', rc=%Rrc\n", argv[i], rc);
            rcRet = 1;
        }
    }

    return rcRet;
}
/**
 * Handles VMMDevCpuEventType_Plug.
 *
 * @param   idCpuCore       The CPU core ID.
 * @param   idCpuPackage    The CPU package ID.
 */
static void VBoxServiceCpuHotPlugHandlePlugEvent(uint32_t idCpuCore, uint32_t idCpuPackage)
{
#ifdef RT_OS_LINUX
    /*
     * The topology directory (containing the physical and core id properties)
     * is not available until the CPU is online. So we just iterate over all directories
     * and enable every CPU which is not online already.
     * Because the directory might not be available immediately we try a few times.
     *
     * @todo: Maybe use udev to monitor hot-add events from the kernel
     */
    bool fCpuOnline = false;
    unsigned cTries = 5;

    do
    {
        PRTDIR pDirDevices = NULL;
        int rc = RTDirOpen(&pDirDevices, SYSFS_CPU_PATH);
        if (RT_SUCCESS(rc))
        {
            RTDIRENTRY DirFolderContent;
            while (RT_SUCCESS(RTDirRead(pDirDevices, &DirFolderContent, NULL))) /* Assumption that szName has always enough space */
            {
                /** @todo r-bird: This code is bringing all CPUs online; the idCpuCore and
                 *        idCpuPackage parameters are unused!
                 *        aeichner: These files are not available at this point unfortunately. (see comment above)
                 *        bird: Yes, but isn't that easily dealt with by doing:
                 *              if (matching_topology() || !have_topology_directory())
                 *                  bring_cpu_online()
                 *              That could save you the cpu0 and cpuidle checks to.
                 */
                /*
                 * Check if this is a CPU object.
                 * cpu0 is excluded because it is not possible to change the state
                 * of the first CPU on Linux (it doesn't even have an online file)
                 * and cpuidle is no CPU device. Prevents error messages later.
                 */
                if(   !strncmp(DirFolderContent.szName, "cpu", 3)
                    && strncmp(DirFolderContent.szName, "cpu0", 4)
                    && strncmp(DirFolderContent.szName, "cpuidle", 7))
                {
                    /* Get the sysdev */
                    RTFILE hFileCpuOnline = NIL_RTFILE;

                    rc = RTFileOpenF(&hFileCpuOnline, RTFILE_O_WRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE,
                                     "%s/%s/online", SYSFS_CPU_PATH, DirFolderContent.szName);
                    if (RT_SUCCESS(rc))
                    {
                        /* Write a 1 to online the CPU */
                        rc = RTFileWrite(hFileCpuOnline, "1", 1, NULL);
                        RTFileClose(hFileCpuOnline);
                        if (RT_SUCCESS(rc))
                        {
                            VBoxServiceVerbose(1, "CpuHotPlug: CPU %u/%u was brought online\n", idCpuPackage, idCpuCore);
                            fCpuOnline = true;
                            break;
                        }
                        /* Error means CPU not present or online already  */
                    }
                    else
                        VBoxServiceError("CpuHotPlug: Failed to open \"%s/%s/online\" rc=%Rrc\n",
                                         SYSFS_CPU_PATH, DirFolderContent.szName, rc);
                }
            }
        }
        else
            VBoxServiceError("CpuHotPlug: Failed to open path %s rc=%Rrc\n", SYSFS_CPU_PATH, rc);

        /* Sleep a bit */
        if (!fCpuOnline)
            RTThreadSleep(10);

    } while (   !fCpuOnline
             && cTries-- > 0);
#else
# error "Port me"
#endif
}
/**
 * Returns the path of the ACPI CPU device with the given core and package ID.
 *
 * @returns VBox status code.
 * @param   ppszPath     Where to store the path.
 * @param   idCpuCore    The core ID of the CPU.
 * @param   idCpuPackage The package ID of the CPU.
 */
static int VBoxServiceCpuHotPlugGetACPIDevicePath(char **ppszPath, uint32_t idCpuCore, uint32_t idCpuPackage)
{
    int rc = VINF_SUCCESS;

    AssertPtrReturn(ppszPath, VERR_INVALID_PARAMETER);

    rc = VBoxServiceCpuHotPlugProbePath();
    if (RT_SUCCESS(rc))
    {
        /* Build the path from all components. */
        bool fFound = false;
        unsigned iLvlCurr = 0;
        char *pszPath = NULL;
        char *pszPathDir = NULL;
        PSYSFSCPUPATH pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr];

        /* Init everything. */
        Assert(pAcpiCpuPathLvl->uId != ACPI_CPU_PATH_NOT_PROBED);
        pszPath = RTPathJoinA(SYSFS_ACPI_CPU_PATH, pAcpiCpuPathLvl->aComponentsPossible[pAcpiCpuPathLvl->uId].pcszName);
        if (!pszPath)
            return VERR_NO_STR_MEMORY;

        pAcpiCpuPathLvl->pszPath = RTStrDup(SYSFS_ACPI_CPU_PATH);
        if (!pAcpiCpuPathLvl->pszPath)
        {
            RTStrFree(pszPath);
            return VERR_NO_STR_MEMORY;
        }

        /* Open the directory */
        rc = RTDirOpenFiltered(&pAcpiCpuPathLvl->pDir, pszPath, RTDIRFILTER_WINNT, 0);
        if (RT_SUCCESS(rc))
        {
            RTStrFree(pszPath);

            /* Search for CPU */
            while (!fFound)
            {
                /* Get the next directory. */
                RTDIRENTRY DirFolderContent;
                rc = RTDirRead(pAcpiCpuPathLvl->pDir, &DirFolderContent, NULL);
                if (RT_SUCCESS(rc))
                {
                    /* Create the new path. */
                    char *pszPathCurr = RTPathJoinA(pAcpiCpuPathLvl->pszPath, DirFolderContent.szName);
                    if (!pszPathCurr)
                    {
                        rc = VERR_NO_STR_MEMORY;
                        break;
                    }

                    /* If this is the last level check for the given core and package id. */
                    if (iLvlCurr == RT_ELEMENTS(g_aAcpiCpuPath) - 1)
                    {
                        /* Get the sysdev */
                        uint32_t idCore    = RTLinuxSysFsReadIntFile(10, "%s/sysdev/topology/core_id",
                                                                     pszPathCurr);
                        uint32_t idPackage = RTLinuxSysFsReadIntFile(10, "%s/sysdev/topology/physical_package_id",
                                                                     pszPathCurr);
                        if (   idCore    == idCpuCore
                            && idPackage == idCpuPackage)
                        {
                            /* Return the path */
                            pszPath = pszPathCurr;
                            fFound = true;
                            VBoxServiceVerbose(3, "CPU found\n");
                            break;
                        }
                        else
                        {
                            /* Get the next directory. */
                            RTStrFree(pszPathCurr);
                            VBoxServiceVerbose(3, "CPU doesn't match, next directory\n");
                        }
                    }
                    else
                    {
                        /* Go deeper */
                        iLvlCurr++;

                        VBoxServiceVerbose(3, "Going deeper (iLvlCurr=%u)\n", iLvlCurr);

                        pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr];

                        Assert(!pAcpiCpuPathLvl->pDir);
                        Assert(!pAcpiCpuPathLvl->pszPath);
                        pAcpiCpuPathLvl->pszPath = pszPathCurr;
                        PCSYSFSCPUPATHCOMP pPathComponent = &pAcpiCpuPathLvl->aComponentsPossible[pAcpiCpuPathLvl->uId];

                        Assert(pAcpiCpuPathLvl->uId != ACPI_CPU_PATH_NOT_PROBED);

                        pszPathDir = RTPathJoinA(pszPathCurr, pPathComponent->pcszName);
                        if (!pszPathDir)
                        {
                            rc = VERR_NO_STR_MEMORY;
                            break;
                        }

                        VBoxServiceVerbose(3, "New path %s\n", pszPathDir);

                        /* Open the directory */
                        rc = RTDirOpenFiltered(&pAcpiCpuPathLvl->pDir, pszPathDir, RTDIRFILTER_WINNT, 0);
                        if (RT_FAILURE(rc))
                            break;
                    }
                }
                else
                {
                    /* Go back one level and try to get the next entry. */
                    Assert(iLvlCurr > 0);

                    RTDirClose(pAcpiCpuPathLvl->pDir);
                    RTStrFree(pAcpiCpuPathLvl->pszPath);
                    pAcpiCpuPathLvl->pDir = NULL;
                    pAcpiCpuPathLvl->pszPath = NULL;

                    iLvlCurr--;
                    pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr];
                    VBoxServiceVerbose(3, "Directory not found, going back (iLvlCurr=%u)\n", iLvlCurr);
                }
            } /* while not found */
        } /* Successful init */

        /* Cleanup */
        for (unsigned i = 0; i < RT_ELEMENTS(g_aAcpiCpuPath); i++)
        {
            if (g_aAcpiCpuPath[i].pDir)
                RTDirClose(g_aAcpiCpuPath[i].pDir);
            if (g_aAcpiCpuPath[i].pszPath)
                RTStrFree(g_aAcpiCpuPath[i].pszPath);
            g_aAcpiCpuPath[i].pDir = NULL;
            g_aAcpiCpuPath[i].pszPath = NULL;
        }
        if (pszPathDir)
            RTStrFree(pszPathDir);
        if (RT_FAILURE(rc) && pszPath)
            RTStrFree(pszPath);

        if (RT_SUCCESS(rc))
            *ppszPath = pszPath;
    }

    return rc;
}
/**
 * Probes for the correct path to the ACPI CPU object in sysfs for the
 * various different kernel versions and distro's.
 *
 * @returns VBox status code.
 */
static int VBoxServiceCpuHotPlugProbePath(void)
{
    int rc = VINF_SUCCESS;

    /* Probe for the correct path if we didn't already. */
    if (RT_UNLIKELY(g_aAcpiCpuPath[0].uId == ACPI_CPU_PATH_NOT_PROBED))
    {
        char *pszPath = NULL;   /** < Current path, increasing while we dig deeper. */

        pszPath = RTStrDup(SYSFS_ACPI_CPU_PATH);
        if (!pszPath)
            return VERR_NO_MEMORY;

        /*
         * Simple algorithm to find the path.
         * Performance is not a real problem because it is
         * only executed once.
         */
        for (unsigned iLvlCurr = 0; iLvlCurr < RT_ELEMENTS(g_aAcpiCpuPath); iLvlCurr++)
        {
            PSYSFSCPUPATH pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr];

            for (unsigned iCompCurr = 0; iCompCurr < pAcpiCpuPathLvl->cComponents; iCompCurr++)
            {
                PCSYSFSCPUPATHCOMP pPathComponent = &pAcpiCpuPathLvl->aComponentsPossible[iCompCurr];

                /* Open the directory */
                PRTDIR pDirCurr = NULL;
                char *pszPathTmp = RTPathJoinA(pszPath, pPathComponent->pcszName);
                if (pszPathTmp)
                {
                    rc = RTDirOpenFiltered(&pDirCurr, pszPathTmp, RTDIRFILTER_WINNT, 0);
                    RTStrFree(pszPathTmp);
                }
                else
                    rc = VERR_NO_STR_MEMORY;
                if (RT_FAILURE(rc))
                    break;

                /* Search if the current directory contains one of the possible parts. */
                size_t cchName = strlen(pPathComponent->pcszName);
                RTDIRENTRY DirFolderContent;
                bool fFound = false;

                /* Get rid of the * filter which is in the path component. */
                if (pPathComponent->fNumberedSuffix)
                    cchName--;

                while (RT_SUCCESS(RTDirRead(pDirCurr, &DirFolderContent, NULL))) /* Assumption that szName has always enough space */
                {
                    if (   DirFolderContent.cbName >= cchName
                        && !strncmp(DirFolderContent.szName, pPathComponent->pcszName, cchName))
                    {
                        /* Found, use the complete name to dig deeper. */
                        fFound = true;
                        pAcpiCpuPathLvl->uId = iCompCurr;
                        char *pszPathLvl = RTPathJoinA(pszPath, DirFolderContent.szName);
                        if (pszPathLvl)
                        {
                            RTStrFree(pszPath);
                            pszPath = pszPathLvl;
                        }
                        else
                            rc = VERR_NO_STR_MEMORY;
                        break;
                    }
                }
                RTDirClose(pDirCurr);

                if (fFound)
                    break;
            } /* For every possible component. */

            /* No matching component for this part, no need to continue */
            if (RT_FAILURE(rc))
                break;
        } /* For every level */

        VBoxServiceVerbose(1, "Final path after probing %s rc=%Rrc\n", pszPath, rc);
        RTStrFree(pszPath);
    }

    return rc;
}
Exemplo n.º 10
0
/**
 * Process the testcases found in the filter.
 *
 * @param   pszFilter   The filter (winnt) to pass to RTDirOpenFiltered for
 *                      selecting the testcases.
 * @param   pszDir      The directory we're processing.
 */
static void Process(const char *pszFilter, const char *pszDir)
{
    /*
     * Open and enumerate the directory.
     */
    PRTDIR pDir;
    int rc = RTDirOpenFiltered(&pDir, pszFilter, RTDIRFILTER_WINNT, 0);
    if (RT_SUCCESS(rc))
    {
        for (;;)
        {
            RTDIRENTRY DirEntry;
            rc = RTDirRead(pDir, &DirEntry, NULL);
            if (RT_FAILURE(rc))
            {
                if (rc == VERR_NO_MORE_FILES)
                    rc = VINF_SUCCESS;
                else
                    RTPrintf("tstRunTestcases: reading '%s' -> %Rrc\n", pszFilter, rc);
                break;
            }

            /*
             * Construct the testcase name.
             */
            char *pszTestcase;
            RTStrAPrintf(&pszTestcase, "%s/%s", pszDir, DirEntry.szName);
            if (!pszTestcase)
            {
                RTPrintf("tstRunTestcases: out of memory!\n");
                rc = VERR_NO_MEMORY;
                break;
            }
            if (IsTestcaseIncluded(pszTestcase))
            {
                /*
                 * Execute the testcase.
                 */
                RTPrintf("*** %s: Executing...\n", pszTestcase);  RTStrmFlush(g_pStdOut);
                const char *papszArgs[2];
                papszArgs[0] = pszTestcase;
                papszArgs[1] = NULL;
                RTPROCESS Process;
                rc = RTProcCreate(pszTestcase, papszArgs, RTENV_DEFAULT, 0, &Process);
                if (RT_SUCCESS(rc))
                {
                    /*
                     * Wait for the process and collect it's return code.
                     * If it takes too long, we'll terminate it and continue.
                     */
                    RTTIMESPEC Start;
                    RTTimeNow(&Start);
                    RTPROCSTATUS ProcStatus;
                    for (;;)
                    {
                        rc = RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus);
                        if (rc != VERR_PROCESS_RUNNING)
                            break;
                        RTTIMESPEC Now;
                        if (RTTimeSpecGetMilli(RTTimeSpecSub(RTTimeNow(&Now), &Start)) > 120*1000 /* 1 min */)
                        {
                            RTPrintf("*** %s: FAILED - timed out. killing it.\n", pszTestcase);
                            RTProcTerminate(Process);
                            RTThreadSleep(100);
                            RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus);
                            g_cFailures++;
                            break;
                        }
                        RTThreadSleep(100);
                    }

                    /*
                     * Examin the exit status.
                     */
                    if (RT_SUCCESS(rc))
                    {
                        if (    ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
                            &&  ProcStatus.iStatus == 0)
                        {
                            RTPrintf("*** %s: PASSED\n", pszTestcase);
                            g_cPasses++;
                        }
                        else
                        {
                            RTPrintf("*** %s: FAILED\n", pszTestcase);
                            g_cFailures++;
                        }
                    }
                    else if (rc != VERR_PROCESS_RUNNING)
                    {
                        RTPrintf("tstRunTestcases: %s: RTProcWait failed -> %Rrc\n", pszTestcase, rc);
                        g_cFailures++;
                    }
                }
                else
                {
                    RTPrintf("tstRunTestcases: %s: failed to start -> %Rrc\n", pszTestcase, rc);
                    g_cFailures++;
                }

            }
            else
            {
                RTPrintf("tstRunTestcases: %s: SKIPPED\n", pszTestcase);
                g_cSkipped++;
            }
            RTStrFree(pszTestcase);
        } /* enumeration loop */

        RTDirClose(pDir);
    }
    else
        RTPrintf("tstRunTestcases: opening '%s' -> %Rrc\n", pszDir, rc);
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
0
/**
 * Recursion worker for RTDirRemoveRecursive.
 *
 * @returns IPRT status code.
 * @param   pszBuf              The path buffer.  Contains the abs path to the
 *                              directory to recurse into.  Trailing slash.
 * @param   cchDir              The length of the directory we're cursing into,
 *                              including the trailing slash.
 * @param   pDirEntry           The dir entry buffer.  (Shared to save stack.)
 * @param   pObjInfo            The object info buffer.  (ditto)
 */
static int rtDirRemoveRecursiveSub(char *pszBuf, size_t cchDir, PRTDIRENTRY pDirEntry, PRTFSOBJINFO pObjInfo)
{
    AssertReturn(RTPATH_IS_SLASH(pszBuf[cchDir - 1]), VERR_INTERNAL_ERROR_4);

    /*
     * Enumerate the directory content and dispose of it.
     */
    PRTDIR pDir;
    int rc = RTDirOpen(&pDir, pszBuf);
    if (RT_FAILURE(rc))
        return rc;
    while (RT_SUCCESS(rc = RTDirRead(pDir, pDirEntry, NULL)))
    {
        if (   pDirEntry->szName[0] != '.'
            || pDirEntry->cbName > 2
            || (   pDirEntry->cbName == 2
                && pDirEntry->szName[1] != '.')
           )
        {
            /* Construct the full name of the entry. */
            if (cchDir + pDirEntry->cbName + 1 /* dir slash */ >= RTPATH_MAX)
            {
                rc = VERR_FILENAME_TOO_LONG;
                break;
            }
            memcpy(&pszBuf[cchDir], pDirEntry->szName, pDirEntry->cbName + 1);

            /* Deal with the unknown type. */
            if (pDirEntry->enmType == RTDIRENTRYTYPE_UNKNOWN)
            {
                rc = RTPathQueryInfoEx(pszBuf, pObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
                if (RT_SUCCESS(rc) && RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode))
                    pDirEntry->enmType = RTDIRENTRYTYPE_DIRECTORY;
                else if (RT_SUCCESS(rc) && RTFS_IS_FILE(pObjInfo->Attr.fMode))
                    pDirEntry->enmType = RTDIRENTRYTYPE_FILE;
                else if (RT_SUCCESS(rc) && RTFS_IS_SYMLINK(pObjInfo->Attr.fMode))
                    pDirEntry->enmType = RTDIRENTRYTYPE_SYMLINK;
            }

            /* Try the delete the fs object. */
            switch (pDirEntry->enmType)
            {
                case RTDIRENTRYTYPE_FILE:
                    rc = RTFileDelete(pszBuf);
                    break;

                case RTDIRENTRYTYPE_DIRECTORY:
                {
                    size_t cchSubDir = cchDir + pDirEntry->cbName;
                    pszBuf[cchSubDir++] = '/';
                    pszBuf[cchSubDir]   = '\0';
                    rc = rtDirRemoveRecursiveSub(pszBuf, cchSubDir, pDirEntry, pObjInfo);
                    if (RT_SUCCESS(rc))
                    {
                        pszBuf[cchSubDir] = '\0';
                        rc = RTDirRemove(pszBuf);
                    }
                    break;
                }

                //case RTDIRENTRYTYPE_SYMLINK:
                //    rc = RTSymlinkDelete(pszBuf, 0);
                //    break;

                default:
                    /** @todo not implemented yet. */
                    rc = VINF_SUCCESS;
                    break;
            }
            if (RT_FAILURE(rc))
               break;
        }
    }
    if (rc == VERR_NO_MORE_FILES)
        rc = VINF_SUCCESS;
    RTDirClose(pDir);
    return rc;
}
Exemplo n.º 14
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;
}