net-snmp 5.7
|
00001 #include <net-snmp/net-snmp-config.h> 00002 #include <net-snmp/net-snmp-features.h> 00003 #include <net-snmp/net-snmp-includes.h> 00004 00005 #include <stdio.h> 00006 #include <ctype.h> 00007 #if HAVE_STDLIB_H 00008 # include <stdlib.h> 00009 #endif 00010 #if HAVE_UNISTD_H 00011 # include <unistd.h> 00012 #endif 00013 #if HAVE_STRING_H 00014 # include <string.h> 00015 #else 00016 # include <strings.h> 00017 #endif 00018 00019 #include <sys/types.h> 00020 00021 #if HAVE_SYS_PARAM_H 00022 # include <sys/param.h> 00023 #endif 00024 #ifdef HAVE_SYS_STAT_H 00025 # include <sys/stat.h> 00026 #endif 00027 #ifdef HAVE_FCNTL_H 00028 # include <fcntl.h> 00029 #endif 00030 00031 #include <errno.h> 00032 00033 #if HAVE_DMALLOC_H 00034 # include <dmalloc.h> 00035 #endif 00036 00037 #include <net-snmp/types.h> 00038 #include <net-snmp/library/container.h> 00039 #include <net-snmp/library/file_utils.h> 00040 00041 netsnmp_feature_child_of(file_utils_all, libnetsnmp) 00042 netsnmp_feature_child_of(file_utils, file_utils_all) 00043 netsnmp_feature_child_of(file_close, file_utils_all) 00044 00045 #ifndef NETSNMP_FEATURE_REMOVE_FILE_UTILS 00046 /*------------------------------------------------------------------ 00047 * 00048 * Prototypes 00049 * 00050 */ 00051 00052 00053 00054 00055 /*------------------------------------------------------------------ 00056 * 00057 * Core Functions 00058 * 00059 */ 00060 00067 netsnmp_file * 00068 netsnmp_file_create(void) 00069 { 00070 netsnmp_file *filei = SNMP_MALLOC_TYPEDEF(netsnmp_file); 00071 00072 /* 00073 * 0 is a valid file descriptor, so init to -1 00074 */ 00075 if (NULL != filei) 00076 filei->fd = -1; 00077 else { 00078 snmp_log(LOG_WARNING,"failed to malloc netsnmp_file structure\n"); 00079 } 00080 00081 return filei; 00082 } 00083 00087 netsnmp_file * 00088 netsnmp_file_new(const char *name, int fs_flags, mode_t mode, u_int ns_flags) 00089 { 00090 netsnmp_file *filei = netsnmp_file_fill(NULL, name, fs_flags, mode, 0); 00091 if (NULL == filei) 00092 return NULL; 00093 00094 if (ns_flags & NETSNMP_FILE_STATS) { 00095 filei->stats = (struct stat*)calloc(1, sizeof(*(filei->stats))); 00096 if (NULL == filei->stats) 00097 DEBUGMSGT(("nsfile:new", "no memory for stats\n")); 00098 else if (stat(name, filei->stats) != 0) 00099 DEBUGMSGT(("nsfile:new", "error getting stats\n")); 00100 } 00101 00102 if (ns_flags & NETSNMP_FILE_AUTO_OPEN) 00103 netsnmp_file_open(filei); 00104 00105 return filei; 00106 } 00107 00108 00118 netsnmp_file * 00119 netsnmp_file_fill(netsnmp_file * filei, const char* name, 00120 int fs_flags, mode_t mode, u_int ns_flags) 00121 { 00122 if (NULL == filei) { 00123 filei = netsnmp_file_create(); 00124 if (NULL == filei) /* failure already logged */ 00125 return NULL; 00126 } 00127 00128 if (NULL != name) 00129 filei->name = strdup(name); 00130 00131 filei->fs_flags = fs_flags; 00132 filei->ns_flags = ns_flags; 00133 filei->mode = mode; 00134 00135 return filei; 00136 } 00137 00143 int 00144 netsnmp_file_release(netsnmp_file * filei) 00145 { 00146 int rc = 0; 00147 00148 if (NULL == filei) 00149 return -1; 00150 00151 if ((filei->fd > 0) && NS_FI_AUTOCLOSE(filei->ns_flags)) 00152 rc = close(filei->fd); 00153 00154 if (NULL != filei->name) 00155 free(filei->name); /* no point in SNMP_FREE */ 00156 00157 if (NULL != filei->extras) 00158 netsnmp_free_all_list_data(filei->extras); 00159 00160 if (NULL != filei->stats) 00161 free(filei->stats); 00162 00163 SNMP_FREE(filei); 00164 00165 return rc; 00166 } 00167 00174 int 00175 netsnmp_file_open(netsnmp_file * filei) 00176 { 00177 /* 00178 * basic sanity checks 00179 */ 00180 if ((NULL == filei) || (NULL == filei->name)) 00181 return -1; 00182 00183 /* 00184 * if file is already open, just return the fd. 00185 */ 00186 if (-1 != filei->fd) 00187 return filei->fd; 00188 00189 /* 00190 * try to open the file, loging an error if we failed 00191 */ 00192 if (0 == filei->mode) 00193 filei->fd = open(filei->name, filei->fs_flags); 00194 else 00195 filei->fd = open(filei->name, filei->fs_flags, filei->mode); 00196 00197 if (filei->fd < 0) { 00198 snmp_log(LOG_ERR, "error opening %s (%d)\n", filei->name, errno); 00199 } 00200 00201 /* 00202 * return results 00203 */ 00204 return filei->fd; 00205 } 00206 00207 00214 #ifndef NETSNMP_FEATURE_REMOVE_FILE_CLOSE 00215 int 00216 netsnmp_file_close(netsnmp_file * filei) 00217 { 00218 int rc; 00219 00220 /* 00221 * basic sanity checks 00222 */ 00223 if ((NULL == filei) || (NULL != filei->name)) 00224 return -1; 00225 00226 /* 00227 * make sure it's not already closed 00228 */ 00229 if (-1 == filei->fd) { 00230 return 0; 00231 } 00232 00233 /* 00234 * close the file, logging an error if we failed 00235 */ 00236 rc = close(filei->fd); 00237 if (rc < 0) { 00238 snmp_log(LOG_ERR, "error closing %s (%d)\n", filei->name, errno); 00239 } 00240 else 00241 filei->fd = -1; 00242 00243 return rc; 00244 } 00245 #endif /* NETSNMP_FEATURE_REMOVE_FILE_CLOSE */ 00246 00247 void 00248 netsnmp_file_container_free(netsnmp_file *file, void *context) 00249 { 00250 netsnmp_file_release(file); 00251 } 00252 00253 int 00254 netsnmp_file_compare_name(netsnmp_file *lhs, netsnmp_file *rhs) 00255 { 00256 netsnmp_assert((NULL != lhs) && (NULL != rhs)); 00257 netsnmp_assert((NULL != lhs->name) && (NULL != rhs->name)); 00258 00259 return strcmp(lhs->name, rhs->name); 00260 } 00261 #else /* NETSNMP_FEATURE_REMOVE_FILE_UTILS */ 00262 netsnmp_feature_unused(file_utils); 00263 #endif /* NETSNMP_FEATURE_REMOVE_FILE_UTILS */