(file) Return to dir.c CVS log (file) (dir) Up to [OMI] / omi / base

File: [OMI] / omi / base / Attic / dir.c (download)
Revision: 1.1.1.1 (vendor branch), Wed May 30 21:47:49 2012 UTC (12 years ago) by mike
Branch: TOG
CVS Tags: OMI_1_0_2_Branch, OMI_1_0_2, OMI_1_0_1_PRE, OMI_1_0_1, OMI_1_0_0
Changes since 1.1: +0 -0 lines
Initial Import

/*
**==============================================================================
**
** Open Management Infrastructure (OMI)
**
** Copyright (c) Microsoft Corporation
** 
** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
** use this file except in compliance with the License. You may obtain a copy 
** of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
** MERCHANTABLITY OR NON-INFRINGEMENT. 
**
** See the Apache 2 License for the specific language governing permissions 
** and limitations under the License.
**
**==============================================================================
*/

#include "dir.h"
#include "strarr.h"
#include "strings.h"
#include "paths.h"
#include <ctype.h>

#if defined(CONFIG_POSIX)
# include <sys/types.h>
# include <sys/stat.h>
# include <dirent.h>
# include <unistd.h>
#endif

#if defined(CONFIG_OS_WINDOWS)
# include <windows.h>
# include <sys/stat.h>
# include <io.h>
#endif

/*
**==============================================================================
**
** POSIC Implementation
**
**==============================================================================
*/

#if defined(CONFIG_POSIX)

struct _Dir
{
    DIR* dir;
    DirEnt ent;
};

Dir* Dir_Open(const char* path)
{
    Dir* self = (Dir*)calloc(1, sizeof(Dir));

    if (!self)
        return NULL;

    self->dir = opendir(path);
    if (!self->dir)
    {
        free(self);
        return NULL;
    }

    return self;
}

DirEnt* Dir_Read(Dir* self)
{
    struct dirent* p = readdir(self->dir);
    if (!p)
        return NULL;

    Strlcpy(self->ent.name, p->d_name, sizeof(self->ent.name));
    self->ent.type = 0;

    return &self->ent;
}

int Dir_Close(Dir* self)
{
    if (!self)
        return -1;

    if (closedir(self->dir) != 0)
    {
        free(self);
        return -1;
    }

    free(self);
    return 0;
}

#endif /* defined(CONFIG_POSIX) */

/*
**==============================================================================
**
** Windows Implementation
**
**==============================================================================
*/

#if defined(CONFIG_OS_WINDOWS)

struct _Dir
{
    intptr_t handle;
    struct _finddata_t fileinfo;
    DirEnt ent;
    int firstTime;
};

Dir* Dir_Open(const char* path)
{
    Dir* dir;
    char filespec[MAX_PATH_SIZE];
    
    /* Allocate and zero-fill struct */
    dir = (Dir*)calloc(1, sizeof(Dir));
    if (!dir)
        return NULL;

    /* Build files spec */
    {
        if (Strlcpy(filespec, path, sizeof(filespec)) >= MAX_PATH_SIZE)
            return NULL;

        if (Strlcat(filespec, "/*", sizeof(filespec)) >= MAX_PATH_SIZE)
            return NULL;
    }

    /* Find first file matching the file spec */
    dir->handle = _findfirst(filespec, &dir->fileinfo);
    if (dir->handle == -1)
    {
        free(dir);
        return NULL;
    }

    /* Note that readdir() has not been called yet */
    dir->firstTime = 1;

    return dir;
}

DirEnt* Dir_Read(Dir* dir)
{
    if (!dir->firstTime)
    {
        if (_findnext(dir->handle, &dir->fileinfo) != 0)
            return NULL;
    }

    Strlcpy(dir->ent.name, dir->fileinfo.name, MAX_PATH_SIZE);
    dir->firstTime = 0;
    return &dir->ent;
}

int Dir_Close(Dir* dir)
{
    _findclose(dir->handle);
    free(dir);
    return 0;
}

#endif /* defined(CONFIG_OS_WINDOWS) */

char** Listdir(const char* path)
{
    Dir* dir;
    char** arr;

    dir = Dir_Open(path);
    if (!dir)
        return NULL;

    arr = StrArr();
    if (!arr)
    {
        Dir_Close(dir);
        return NULL;
    }

    for (;;)
    {
        DirEnt* ent = Dir_Read(dir);
        if (!ent)
            break;

        if (strcmp(ent->name, ".") == 0 || strcmp(ent->name, "..") == 0)
            continue;

        StrArrCat(&arr, ent->name);
    }

    Dir_Close(dir);
    return arr;
}

MI_Boolean Isdir(const char* path)
{
#if defined(CONFIG_OS_WINDOWS)
    {
        struct _stat st;

        if (_stat(path, &st) != 0)
            return 0;

        return (_S_IFDIR  & st.st_mode) ? MI_TRUE : MI_FALSE;
    }
#else
    {
        struct stat st;

        if (stat(path, &st) != 0)
            return 0;

        return S_ISDIR(st.st_mode);
    }
#endif
}

int Mkdirhier(const char* path_, int mode)
{
    char path[MAX_PATH_SIZE];
    char buf[MAX_PATH_SIZE];
    char* p;
    char* context = NULL;

    /* Make a complete copy of the path (that we can destroy) */
    if (Strlcpy(path, path_, sizeof(path)) >= sizeof(path))
        return -1;

    buf[0] = '\0';

    for (p = Strtok(path, "/", &context); p; p = Strtok(NULL, "/", &context))
    {
#if defined(CONFIG_OS_WINDOWS)
        /* Skip drive letters (on Windows) */
        if (p == path && isalpha((unsigned char)p[0]) && p[1] == ':' && p[2] == '\0')
        {
            Strlcat(buf, p, sizeof(buf));
            continue;
        }
#endif

        /* Concatenate next component */
        Strlcat(buf, "/", sizeof(buf));
        Strlcat(buf, p, sizeof(buf));

        /* Create directory if it does not already exist */
        if (!Isdir(buf))
        {
            if (Mkdir(buf, mode) != 0)
                return -1;
        }
    }

    return 0;
}

char* TempPath(char path[MAX_PATH_SIZE], const char* file)
{
    if (Strlcpy(path, GetPath(ID_TMPDIR), MAX_PATH_SIZE) >= MAX_PATH_SIZE)
        return NULL;

    if (Strlcat(path, "/", MAX_PATH_SIZE) >= MAX_PATH_SIZE)
        return NULL;

    if (Strlcat(path, file, MAX_PATH_SIZE) >= MAX_PATH_SIZE)
        return NULL;

    return path;
}

MI_Char* ZSTempPath(MI_Char path[MAX_PATH_SIZE], const char* file)
{
    if (ZStrlcpy(path, GetPath(ID_TMPDIR), MAX_PATH_SIZE) >= MAX_PATH_SIZE)
        return NULL;

    if (ZStrlcat(path, "/", MAX_PATH_SIZE) >= MAX_PATH_SIZE)
        return NULL;

    if (ZStrlcat(path, file, MAX_PATH_SIZE) >= MAX_PATH_SIZE)
        return NULL;

    return path;
}

const char* Basename(const char* path)
{
    const char* p = strrchr(path, '/');

    if (p)
        return p + 1;

    return path;
}

ViewCVS 0.9.2