/* Portions of this file are subject to the following copyright(s).  See
 * the Net-SNMP's COPYING file for more details and other copyrights
 * that may apply:
 */
/*
 * Portions of this file are copyrighted by:
 * Copyright (C) 2007 Apple, Inc. All rights reserved.
 * Use is subject to license terms specified in the COPYING file
 * distributed with the Net-SNMP package.
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>

#include <stdio.h>
#include <ctype.h>
#if HAVE_STDLIB_H
#   include <stdlib.h>
#endif
#if HAVE_UNISTD_H
#   include <unistd.h>
#endif
#if HAVE_STRING_H
#   include <string.h>
#else
#  include <strings.h>
#endif

#include <sys/types.h>
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif

#include <errno.h>

#if HAVE_DMALLOC_H
#  include <dmalloc.h>
#endif

#include <net-snmp/types.h>
#include <net-snmp/library/container.h>
#include <net-snmp/library/container_binary_array.h>
#include <net-snmp/library/dir_utils.h>

netsnmp_container *
netsnmp_directory_container_read(netsnmp_container *user_container,
                                 const char *dirname, u_int flags)
{
    DIR               *dir;
    netsnmp_container *container = user_container;
    struct dirent     *file;
    char               path[PATH_MAX];
    u_char             dirname_len;
    int                rc;
#if !(defined(HAVE_STRUCT_DIRENT_D_TYPE) && defined(DT_DIR)) && defined(S_ISDIR)
    struct stat        statbuf;
#endif

    DEBUGMSGTL(("directory:container", "reading %s\n", dirname));

    /*
     * create the container, if needed
     */
    if (NULL == container) {
        container = netsnmp_container_find("directory_container:cstring");
        if (NULL == container)
            return NULL;
        container->container_name = strdup("directory container");
        netsnmp_binary_array_options_set(container, 1, CONTAINER_KEY_UNSORTED);
    }

    dir = opendir(dirname);
    if (NULL == dir) {
        DEBUGMSGTL(("directory:container", "  not a dir\n"));
        return NULL;
    }

    /** copy dirname into path */
    dirname_len = strlen(dirname);
    strlcpy(path, dirname, sizeof(path));
    if ((dirname_len + 2) > sizeof(path)) {
        /** not enough room for files */
        closedir(dir);
        return NULL;
    }
    path[dirname_len] = '/';
    path[++dirname_len] = '\0';

    /** iterate over dir */
    while ((file = readdir(dir))) {

        if ((file->d_name == NULL) || (file->d_name[0] == 0))
            continue;

        /** skip '.' and '..' */
        if ((file->d_name[0] == '.') &&
            ((file->d_name[1] == 0) ||
             ((file->d_name[1] == '.') && ((file->d_name[2] == 0)))))
            continue;

        strlcpy(&path[dirname_len], file->d_name, sizeof(path) - dirname_len);
        DEBUGMSGTL(("9:directory:container", "  found %s\n", path));
#if defined(HAVE_STRUCT_DIRENT_D_TYPE) && defined(DT_DIR)
        if ((file->d_type == DT_DIR) && (flags & NETSNMP_DIR_RECURSE)) {
#elif defined(S_ISDIR)
        if ((flags & NETSNMP_DIR_RECURSE) && (stat(file->d_name, &statbuf) != 0) && (S_ISDIR(statbuf.st_mode))) {
#else
        if (flags & NETSNMP_DIR_RECURSE) {
#endif
            /** xxx add the dir as well? not for now.. maybe another flag? */
            netsnmp_directory_container_read(container, path, flags);
        }
        else {
            char *dup = strdup(path);
            if (NULL == dup) {
               snmp_log(LOG_ERR, "strdup failed\n");
               break;
            }
            rc = CONTAINER_INSERT(container, dup);
            if (-1 == rc ) {
                DEBUGMSGTL(("directory:container", "  err adding %s\n", path));
                free(dup);
            }
        }
    }

    closedir(dir);

    DEBUGMSGTL(("directory:container", "  container now has %d items\n",
                (int)CONTAINER_SIZE(container)));
    
    return container;
}

void
netsnmp_directory_container_free(netsnmp_container *container)
{
    CONTAINER_CLEAR(container, netsnmp_container_simple_free, NULL);
    CONTAINER_FREE(container);
}
