📄 read_config.c
字号:
* 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 CYGPKG_SNMPLIB_FILESYSTEM_SUPPORT
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: %s\n", filename, strerror(errno)));
} else
#endif /* ENOENT */
#ifdef EACCES
if (errno == EACCES) {
DEBUGMSGTL(("read_config", "%s: %s\n", 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 %s\n", 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: %s\n",
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);
#endif
return;
} /* 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))();
}
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 tokens\n"));
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);
}
void
read_premib_configs (void)
{
DEBUGMSGTL(("read_config","reading premib configuration tokens\n"));
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 CYGPKG_SNMPLIB_FILESYSTEM_SUPPORT
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:%s\n", 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.
*/
#ifdef CYGPKG_SNMPLIB_PERSISTENT_FILESYSTEM
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, parsing\n", configfile));
read_config (configfile, ltmp, when);
}
}
}
#endif
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);
}
#ifdef CYGPKG_SNMPLIB_PERSISTENT_FILESYSTEM
if (config_errors) {
snmp_log(LOG_ERR, "ucd-snmp: %d errors in config file\n", config_errors);
/* exit(1); */
}
#endif
#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 %s\n", 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 CYGPKG_SNMPLIB_PERSISTENT_FILESYSTEM
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 %s\n",
file);
}
if ((fout = fopen(filep, "a")) != NULL) {
fprintf(fout,line);
if (line[strlen(line)] != '\n')
fprintf(fout,"\n");
DEBUGMSGTL(("read_config","storing: %s\n",line));
fclose(fout);
} else {
DEBUGMSGTL(("read_config","open failure"));
}
#ifdef PERSISTENT_MASK
umask(oldmask);
#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)
{
#ifndef ECOSFIXME_NEEDFILESYSTEM
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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -