read_config.c
来自「eCos操作系统源码」· C语言 代码 · 共 1,133 行 · 第 1/3 页
C
1,133 行
* 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() */voidfree_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))();}voidread_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);}voidread_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. */voidread_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. * */voidread_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() */voidread_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. * */voidsnmp_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 + =
减小字号Ctrl + -
显示快捷键?