Exemple #1
0
static void *copy_info(const char *name, const LPWIN32_FIND_DATAA data)
{
    time_t ctime = file_time_to_unix(&data->ftCreationTime);
    time_t mtime = file_time_to_unix(&data->ftLastWriteTime);

    return FS_CopyInfo(name, data->nFileSizeLow, ctime, mtime);
}
Exemple #2
0
/*
=================
Sys_ListFiles_r

Internal function to filesystem. Conventions apply:
    - files should hold at least MAX_LISTED_FILES
    - *count_p must be initialized in range [0, MAX_LISTED_FILES - 1]
    - depth must be 0 on the first call
=================
*/
void Sys_ListFiles_r(const char  *path,
                     const char  *filter,
                     unsigned    flags,
                     size_t      baselen,
                     int         *count_p,
                     void        **files,
                     int         depth)
{
    struct dirent *ent;
    DIR *dir;
    struct stat st;
    char fullpath[MAX_OSPATH];
    char *name;
    size_t len;
    void *info;

    if ((dir = opendir(path)) == NULL) {
        return;
    }

    while ((ent = readdir(dir)) != NULL) {
        if (ent->d_name[0] == '.') {
            continue; // ignore dotfiles
        }

        len = Q_concat(fullpath, sizeof(fullpath),
                       path, "/", ent->d_name, NULL);
        if (len >= sizeof(fullpath)) {
            continue;
        }

        st.st_mode = 0;

#ifdef _DIRENT_HAVE_D_TYPE
        // try to avoid stat() if possible
        if (!(flags & FS_SEARCH_EXTRAINFO)
            && ent->d_type != DT_UNKNOWN
            && ent->d_type != DT_LNK) {
            st.st_mode = DTTOIF(ent->d_type);
        }
#endif

        if (st.st_mode == 0 && stat(fullpath, &st) == -1) {
            continue;
        }

        // pattern search implies recursive search
        if ((flags & FS_SEARCH_BYFILTER) &&
            S_ISDIR(st.st_mode) && depth < MAX_LISTED_DEPTH) {
            Sys_ListFiles_r(fullpath, filter, flags, baselen,
                            count_p, files, depth + 1);

            // re-check count
            if (*count_p >= MAX_LISTED_FILES) {
                break;
            }
        }

        // check type
        if (flags & FS_SEARCH_DIRSONLY) {
            if (!S_ISDIR(st.st_mode)) {
                continue;
            }
        } else {
            if (!S_ISREG(st.st_mode)) {
                continue;
            }
        }

        // check filter
        if (filter) {
            if (flags & FS_SEARCH_BYFILTER) {
                if (!FS_WildCmp(filter, fullpath + baselen)) {
                    continue;
                }
            } else {
                if (!FS_ExtCmp(filter, ent->d_name)) {
                    continue;
                }
            }
        }

        // strip path
        if (flags & FS_SEARCH_SAVEPATH) {
            name = fullpath + baselen;
        } else {
            name = ent->d_name;
        }

        // strip extension
        if (flags & FS_SEARCH_STRIPEXT) {
            *COM_FileExtension(name) = 0;

            if (!*name) {
                continue;
            }
        }

        // copy info off
        if (flags & FS_SEARCH_EXTRAINFO) {
            info = FS_CopyInfo(name,
                               st.st_size,
                               st.st_ctime,
                               st.st_mtime);
        } else {
            info = FS_CopyString(name);
        }

        files[(*count_p)++] = info;

        if (*count_p >= MAX_LISTED_FILES) {
            break;
        }
    }

    closedir(dir);
}