Blame snmplib/file_utils.c

Packit fcad23
#include <net-snmp/net-snmp-config.h>
Packit fcad23
#include <net-snmp/net-snmp-features.h>
Packit fcad23
#include <net-snmp/net-snmp-includes.h>
Packit fcad23
Packit fcad23
#if HAVE_IO_H
Packit fcad23
#include <io.h>
Packit fcad23
#endif
Packit fcad23
#include <stdio.h>
Packit fcad23
#include <ctype.h>
Packit fcad23
#if HAVE_STDLIB_H
Packit fcad23
#   include <stdlib.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_UNISTD_H
Packit fcad23
#   include <unistd.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_STRING_H
Packit fcad23
#   include <string.h>
Packit fcad23
#else
Packit fcad23
#  include <strings.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#include <sys/types.h>
Packit fcad23
Packit fcad23
#if HAVE_SYS_PARAM_H
Packit fcad23
#   include <sys/param.h>
Packit fcad23
#endif
Packit fcad23
#ifdef HAVE_SYS_STAT_H
Packit fcad23
#   include <sys/stat.h>
Packit fcad23
#endif
Packit fcad23
#ifdef HAVE_FCNTL_H
Packit fcad23
#   include <fcntl.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#include <errno.h>
Packit fcad23
Packit fcad23
#if HAVE_DMALLOC_H
Packit fcad23
#  include <dmalloc.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#include <net-snmp/types.h>
Packit fcad23
#include <net-snmp/library/container.h>
Packit fcad23
#include <net-snmp/library/file_utils.h>
Packit fcad23
Packit fcad23
netsnmp_feature_child_of(file_utils_all, libnetsnmp)
Packit fcad23
netsnmp_feature_child_of(file_utils, file_utils_all)
Packit fcad23
netsnmp_feature_child_of(file_close, file_utils_all)
Packit fcad23
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_FILE_UTILS
Packit fcad23
/*------------------------------------------------------------------
Packit fcad23
 *
Packit fcad23
 * Prototypes
Packit fcad23
 *
Packit fcad23
 */
Packit fcad23
Packit fcad23
Packit fcad23
Packit fcad23
Packit fcad23
/*------------------------------------------------------------------
Packit fcad23
 *
Packit fcad23
 * Core Functions
Packit fcad23
 *
Packit fcad23
 */
Packit fcad23
Packit fcad23
/**
Packit fcad23
 * allocate a netsnmp_file structure
Packit fcad23
 *
Packit fcad23
 * This routine should be used instead of allocating on the stack,
Packit fcad23
 * for future compatability.
Packit fcad23
 */
Packit fcad23
netsnmp_file *
Packit fcad23
netsnmp_file_create(void)
Packit fcad23
{
Packit fcad23
    netsnmp_file *filei = SNMP_MALLOC_TYPEDEF(netsnmp_file);
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * 0 is a valid file descriptor, so init to -1
Packit fcad23
     */
Packit fcad23
    if (NULL != filei)
Packit fcad23
        filei->fd = -1;
Packit fcad23
    else {
Packit fcad23
        snmp_log(LOG_WARNING,"failed to malloc netsnmp_file structure\n");
Packit fcad23
    }
Packit fcad23
Packit fcad23
    return filei;
Packit fcad23
}
Packit fcad23
Packit fcad23
/**
Packit fcad23
 * open file and get stats
Packit fcad23
 */
Packit fcad23
netsnmp_file *
Packit fcad23
netsnmp_file_new(const char *name, int fs_flags, mode_t mode, u_int ns_flags)
Packit fcad23
{
Packit fcad23
    netsnmp_file *filei = netsnmp_file_fill(NULL, name, fs_flags, mode, 0);
Packit fcad23
    if (NULL == filei)
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    if (ns_flags & NETSNMP_FILE_STATS) {
Packit fcad23
        filei->stats = (struct stat*)calloc(1, sizeof(*(filei->stats)));
Packit fcad23
        if (NULL == filei->stats)
Packit fcad23
            DEBUGMSGT(("nsfile:new", "no memory for stats\n"));
Packit fcad23
        else if (stat(name, filei->stats) != 0)
Packit fcad23
            DEBUGMSGT(("nsfile:new", "error getting stats\n"));
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (ns_flags & NETSNMP_FILE_AUTO_OPEN)
Packit fcad23
        netsnmp_file_open(filei);
Packit fcad23
Packit fcad23
    return filei;
Packit fcad23
}
Packit fcad23
Packit fcad23
        
Packit fcad23
/**
Packit fcad23
 * fill core members in a netsnmp_file structure
Packit fcad23
 *
Packit fcad23
 * @param filei      structure to fill; if NULL, a new one will be allocated
Packit fcad23
 * @param name       file name
Packit fcad23
 * @param fs_flags   filesystem flags passed to open()
Packit fcad23
 * @param mode       optional filesystem open modes passed to open()
Packit fcad23
 * @param ns_flags   net-snmp flags
Packit fcad23
 */
Packit fcad23
netsnmp_file *
Packit fcad23
netsnmp_file_fill(netsnmp_file * filei, const char* name,
Packit fcad23
                  int fs_flags, mode_t mode, u_int ns_flags)
Packit fcad23
{
Packit fcad23
    if (NULL == filei) {
Packit fcad23
        filei = netsnmp_file_create();
Packit fcad23
        if (NULL == filei) /* failure already logged */
Packit fcad23
            return NULL;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (NULL != name)
Packit fcad23
        filei->name = strdup(name);
Packit fcad23
Packit fcad23
    filei->fs_flags = fs_flags;
Packit fcad23
    filei->ns_flags = ns_flags;
Packit fcad23
    filei->mode = mode;
Packit fcad23
Packit fcad23
    return filei;
Packit fcad23
}
Packit fcad23
Packit fcad23
/**
Packit fcad23
 * release a netsnmp_file structure
Packit fcad23
 *
Packit fcad23
 * @retval  see close() man page
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
netsnmp_file_release(netsnmp_file * filei)
Packit fcad23
{
Packit fcad23
    int rc = 0;
Packit fcad23
Packit fcad23
    if (NULL == filei)
Packit fcad23
        return -1;
Packit fcad23
Packit fcad23
    if ((filei->fd > 0) && NS_FI_AUTOCLOSE(filei->ns_flags))
Packit fcad23
        rc = close(filei->fd);
Packit fcad23
Packit fcad23
    if (NULL != filei->name)
Packit fcad23
        free(filei->name); /* no point in SNMP_FREE */
Packit fcad23
Packit fcad23
    if (NULL != filei->extras)
Packit fcad23
        netsnmp_free_all_list_data(filei->extras);
Packit fcad23
Packit fcad23
    if (NULL != filei->stats)
Packit fcad23
        free(filei->stats);
Packit fcad23
Packit fcad23
    SNMP_FREE(filei);
Packit fcad23
Packit fcad23
    return rc;
Packit fcad23
}
Packit fcad23
Packit fcad23
/**
Packit fcad23
 * open the file associated with a netsnmp_file structure
Packit fcad23
 *
Packit fcad23
 * @retval -1  : error opening file
Packit fcad23
 * @retval >=0 : file descriptor for opened file
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
netsnmp_file_open(netsnmp_file * filei)
Packit fcad23
{
Packit fcad23
    /*
Packit fcad23
     * basic sanity checks
Packit fcad23
     */
Packit fcad23
    if ((NULL == filei) || (NULL == filei->name))
Packit fcad23
        return -1;
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * if file is already open, just return the fd.
Packit fcad23
     */
Packit fcad23
    if (-1 != filei->fd)
Packit fcad23
        return filei->fd;
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * try to open the file, loging an error if we failed
Packit fcad23
     */
Packit fcad23
    if (0 == filei->mode)
Packit fcad23
        filei->fd = open(filei->name, filei->fs_flags);
Packit fcad23
    else
Packit fcad23
        filei->fd = open(filei->name, filei->fs_flags, filei->mode);
Packit fcad23
Packit fcad23
    if (filei->fd < 0) {
Packit fcad23
        DEBUGMSGTL(("netsnmp_file", "error opening %s (%d)\n", filei->name, errno));
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * return results
Packit fcad23
     */
Packit fcad23
    return filei->fd;
Packit fcad23
}
Packit fcad23
Packit fcad23
Packit fcad23
/**
Packit fcad23
 * close the file associated with a netsnmp_file structure
Packit fcad23
 *
Packit fcad23
 * @retval  0 : success
Packit fcad23
 * @retval -1 : error
Packit fcad23
 */
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_FILE_CLOSE
Packit fcad23
int
Packit fcad23
netsnmp_file_close(netsnmp_file * filei)
Packit fcad23
{
Packit fcad23
    int rc;
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * basic sanity checks
Packit fcad23
     */
Packit fcad23
    if ((NULL == filei) || (NULL != filei->name))
Packit fcad23
        return -1;
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * make sure it's not already closed
Packit fcad23
     */
Packit fcad23
    if (-1 == filei->fd) {
Packit fcad23
        return 0;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * close the file, logging an error if we failed
Packit fcad23
     */
Packit fcad23
    rc = close(filei->fd);
Packit fcad23
    if (rc < 0) {
Packit fcad23
        DEBUGMSGTL(("netsnmp_file", "error closing %s (%d)\n", filei->name, errno));
Packit fcad23
    }
Packit fcad23
    else
Packit fcad23
        filei->fd = -1;
Packit fcad23
Packit fcad23
    return rc;
Packit fcad23
}
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_FILE_CLOSE */
Packit fcad23
Packit fcad23
void
Packit fcad23
netsnmp_file_container_free(netsnmp_file *file, void *context)
Packit fcad23
{
Packit fcad23
    netsnmp_file_release(file);
Packit fcad23
}
Packit fcad23
Packit fcad23
int
Packit fcad23
netsnmp_file_compare_name(netsnmp_file *lhs, netsnmp_file *rhs)
Packit fcad23
{
Packit fcad23
    netsnmp_assert((NULL != lhs) && (NULL != rhs));
Packit fcad23
    netsnmp_assert((NULL != lhs->name) && (NULL != rhs->name));
Packit fcad23
Packit fcad23
    return strcmp(lhs->name, rhs->name);
Packit fcad23
}
Packit fcad23
#else /* NETSNMP_FEATURE_REMOVE_FILE_UTILS */
Packit fcad23
netsnmp_feature_unused(file_utils);
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_FILE_UTILS */