read_config.c
资源名称:snmp.src.rar [点击查看]
上传用户:cxs890
上传日期:2021-05-22
资源大小:347k
文件大小:28k
源码类别:
SNMP编程
开发平台:
C/C++
- /*
- * read_config.c
- */
- #include <config.h>
- #include <stdio.h>
- #include <ctype.h>
- #if HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #if HAVE_STRING_H
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #if HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include <sys/types.h>
- #if HAVE_SYS_PARAM_H
- #include <sys/param.h>
- #endif
- #if TIME_WITH_SYS_TIME
- # ifdef WIN32
- # include <sys/timeb.h>
- # else
- # include <time.h>
- # endif
- # include <time.h>
- #else
- # if HAVE_SYS_TIME_H
- # include <sys/time.h>
- # else
- # include <time.h>
- # endif
- #endif
- #ifdef HAVE_SYS_STAT_H
- #endif
- #if HAVE_NETINET_IN_H
- #include <netinet/in.h>
- #endif
- #if HAVE_ARPA_INET_H
- #include <arpa/inet.h>
- #endif
- #if HAVE_SYS_SELECT_H
- #include <sys/select.h>
- #endif
- #if HAVE_WINSOCK_H
- #include <ip/socket.h>
- #endif
- #if HAVE_SYS_SOCKET_H
- #include <sys/socket.h>
- #endif
- #if HAVE_NETDB_H
- #include <netdb.h>
- #endif
- #include <errno.h>
- #if HAVE_DMALLOC_H
- #include <dmalloc.h>
- #endif
- #include "asn1.h"
- #include "mib.h"
- #include "parse.h"
- #include "system.h"
- #include "snmp_api.h"
- #include "snmp_debug.h"
- #include "snmp_logging.h"
- #include "snmp_impl.h"
- #include "default_store.h"
- #include "callback.h"
- #include "read_config.h"
- #include "tools.h"
- #include <libsys/misc.h>
- int config_errors;
- struct config_files *config_files = NULL;
- extern char *strdup (const char *);
- extern char *staticstrdup(const char *);
- extern void vacm_parse_view (const char *, char *);
- struct config_line *
- register_premib_handler(const char *type,
- const char *token,
- void (*parser) (const char *, char *),
- void (*releaser) (void),
- const char *help)
- {
- struct config_line *ltmp;
- ltmp = register_config_handler(type, token, parser, releaser, help);
- if (ltmp != NULL)
- ltmp->config_time = PREMIB_CONFIG;
- return (ltmp);
- }
- struct config_line *
- register_app_premib_handler(const char *token,
- void (*parser) (const char *, char *),
- void (*releaser) (void),
- const char *help)
- {
- return(register_premib_handler( NULL, token, parser, releaser, help ));
- }
- /*******************************************************************-o-******
- * register_config_handler
- *
- * Parameters:
- * *type
- * *token
- * *parser
- * *releaser
- *
- * Returns:
- * Pointer to a new config line entry -OR- NULL on error.
- */
- struct config_line *
- register_config_handler(const char *type_param,
- const char *token,
- void (*parser) (const char *, char *),
- void (*releaser) (void),
- const char *help)
- {
- struct config_files **ctmp = &config_files;
- struct config_line **ltmp;
- const char *type = type_param;
- if ( type == NULL )
- type = ds_get_string(DS_LIBRARY_ID, DS_LIB_APPTYPE);
- /*
- * Find type in current list -OR- create a new file type.
- */
- while (*ctmp != NULL && strcmp((*ctmp)->fileHeader, type)) {
- ctmp = &((*ctmp)->next);
- }
- if (*ctmp == NULL) {
- *ctmp = (struct config_files *)
- malloc(sizeof(struct config_files));
- if ( !*ctmp ) {
- return NULL;
- }
- (*ctmp)->next = NULL;
- (*ctmp)->start = NULL;
- (*ctmp)->fileHeader = strdup(type);
- }
- /*
- * Find parser type in current list -OR- create a new
- * line parser entry.
- */
- ltmp = &((*ctmp)->start);
- while (*ltmp != NULL && strcmp((*ltmp)->config_token, token)) {
- ltmp = &((*ltmp)->next);
- }
- if (*ltmp == NULL) {
- *ltmp = (struct config_line *)
- malloc(sizeof(struct config_line));
- if ( !*ltmp ) {
- return NULL;
- }
- (*ltmp)->next = NULL;
- (*ltmp)->config_time = NORMAL_CONFIG;
- (*ltmp)->parse_line = 0;
- (*ltmp)->free_func = 0;
- (*ltmp)->config_token = staticstrdup(token);
- if (help != NULL)
- (*ltmp)->help = staticstrdup(help);
- }
- /*
- * Add/Replace the parse/free functions for the given line type
- * in the given file type.
- */
- (*ltmp)->parse_line = parser;
- (*ltmp)->free_func = releaser;
- return (*ltmp);
- } /* end register_config_handler() */
- struct config_line *
- register_app_config_handler(const char *token,
- void (*parser) (const char *, char *),
- void (*releaser) (void),
- const char *help)
- {
- return(register_config_handler( NULL, token, parser, releaser, help ));
- }
- #if 0
- void
- unregister_config_handler(const char *type_param,
- const char *token)
- {
- struct config_files **ctmp = &config_files;
- struct config_line **ltmp, *ltmp2;
- const char *type = type_param;
- if ( type == NULL )
- type = ds_get_string(DS_LIBRARY_ID, DS_LIB_APPTYPE);
- /* find type in current list */
- while (*ctmp != NULL && strcmp((*ctmp)->fileHeader,type)) {
- ctmp = &((*ctmp)->next);
- }
- if (*ctmp == NULL) {
- /* Not found, return. */
- return;
- }
- ltmp = &((*ctmp)->start);
- if (*ltmp == NULL) {
- /* Not found, return. */
- return;
- }
- if (strcmp((*ltmp)->config_token,token) == 0) {
- /* found it at the top of the list */
- (*ctmp)->start = (*ltmp)->next;
- free((*ltmp)->config_token);
- SNMP_FREE((*ltmp)->help);
- free(*ltmp);
- return;
- }
- while ((*ltmp)->next != NULL && strcmp((*ltmp)->next->config_token,token)) {
- ltmp = &((*ltmp)->next);
- }
- if (*ltmp == NULL) {
- free((*ltmp)->config_token);
- SNMP_FREE((*ltmp)->help);
- ltmp2 = (*ltmp)->next->next;
- free((*ltmp)->next);
- (*ltmp)->next = ltmp2;
- }
- }
- void
- unregister_app_config_handler(const char *token)
- {
- unregister_config_handler( NULL, token );
- }
- #endif
- #ifdef TESTING
- void print_config_handlers (void)
- {
- struct config_files *ctmp = config_files;
- struct config_line *ltmp;
- for(;ctmp != NULL; ctmp = ctmp->next) {
- DEBUGMSGTL(("read_config", "read_conf: %sn", ctmp->fileHeader));
- for(ltmp = ctmp->start; ltmp != NULL; ltmp = ltmp->next)
- DEBUGMSGTL(("read_config", " %sn", ltmp->config_token));
- }
- }
- #endif
- int linecount;
- const char *curfilename;
- void read_config_with_type(const char *filename,
- const char *type)
- {
- struct config_files *ctmp = config_files;
- for(;ctmp != NULL && strcmp(ctmp->fileHeader,type); ctmp = ctmp->next);
- if (ctmp)
- read_config(filename, ctmp->start, EITHER_CONFIG);
- else
- DEBUGMSGTL(("read_config", "read_config: I have no registrations for type:%s,file:%sn",
- type, filename));
- }
- /*******************************************************************-o-******
- * read_config
- *
- * Parameters:
- * *filename
- * *line_handler
- * when
- *
- * Read <filename> and process each line in accordance with the list of
- * <line_handler> functions.
- *
- *
- * For each line in <filename>, search the list of <line_handler>'s
- * for an entry that matches the first token on the line. This comparison is
- * case insensitive.
- *
- * For each match, check that <when> is the designated time for the
- * <line_handler> function to be executed before processing the line.
- */
- void read_config(const char *filename,
- struct config_line *line_handler,
- int when)
- {
- #ifdef UCD_SNMP
- FILE *ifile;
- char line[STRINGMAX], token[STRINGMAX], tmpbuf[STRINGMAX];
- char *cptr;
- int i, done;
- struct config_line *lptr;
- linecount = 0;
- curfilename = filename;
- if ((ifile = fopen(filename, "r")) == NULL) {
- #ifdef ENOENT
- if (errno == ENOENT) {
- DEBUGMSGTL(("read_config", "%s: %sn", filename, strerror(errno)));
- } else
- #endif /* ENOENT */
- #ifdef EACCES
- if (errno == EACCES) {
- DEBUGMSGTL(("read_config", "%s: %sn", filename, strerror(errno)));
- } else
- #endif /* EACCES */
- #if defined(ENOENT) || defined(EACCES)
- {
- snmp_log_perror(filename);
- }
- #else /* defined(ENOENT) || defined(EACCES) */
- snmp_log_perror(filename);
- #endif /* ENOENT */
- return;
- } else {
- DEBUGMSGTL(("read_config", "Reading configuration %sn", filename));
- }
- while (fgets(line, sizeof(line), ifile) != NULL)
- {
- lptr = line_handler;
- linecount++;
- cptr = line;
- i = strlen(line)-1;
- if (line[i] == 'n')
- line[i] = 0;
- /* check blank line or # comment */
- if ((cptr = skip_white(cptr)))
- {
- cptr = copy_word(cptr,token);
- if (cptr == NULL) {
- sprintf(tmpbuf,"Blank line following %s token.", token);
- config_perror(tmpbuf);
- } else {
- for(lptr = line_handler, done=0;
- lptr != NULL && !done;
- lptr = lptr->next) {
- if (!strcasecmp(token,lptr->config_token)) {
- if (when == EITHER_CONFIG || lptr->config_time == when) {
- DEBUGMSGTL(("read_config", "%s:%d Parsing: %sn",
- filename, linecount, line));
- (*(lptr->parse_line))(token,cptr);
- }
- done = 1;
- }
- }
- if (!done && when != PREMIB_CONFIG &&
- !ds_get_boolean(DS_LIBRARY_ID, DS_LIB_NO_TOKEN_WARNINGS)) {
- sprintf(tmpbuf,"Unknown token: %s.", token);
- config_pwarn(tmpbuf);
- }
- }
- }
- }
- fclose(ifile);
- return;
- #endif
- } /* end read_config() */
- void
- free_config (void)
- {
- struct config_files *ctmp = config_files;
- struct config_line *ltmp;
- for(;ctmp != NULL; ctmp = ctmp->next)
- for(ltmp = ctmp->start; ltmp != NULL; ltmp = ltmp->next)
- if (ltmp->free_func)
- (*(ltmp->free_func))();
- }
- static char snmpv3_default_view_str[] = SNMPV3_DEFAULT_VIEW" included .1.3.6.1";
- void
- read_configs (void)
- {
- char *optional_config = ds_get_string(DS_LIBRARY_ID, DS_LIB_OPTIONALCONFIG);
- char *type = ds_get_string(DS_LIBRARY_ID, DS_LIB_APPTYPE);
- DEBUGMSGTL(("read_config","reading normal configuration tokensn"));
- if (!ds_get_boolean(DS_LIBRARY_ID, DS_LIB_DONT_READ_CONFIGS))
- read_config_files(NORMAL_CONFIG);
- /* do this even when the normal above wasn't done */
- if (optional_config && type)
- read_config_with_type(optional_config, type);
- snmp_call_callbacks(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_READ_CONFIG,
- NULL);
- vacm_parse_view("view",snmpv3_default_view_str/*SNMPV3_DEFAULT_VIEW" included .1.3.6.1"*/);
- }
- void
- read_premib_configs (void)
- {
- DEBUGMSGTL(("read_config","reading premib configuration tokensn"));
- if (!ds_get_boolean(DS_LIBRARY_ID, DS_LIB_DONT_READ_CONFIGS))
- read_config_files(PREMIB_CONFIG);
- snmp_call_callbacks(SNMP_CALLBACK_LIBRARY,
- SNMP_CALLBACK_POST_PREMIB_READ_CONFIG,
- NULL);
- }
- /*******************************************************************-o-******
- * read_config_files
- *
- * Parameters:
- * when == PREMIB_CONFIG, NORMAL_CONFIG -or- EITHER_CONFIG
- *
- *
- * Traverse the list of config file types, performing the following actions
- * for each --
- *
- * First, build a search path for config files. If the contents of
- * environment variable SNMPCONFPATH are NULL, then use the following
- * path list (where the last entry exists only if HOME is non-null):
- *
- * SNMPSHAREPATH:SNMPLIBPATH:${HOME}/.snmp
- *
- * Then, In each of these directories, read config files by the name of:
- *
- * <dir>/<fileHeader>.conf -AND-
- * <dir>/<fileHeader>.local.conf
- *
- * where <fileHeader> is taken from the config file type structure.
- *
- *
- * PREMIB_CONFIG causes free_config() to be invoked prior to any other action.
- *
- *
- * EXITs if any 'config_errors' are logged while parsing config file lines.
- */
- void
- read_config_files (int when)
- {
- #ifdef UCD_SNMP
- int i, j;
- char configfile[300];
- char *envconfpath, *homepath;
- char *cptr1, *cptr2;
- char defaultPath[SPRINT_MAX_LEN];
- struct config_files *ctmp = config_files;
- struct config_line *ltmp;
- struct stat statbuf;
- if (when == PREMIB_CONFIG)
- free_config();
- /* read all config file types */
- for(;ctmp != NULL; ctmp = ctmp->next) {
- ltmp = ctmp->start;
- /* read the config files */
- if ((envconfpath = getenv("SNMPCONFPATH")) == NULL) {
- homepath=getenv("HOME");
- sprintf(defaultPath,"%s%c%s%c%s%s%s%s%c%s",
- SNMPCONFPATH, ENV_SEPARATOR_CHAR,
- SNMPSHAREPATH, ENV_SEPARATOR_CHAR, SNMPLIBPATH,
- ((homepath == NULL) ? "" : ENV_SEPARATOR),
- ((homepath == NULL) ? "" : homepath),
- ((homepath == NULL) ? "" : "/.snmp"),
- ENV_SEPARATOR_CHAR, PERSISTENT_DIRECTORY);
- envconfpath = defaultPath;
- }
- envconfpath = strdup(envconfpath); /* prevent actually writing in env */
- DEBUGMSGTL(("read_config","config path used:%sn", envconfpath));
- cptr1 = cptr2 = envconfpath;
- i = 1;
- while (i && *cptr2 != 0) {
- while(*cptr1 != 0 && *cptr1 != ENV_SEPARATOR_CHAR)
- cptr1++;
- if (*cptr1 == 0)
- i = 0;
- else
- *cptr1 = 0;
- /*
- * for proper persistent storage retrival, we need to read old backup
- * copies of the previous storage files. If the application in
- * question has died without the proper call to snmp_clean_persistent,
- * then we read all the configuration files we can, starting with
- * the oldest first.
- */
- if (strncmp(cptr2, PERSISTENT_DIRECTORY,
- strlen(PERSISTENT_DIRECTORY)) == 0 ||
- (getenv("SNMP_PERSISTENT_FILE") != NULL &&
- strncmp(cptr2, getenv("SNMP_PERSISTENT_FILE"),
- strlen(getenv("SNMP_PERSISTENT_FILE"))) == 0)) {
- /* limit this to the known storage directory only */
- for(j=0; j <= MAX_PERSISTENT_BACKUPS; j++) {
- sprintf(configfile,"%s/%s.%d.conf",cptr2, ctmp->fileHeader, j);
- if (stat(configfile, &statbuf) != 0) {
- /* file not there, continue */
- break;
- } else {
- /* backup exists, read it */
- DEBUGMSGTL(("read_config_files","old config file found: %s, parsingn", configfile));
- read_config (configfile, ltmp, when);
- }
- }
- }
- sprintf(configfile,"%s/%s.conf",cptr2, ctmp->fileHeader);
- read_config (configfile, ltmp, when);
- sprintf(configfile,"%s/%s.local.conf",cptr2, ctmp->fileHeader);
- read_config (configfile, ltmp, when);
- cptr2 = ++cptr1;
- }
- free(envconfpath);
- }
- if (config_errors) {
- snmp_log(LOG_ERR, "ucd-snmp: %d errors in config filen", config_errors);
- /* exit(1); */
- }
- #endif
- }
- void read_config_print_usage(const char *lead)
- {
- struct config_files *ctmp = config_files;
- struct config_line *ltmp;
- if (lead == NULL)
- lead = "";
- for(ctmp = config_files; ctmp != NULL; ctmp = ctmp->next) {
- snmp_log(LOG_INFO, "%sIn %s.conf and %s.local.conf:n", lead, ctmp->fileHeader,
- ctmp->fileHeader);
- for(ltmp = ctmp->start; ltmp != NULL; ltmp = ltmp->next) {
- if (ltmp->help != NULL)
- snmp_log(LOG_INFO, "%s%s%-15s %sn", lead, lead, ltmp->config_token,
- ltmp->help);
- }
- }
- }
- /*******************************************************************-o-******
- * read_config_store
- *
- * Parameters:
- * *type
- * *line
- *
- *
- * Append line to a file named either ENV(SNMP_PERSISTENT_FILE) or
- * "<PERSISTENT_DIRECTORY>/<type>.conf".
- * Add a trailing newline to the stored file if necessary.
- *
- * Intended for use by applications to store permenant configuration
- * information generated by sets or persistent counters.
- *
- */
- void
- read_config_store(const char *type, const char *line)
- {
- #ifdef UCD_SNMP
- #ifdef PERSISTENT_DIRECTORY
- char file[512], *filep;
- FILE *fout;
- #ifdef PERSISTENT_MASK
- mode_t oldmask;
- #endif
- /* store configuration directives in the following order of preference:
- 1. ENV variable SNMP_PERSISTENT_FILE
- 2. configured <PERSISTENT_DIRECTORY>/<type>.conf
- */
- if ((filep = getenv("SNMP_PERSISTENT_FILE")) == NULL) {
- sprintf(file,"%s/%s.conf",PERSISTENT_DIRECTORY,type);
- filep = file;
- }
- #ifdef PERSISTENT_MASK
- oldmask = umask(PERSISTENT_MASK);
- #endif
- if (mkdirhier(filep, AGENT_DIRECTORY_MODE, 1)) {
- snmp_log(LOG_ERR, "Failed to create the persistent directory for %sn",
- file);
- }
- if ((fout = fopen(filep, "a")) != NULL) {
- fprintf(fout,line);
- if (line[strlen(line)] != 'n')
- fprintf(fout,"n");
- DEBUGMSGTL(("read_config","storing: %sn",line));
- fclose(fout);
- } else {
- DEBUGMSGTL(("read_config","open failure"));
- }
- #ifdef PERSISTENT_MASK
- umask(oldmask);
- #endif
- #endif
- #endif
- } /* end read_config_store() */
- void
- read_app_config_store(const char *line)
- {
- read_config_store(ds_get_string(DS_LIBRARY_ID, DS_LIB_APPTYPE), line);
- }
- /*******************************************************************-o-******
- * snmp_save_persistent
- *
- * Parameters:
- * *type
- *
- *
- * Save the file "<PERSISTENT_DIRECTORY>/<type>.conf" into a backup copy
- * called "<PERSISTENT_DIRECTORY>/<type>.%d.conf", which %d is an
- * incrementing number on each call, but less than MAX_PERSISTENT_BACKUPS.
- *
- * Should be called just before all persistent information is supposed to be
- * written to move aside the existing persistent cache.
- * snmp_clean_persistent should then be called afterward all data has been
- * saved to remove these backup files.
- *
- * Note: on an rename error, the files are removed rather than saved.
- *
- */
- void
- snmp_save_persistent(const char *type)
- {
- #ifdef UCD_SNMP
- char file[512], fileold[512];
- struct stat statbuf;
- int j;
- DEBUGMSGTL(("snmp_save_persistent","saving %s files...n", type));
- sprintf(file,"%s/%s.conf", PERSISTENT_DIRECTORY, type);
- if (stat(file, &statbuf) == 0) {
- for(j=0; j <= MAX_PERSISTENT_BACKUPS; j++) {
- sprintf(fileold,"%s/%s.%d.conf", PERSISTENT_DIRECTORY, type, j);
- if (stat(fileold, &statbuf) != 0) {
- DEBUGMSGTL(("snmp_save_persistent"," saving old config file: %s -> %s.n", file, fileold));
- if (rename(file, fileold)) {
- unlink(file);/* moving it failed, try nuking it, as leaving
- it around is very bad. */
- }
- break;
- }
- }
- }
- #endif
- }
- /*******************************************************************-o-******
- * snmp_clean_persistent
- *
- * Parameters:
- * *type
- *
- *
- * Unlink all backup files called "<PERSISTENT_DIRECTORY>/<type>.%d.conf".
- *
- * Should be called just after we successfull dumped the last of the
- * persistent data, to remove the backup copies of previous storage dumps.
- *
- * XXX Worth overwriting with random bytes first? This would
- * ensure that the data is destroyed, even a buffer containing the
- * data persists in memory or swap. Only important if secrets
- * will be stored here.
- */
- void
- snmp_clean_persistent(const char *type)
- {
- #ifdef UCD_SNMP
- char file[512];
- struct stat statbuf;
- int j;
- DEBUGMSGTL(("snmp_clean_persistent","cleaning %s files...n", type));
- sprintf(file,"%s/%s.conf",PERSISTENT_DIRECTORY,type);
- if (stat(file, &statbuf) == 0) {
- for(j=0; j <= MAX_PERSISTENT_BACKUPS; j++) {
- sprintf(file,"%s/%s.%d.conf", PERSISTENT_DIRECTORY, type, j);
- if (stat(file, &statbuf) == 0) {
- DEBUGMSGTL(("snmp_clean_persistent"," removing old config file: %sn", file));
- unlink(file);
- }
- }
- }
- #endif
- }
- /* config_perror: prints a warning string associated with a file and
- line number of a .conf file and increments the error count. */
- void config_perror(const char *string)
- {
- config_pwarn(string);
- config_errors++;
- }
- void config_pwarn(const char *string)
- {
- snmp_log(LOG_WARNING, "%s: line %d: %sn", curfilename, linecount, string);
- }
- /* skip all white spaces and return 1 if found something either end of
- line or a comment character */
- char *skip_white(char *ptr)
- {
- if (ptr == NULL) return (NULL);
- while (*ptr != 0 && isspace(*ptr)) ptr++;
- if (*ptr == 0 || *ptr == '#') return (NULL);
- return (ptr);
- }
- char *skip_not_white(char *ptr)
- {
- if (ptr == NULL) return (NULL);
- while (*ptr != 0 && !isspace(*ptr)) ptr++;
- if (*ptr == 0 || *ptr == '#') return (NULL);
- return (ptr);
- }
- char *skip_token(char *ptr)
- {
- ptr = skip_white(ptr);
- ptr = skip_not_white(ptr);
- ptr = skip_white(ptr);
- return (ptr);
- }
- /* copy_word
- copies the next 'token' from 'from' into 'to'.
- currently a token is anything seperate by white space
- or within quotes (double or single) (i.e. "the red rose"
- is one token, "the red rose" is three tokens)
- a '' character will allow a quote character to be treated
- as a regular character
- It returns a pointer to first non-white space after the end of the token
- being copied or to 0 if we reach the end.*/
- char *copy_word(char *from, char *to)
- {
- char quote;
- if ( (*from == '"') || (*from ==''') ){
- quote = *(from++);
- while ( (*from != quote) && (*from != 0) ) {
- if ((*from == '\') && (*(from+1) != 0)) {
- *to++ = *(from+1);
- from = from +2;
- }
- else *to++ = *from++;
- }
- if (*from == 0) {
- DEBUGMSGTL(("read_config_copy_word",
- "no end quote found in config stringn"));
- } else from++;
- }
- else {
- while (*from != 0 && !isspace(*from)) {
- if ((*from == '\') && (*(from+1) != 0)) {
- *to++ = *(from+1);
- from = from +2;
- }
- else *to++ = *from++;
- }
- }
- *to = 0;
- from = skip_white(from);
- return(from);
- } /* copy_word */
- /* read_config_save_octet_string(): saves an octet string as a length
- followed by a string of hex */
- char *read_config_save_octet_string(char *saveto, u_char *str, size_t len) {
- int i;
- if (str != NULL) {
- sprintf(saveto, "0x");
- saveto += 2;
- for(i = 0; i < (int)len; i++) {
- sprintf(saveto,"%02x", str[i]);
- saveto = saveto + 2;
- }
- return saveto;
- } else {
- sprintf(saveto,"""");
- saveto += 2;
- }
- return saveto;
- }
- /* read_config_read_octet_string(): reads an octet string that was
- saved by the read_config_save_octet_string() function */
- char *read_config_read_octet_string(char *readfrom, u_char **str, size_t *len) {
- u_char *cptr=NULL;
- char *cptr1;
- u_int tmp;
- int i;
- if (readfrom == NULL || str == NULL)
- return NULL;
- if (strncasecmp(readfrom,"0x",2) == 0) {
- /* A hex string submitted. How long? */
- readfrom += 2;
- cptr1 = skip_not_white(readfrom);
- if (cptr1)
- *len = (cptr1 - readfrom);
- else
- *len = strlen(readfrom);
- if (*len % 2) {
- DEBUGMSGTL(("read_config_read_octet_string","invalid hex string: wrong length"));
- return NULL;
- }
- *len = *len / 2;
- /* malloc data space if needed */
- if (*str == NULL) {
- if (*len == 0) {
- /* null length string found */
- cptr = NULL;
- } else if (*len > 0 && (str == NULL || (cptr = (u_char *)malloc(*len)) == NULL)) {
- return NULL;
- }
- *str = cptr;
- } else {
- cptr = *str;
- }
- /* copy data */
- for(i = 0; i < (int)*len; i++) {
- sscanf(readfrom,"%2x",&tmp);
- *cptr++ = (u_char) tmp;
- readfrom += 2;
- }
- readfrom = skip_white(readfrom);
- } else {
- /* Normal string */
- /* malloc data space if needed */
- if (*str == NULL) {
- char buf[SNMP_MAXBUF];
- readfrom = copy_word(readfrom, buf);
- *len = strlen(buf);
- /* malloc an extra space to add a null */
- if (*len > 0 && (str == NULL ||
- (cptr = (u_char *) malloc(*len + 1))
- == NULL))
- return NULL;
- *str = cptr;
- if (cptr)
- memcpy(cptr, buf, (*len+1));
- } else {
- readfrom = copy_word(readfrom, (char *)*str);
- }
- }
- return readfrom;
- }
- /* read_config_save_objid(): saves an objid as a numerical string */
- char *read_config_save_objid(char *saveto, oid *objid, size_t len) {
- int i;
- if (len == 0) {
- strcat(saveto, "NULL");
- saveto += strlen(saveto);
- return saveto;
- }
- /* in case len=0, this makes it easier to read it back in */
- for(i=0; i < (int)len; i++) {
- sprintf(saveto,".%ld", objid[i]);
- saveto += strlen(saveto);
- }
- return saveto;
- }
- /* read_config_read_objid(): reads an objid from a format saved by the above */
- char *read_config_read_objid(char *readfrom, oid **objid, size_t *len) {
- if (objid == NULL || readfrom == NULL)
- return NULL;
- if (*objid != NULL) {
- char buf[SPRINT_MAX_LEN];
- if (strncmp(readfrom,"NULL",4) == 0) {
- /* null length oid */
- *len = 0;
- } else {
- /* read_objid is touchy with trailing stuff */
- copy_word(readfrom, buf);
- /* read the oid into the buffer passed to us */
- if (!read_objid(buf, *objid, len)) {
- DEBUGMSGTL(("read_config_read_objid","Invalid OID"));
- return NULL;
- }
- }
- readfrom = skip_token(readfrom);
- } else {
- if (strncmp(readfrom,"NULL",4) == 0) {
- /* null length oid */
- *len = 0;
- readfrom = skip_token(readfrom);
- } else {
- /* space needs to be malloced. Call ourself recursively to figure
- out how long the oid actually is */
- oid obuf[MAX_OID_LEN];
- size_t obuflen = MAX_OID_LEN;
- oid *oidp = obuf;
- oid **oidpp = &oidp; /* done this way for odd, untrue, gcc warnings */
- readfrom = read_config_read_objid(readfrom, oidpp, &obuflen);
- /* Then malloc and copy the results */
- *len = obuflen;
- if (*len > 0 && (*objid = (oid*)malloc(*len * sizeof(oid))) == NULL)
- return NULL;
- if (obuflen > 0)
- memcpy(*objid, obuf, obuflen*sizeof(oid));
- }
- }
- return readfrom;
- }
- /* read_config_read_data():
- reads data of a given type from a token(s) on a configuration line.
- Returns: character pointer to the next token in the configuration line.
- NULL if none left.
- NULL if an unknown type.
- */
- char *read_config_read_data(int type, char *readfrom, void *dataptr, size_t *len) {
- int *intp;
- char **charpp;
- oid **oidpp;
- if (dataptr == NULL || readfrom == NULL)
- return NULL;
- switch(type) {
- case ASN_INTEGER:
- intp = (int *) dataptr;
- *intp = atoi(readfrom);
- readfrom = skip_token(readfrom);
- return readfrom;
- case ASN_OCTET_STR:
- charpp = (char **) dataptr;
- return read_config_read_octet_string(readfrom, (u_char **) charpp, len);
- case ASN_OBJECT_ID:
- oidpp = (oid **) dataptr;
- return read_config_read_objid(readfrom, oidpp, len);
- default:
- DEBUGMSGTL(("read_config_read_data","Fail: Unknown type: %d", type));
- return NULL;
- }
- return NULL;
- }
- /* read_config_read_data():
- reads data of a given type from a token(s) on a configuration line.
- Returns: character pointer to the next token in the configuration line.
- NULL if none left.
- NULL if an unknown type.
- */
- char *read_config_store_data(int type, char *storeto, void *dataptr, size_t *len) {
- int *intp;
- u_char **charpp;
- oid **oidpp;
- if (dataptr == NULL || storeto == NULL)
- return NULL;
- switch(type) {
- case ASN_INTEGER:
- intp = (int *) dataptr;
- sprintf(storeto," %d", *intp);
- return (storeto + strlen(storeto));
- case ASN_OCTET_STR:
- charpp = (u_char **) dataptr;
- return read_config_save_octet_string(storeto, *charpp, *len);
- case ASN_OBJECT_ID:
- oidpp = (oid **) dataptr;
- return read_config_save_objid(storeto, *oidpp, *len);
- default:
- DEBUGMSGTL(("read_config_store_data","Fail: Unknown type: %d", type));
- return NULL;
- }
- return NULL;
- }