| #include <net-snmp/net-snmp-config.h> |
| #include <net-snmp/net-snmp-features.h> |
| #include <net-snmp/net-snmp-includes.h> |
| |
| #if HAVE_IO_H |
| #include <io.h> |
| #endif |
| #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_SYS_PARAM_H |
| # include <sys/param.h> |
| #endif |
| #ifdef HAVE_SYS_STAT_H |
| # include <sys/stat.h> |
| #endif |
| #ifdef HAVE_FCNTL_H |
| # include <fcntl.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/file_utils.h> |
| |
| netsnmp_feature_child_of(file_utils_all, libnetsnmp) |
| netsnmp_feature_child_of(file_utils, file_utils_all) |
| netsnmp_feature_child_of(file_close, file_utils_all) |
| |
| #ifndef NETSNMP_FEATURE_REMOVE_FILE_UTILS |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| netsnmp_file * |
| netsnmp_file_create(void) |
| { |
| netsnmp_file *filei = SNMP_MALLOC_TYPEDEF(netsnmp_file); |
| |
| |
| |
| |
| if (NULL != filei) |
| filei->fd = -1; |
| else { |
| snmp_log(LOG_WARNING,"failed to malloc netsnmp_file structure\n"); |
| } |
| |
| return filei; |
| } |
| |
| |
| |
| |
| netsnmp_file * |
| netsnmp_file_new(const char *name, int fs_flags, mode_t mode, u_int ns_flags) |
| { |
| netsnmp_file *filei = netsnmp_file_fill(NULL, name, fs_flags, mode, 0); |
| if (NULL == filei) |
| return NULL; |
| |
| if (ns_flags & NETSNMP_FILE_STATS) { |
| filei->stats = (struct stat*)calloc(1, sizeof(*(filei->stats))); |
| if (NULL == filei->stats) |
| DEBUGMSGT(("nsfile:new", "no memory for stats\n")); |
| else if (stat(name, filei->stats) != 0) |
| DEBUGMSGT(("nsfile:new", "error getting stats\n")); |
| } |
| |
| if (ns_flags & NETSNMP_FILE_AUTO_OPEN) |
| netsnmp_file_open(filei); |
| |
| return filei; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| netsnmp_file * |
| netsnmp_file_fill(netsnmp_file * filei, const char* name, |
| int fs_flags, mode_t mode, u_int ns_flags) |
| { |
| if (NULL == filei) { |
| filei = netsnmp_file_create(); |
| if (NULL == filei) |
| return NULL; |
| } |
| |
| if (NULL != name) |
| filei->name = strdup(name); |
| |
| filei->fs_flags = fs_flags; |
| filei->ns_flags = ns_flags; |
| filei->mode = mode; |
| |
| return filei; |
| } |
| |
| |
| |
| |
| |
| |
| int |
| netsnmp_file_release(netsnmp_file * filei) |
| { |
| int rc = 0; |
| |
| if (NULL == filei) |
| return -1; |
| |
| if ((filei->fd > 0) && NS_FI_AUTOCLOSE(filei->ns_flags)) |
| rc = close(filei->fd); |
| |
| if (NULL != filei->name) |
| free(filei->name); |
| |
| if (NULL != filei->extras) |
| netsnmp_free_all_list_data(filei->extras); |
| |
| if (NULL != filei->stats) |
| free(filei->stats); |
| |
| SNMP_FREE(filei); |
| |
| return rc; |
| } |
| |
| |
| |
| |
| |
| |
| |
| int |
| netsnmp_file_open(netsnmp_file * filei) |
| { |
| |
| |
| |
| if ((NULL == filei) || (NULL == filei->name)) |
| return -1; |
| |
| |
| |
| |
| if (-1 != filei->fd) |
| return filei->fd; |
| |
| |
| |
| |
| if (0 == filei->mode) |
| filei->fd = open(filei->name, filei->fs_flags); |
| else |
| filei->fd = open(filei->name, filei->fs_flags, filei->mode); |
| |
| if (filei->fd < 0) { |
| DEBUGMSGTL(("netsnmp_file", "error opening %s (%d)\n", filei->name, errno)); |
| } |
| |
| |
| |
| |
| return filei->fd; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifndef NETSNMP_FEATURE_REMOVE_FILE_CLOSE |
| int |
| netsnmp_file_close(netsnmp_file * filei) |
| { |
| int rc; |
| |
| |
| |
| |
| if ((NULL == filei) || (NULL != filei->name)) |
| return -1; |
| |
| |
| |
| |
| if (-1 == filei->fd) { |
| return 0; |
| } |
| |
| |
| |
| |
| rc = close(filei->fd); |
| if (rc < 0) { |
| DEBUGMSGTL(("netsnmp_file", "error closing %s (%d)\n", filei->name, errno)); |
| } |
| else |
| filei->fd = -1; |
| |
| return rc; |
| } |
| #endif |
| |
| void |
| netsnmp_file_container_free(netsnmp_file *file, void *context) |
| { |
| netsnmp_file_release(file); |
| } |
| |
| int |
| netsnmp_file_compare_name(netsnmp_file *lhs, netsnmp_file *rhs) |
| { |
| netsnmp_assert((NULL != lhs) && (NULL != rhs)); |
| netsnmp_assert((NULL != lhs->name) && (NULL != rhs->name)); |
| |
| return strcmp(lhs->name, rhs->name); |
| } |
| #else |
| netsnmp_feature_unused(file_utils); |
| #endif |