Platon Technologies
not logged in Login Registration
EnglishSlovak
open source software development celebrating 10 years of open source development! Friday, October 16, 2026

Diff for ep/src/conf.c between version 1.8 and 1.9

version 1.8, 2002/02/17 15:18:44 version 1.9, 2002/02/18 21:34:55
Line 16 
Line 16 
 #include "message.h"  #include "message.h"
 #include "cfglocal.h"  #include "cfglocal.h"
   
 static char *name_vs_stream_separator[2] = {".", NULL};  /*
    * Global variables
 /* static */ struct conf_struct_global globalcfg;   */
 static struct conf_struct_process processcfg;  
   char *conf_global_filename = "/etc/ep.conf";
 static struct cfg_option options_global[] = {  char *conf_user_filename = ".ep.conf";
         {"verbose", 'v', "verbose",  
                 CFG_BOOLEAN + CFG_MULTI, (void *) &(globalcfg.verbose), 0},  /*
                 CFG_END_OF_LIST   * Static variables
    */
   static char *section_boundaries[2] = {"[", "]"};
   /* static char *name_vs_stream_separator[4] = {".", "..", "-", NULL}; */
   static char *global_str = "Global";
   static char *process_str = "Process";
   
   
   /* struct conf_struct_global cfg; */
   
   /*
    * Options structures
    */
   
   static struct conf_struct_global global_cfg;
   static struct conf_struct_process process_cfg;
   
   /*
    * Options contexts
    */
   
   static CFG_CONTEXT global_context = NULL;
   static CFG_CONTEXT process_context = NULL;
   
   /*
    * Global options
    */
   
   static struct cfg_option global_options[] = {
           {"verbose", 'v', "verbose", CFG_BOOLEAN + CFG_MULTI, (void *) &(global_cfg.verbose), 0},
           {NULL, 'f', NULL, CFG_STRING + CFG_MULTI, (void *) &(global_cfg.config_file), 0},
           {"disable-global-config",'\0',NULL,CFG_BOOLEAN,(void*)&(global_cfg.disable_global_config),0},
           {"disable-user-config",'\0',NULL,CFG_BOOLEAN,(void*)&(global_cfg.disable_user_config),0},
           CFG_END_OF_LIST
 };  };
   
 static struct cfg_option options_process[] = {  /*
         {"nice", 'N', "nice", CFG_INT, (void *) &(processcfg.nice), 0},   * Process options
         { "name", 'n', "name", CFG_STRING+CFG_MULTI_SEPARATED, (void *) &(processcfg.name), 0 },   */
         {"input", 'i', "input", CFG_STRING+CFG_MULTI_SEPARATED, (void *) &(processcfg.fd[0]), 0},  
         {"output", 'o', "output", CFG_STRING+CFG_MULTI_SEPARATED, (void *) &(processcfg.fd[1]), 0},  static struct cfg_option process_options[] = {
         {"errput", 'e', "errput", CFG_STRING+CFG_MULTI_SEPARATED, (void *) &(processcfg.fd[2]), 0},          {"nice", 'N', "nice", CFG_INT, (void *) &(process_cfg.nice), 0},
         {NULL, '\0', NULL, CFG_LEFTOVER_ARGS+CFG_STRING+CFG_MULTI, (void *) &(processcfg.argv), 0},          {"name", 'n', "name", CFG_STRING+CFG_MULTI_SEPARATED, (void *) &(process_cfg.name), 0},
           {"input", 'i', "input", CFG_STRING+CFG_MULTI_SEPARATED, (void *) &(process_cfg.fd[0]), 0},
           {"output", 'o', "output", CFG_STRING+CFG_MULTI_SEPARATED, (void *) &(process_cfg.fd[1]), 0},
           {"errput", 'e', "errput", CFG_STRING+CFG_MULTI_SEPARATED, (void *) &(process_cfg.fd[2]), 0},
           {NULL, '\0', NULL, CFG_LEFTOVER_ARGS+CFG_STRING+CFG_MULTI, (void *) &(process_cfg.argv), 0},
         CFG_END_OF_LIST          CFG_END_OF_LIST
 };  };
   
   /*
    * Static function declarations
    */
   
   static char *get_user_config_filename(void);
   static void global_cfg_clear(void);
   static void process_cfg_clear(void);
   static int check_global_context(void);
   static int check_process_context(void);
   static int check_context(CFG_CONTEXT *context, struct cfg_option options[]);
   static int is_cfgfile_section(char *section_str);
   static int add_global_cfg_to_global(struct conf_struct_global **global);
   static int add_process_cfg_to_processes(
                   struct conf_struct_process ***processes,
                   int *size);
   static int add_processes_to_processes(
                   struct conf_struct_process ***dest_processes,
                   struct conf_struct_process **src_processes);
   
   /*
    * Function definitions
    */
   
   PROCTABLE conf_parse_all(int argc, char **argv)
   {
   
           register int ret, i;
           struct conf_struct_global *global;
           struct conf_struct_global *global_work;
           struct conf_struct_process **processes;
           struct conf_struct_process **processes_work;
   
           ret = conf_cmdline_parse(argc - 1, argv + 1, &global, &processes);
   
           if (ret != CFG_OK) {
                   msg_error_print("command line parsing error %d\n", ret);
                   /* TODO: free structures */
                   return NULL;
           }
   
           for (i = 0; i < 2 || (global->config_file != NULL
                                   && global->config_file[i - 2] != NULL); i++) {
   
                   if (i >= 2
                                   || (i == 0 && ! global->disable_global_config)
                                   || (i == 1 && ! global->disable_user_config))
                   {
                           register char *filename = i <= 0 ? conf_global_filename : i == 1
                                   ? get_user_config_filename() : global->config_file[i - 2];
   
                           if (/* i == 1 && */ filename == NULL) {
                                   msg_error_print("not enough memory\n");
                                   /* TODO: free structures */
                                   return NULL;
                           }
   
   #ifdef DEBUG
                           msg_debug_print("conf_parse_all(): parsing '%s'\n", filename);
   #endif
   
                           ret = conf_cfgfile_parse(filename, &global_work, &processes_work);
   
                           /* TODO: Progressive config file type reporting in error messages.
                              There are three types: global, local/user, user defined. */
   
                           if (ret != CFG_OK && (i >= 2
                                                   || (i < 2 && ret != CFG_ERR_FILE_NOT_FOUND))) {
                                   msg_error_print("config file '%s' parsing error %d\n",
                                                   filename, ret);
                                   /* TODO: free structures */
                                   return NULL;
                           }
   
                           if (! add_processes_to_processes(&processes, processes_work)) {
                                   msg_error_print("not enough memory for config file '%s'"
                                                   "process table merging\n", filename);
                                   /* TODO: free structures */
                                   return NULL;
                           }
   
                           if (i == 1)
                                   free(filename);
   
                           free(global_work);
                   }
           }
   
   #if DEBUG
           {
                   register int i;
   
                   msg_debug_print("conf_parse_all(): ret = %d\n", ret);
   
                   msg_debug_print("verbose = %d\n", global->verbose);
   
                   for (i = 0; processes != NULL && processes[i] != NULL; i++) {
                           msg_debug_print("[%d] %s, %d\n", i,
                                           processes[i]->name != NULL ? processes[i]->name[0] : "NULL",
                                           processes[i]->nice);
                   }
           }
   #endif
   
           return NULL;
   }
   
   int conf_cfgfile_parse(
                   char *filename,
                   struct conf_struct_global **global,
                   struct conf_struct_process ***processes)
   {
           register int ret;
           int processes_size;
           CFG_CONTEXT cur_context;
   
           *processes = NULL;
           processes_size = 0;
   
           if (check_global_context() < 0 || check_process_context() < 0)
                   return CFG_ERR_NOMEM;
   
           global_cfg_clear();
           process_cfg_clear();
   
           cfg_set_cfgfile_context(global_context, 0, 0, filename);
           cfg_set_cfgfile_context(process_context, 0, 0, filename);
   
           for (cur_context = global_context; ; ) {
   
                   ret = cfg_parse(cur_context);
   
                   if (ret != CFG_ERR_STOP_STR) {
   #if DEBUG
                           msg_debug_print("detected %s error %d in <%s>\n",
                                           cur_context == process_context ? "process" : "global",
                                           ret, cfg_get_cur_opt(cur_context));
   #endif
                           break;
                   }
                   else {
                           int sec_no;
                           char *section_str;
   
                           section_str = cfg_get_cur_opt(cur_context);
                           sec_no = is_cfgfile_section(section_str);
   
                           if (sec_no > 0) {
                                   if (cur_context == process_context) {
                                           if (! add_process_cfg_to_processes(processes,
                                                                   &processes_size))
                                                   return CFG_ERR_NOMEM;
   
                                           process_cfg_clear();
                                   }
   
                                   if (sec_no == 1) { /* [Global] section */
                                           cfg_set_cfgfile_context(global_context,
                                                           cfg_get_cur_idx(cur_context), 0, NULL);
                                           cur_context = global_context;
                                   }
                                   else { /* [Process] section */
                                           cfg_set_cfgfile_context(process_context,
                                                           cfg_get_cur_idx(cur_context), 0, NULL);
                                           cur_context = process_context;
                                   }
                           }
                           else {
                                   msg_error_print("unknown section '%s' in config file '%s'\n",
                                                   section_str, filename);
                                   ret = CFG_ERROR_UNKNOWN;
                                   break;
                           }
                   }
           }
   
           /* Set returning parameters. */
           if ((cur_context == process_context &&
                                   ! add_process_cfg_to_processes(processes, &processes_size))
                           || ! add_global_cfg_to_global(global))
                   return CFG_ERR_NOMEM;
   
           return ret;
   }
   
   int conf_cmdline_parse(
                   int argc, char **argv,
                   struct conf_struct_global **global,
                   struct conf_struct_process ***processes)
   {
           register int ret = CFG_OK, first_loop, index;
           int processes_size;
           CFG_CONTEXT cur_context;
   
           *processes = NULL;
           processes_size = 0;
   
           if (check_global_context() < 0 || check_process_context() < 0)
                   return CFG_ERR_NOMEM;
   
           global_cfg_clear();
           process_cfg_clear();
   
           cfg_set_cmdline_context(global_context, argc, argv);
           cfg_set_cmdline_context(process_context, argc, argv);
   
           /*
            * Yokotasi intelligent parser. :-)
            */
   
           for (cur_context = process_context, first_loop = 1, index = 0;
                           index < argc; first_loop = 0) {
   
                   ret = cfg_parse(cur_context);
   
                   if (ret < 0 && ret != CFG_ERR_STOP_STR_FOUND) {
                           if (! first_loop) {
                                   /* TODO: better specification about error on command line */
                                   msg_error_print("error on command line (error %d at %s)\n",
                                                   ret, argv[index + cfg_get_cur_idx(cur_context)]);
   
                                   break;
                           }
   
                           cur_context = global_context;
                           /* not needed: cfg_set_cmdline_context(cur_context, argc, argv); */
                           continue;
                   }
                   else if (ret == CFG_ERR_STOP_STR_FOUND) {
                           if (cfg_get_cur_idx(cur_context) < 1) {
                                   if (! first_loop) {
                                           msg_error_print("misplaced process separator '--'\n");
   
                                           break;
                                   }
                           }
   
                           if (cur_context == process_context) {
                                   if (! add_process_cfg_to_processes(processes,
                                                           &processes_size))
                                           return CFG_ERR_NOMEM;
   
                                   process_cfg_clear();
                           }
   
                           index += cfg_get_cur_idx(cur_context) + 1;
                           cur_context = process_context;
                           cfg_set_cmdline_context(cur_context, argc - index, argv + index);
                   }
                   else
                           break;
           }
   
           /* Set returning parameters. */
           if ((cur_context == process_context && index > 0 && ret == CFG_OK &&
                                   ! add_process_cfg_to_processes(processes, &processes_size))
                           || ! add_global_cfg_to_global(global))
                   return CFG_ERR_NOMEM;
   
           return ret;
   }
   
   /*
    * Static function definitions
    */
   
   static char *get_user_config_filename(void)
   {
           register char *homedir, *filename;
   
           if ((homedir = getenv("HOME")) == NULL)
                   return strdup(conf_user_filename);
   
           filename = (char *) malloc((strlen(homedir)
                                   + strlen(conf_user_filename) + 2) * sizeof(char));
           if (filename == NULL)
                   return NULL;
   
           strcpy(filename, homedir);
           if (strlen(filename) > 0 && filename[strlen(filename) - 1] != '/')
                   strcpy(filename + strlen(filename), "/");
   
           strcpy(filename + strlen(filename), conf_user_filename);
   
           return filename;
   }
   
   static void global_cfg_clear(void)
   {
           memset((void *) &global_cfg, '\0',
                           sizeof(struct conf_struct_global));
   }
   
   static void process_cfg_clear(void)
   {
           memset((void *) &process_cfg, '\0',
                           sizeof(struct conf_struct_process));
   }
   
   static int check_global_context(void)
   {
           return check_context(&global_context, global_options);
   }
   
   static int check_process_context(void)
   {
           return check_context(&process_context, process_options);
   }
   
   static int check_context(CFG_CONTEXT *context, struct cfg_option options[])
   {
           if (*context == NULL) {
                   if ((*context = cfg_get_context(options)) == NULL)
                           return -1;
   
                   cfg_set_context_flags(*context, CFG_PROCESS_FIRST);
                   cfg_clear_cmdline_stop_string(*context);
                   cfg_clear_cmdline_multi_vals_separator(*context);
                   cfg_clear_cfgfile_stop_prefix(*context);
   
                   if (! cfg_add_cmdline_stop_string(*context, "--")
                                   || ! cfg_add_cmdline_multi_vals_separator(*context, ",")
                                   || ! cfg_add_cfgfile_stop_prefix(*context,
                                           section_boundaries[0]))
                           return -1;
           }
   
           cfg_reset_context(*context);
   
           return 0;
   }
   
   static int is_cfgfile_section(char *section_str)
   {
           register int secstr_size = strlen(section_str);
           register int secb0_size = strlen(section_boundaries[0]);
           register int secb1_size = strlen(section_boundaries[1]);
   
           register int ret = 0;
   
           if (secstr_size > secb0_size + secb1_size
                           && ! strncmp(section_str, section_boundaries[0], secb0_size)
                           && ! strncmp(section_str + secstr_size - secb1_size,
                                   section_boundaries[1], secb1_size))
           {
                   register char *pos = section_str + secb0_size;
   
                   while (isspace(*pos))
                           pos++;
   
                   if (! strncasecmp(global_str, pos, strlen(global_str))) {
                           pos += strlen(global_str);
                           ret = 1;
                   }
                   else if (! strncasecmp(process_str, pos, strlen(process_str))) {
                           pos += strlen(process_str);
                           ret = 2;
                   }
   
                   while (ret > 0 && pos < section_str + secstr_size - secb1_size)
                           if (isspace(*pos))
                                   pos++;
                           else
                                   ret = 0;
           }
   
           return ret;
   }
   
   static int add_global_cfg_to_global(struct conf_struct_global **global)
   {
           *global = (struct conf_struct_global *)
                   malloc(sizeof(struct conf_struct_global));
           if (*global == NULL)
                   return 0;
   
           **global = global_cfg;
   
           return 1;
   }
   
   static int add_process_cfg_to_processes(
                   struct conf_struct_process ***processes,
                   int *size)
   {
           register int items;
   
           for (items = 0; *processes != NULL && (*processes)[items] != NULL; items++)
                   ;
   
           if (items + 1 >= *size) {
   
   #if DEBUG /* minimum increment value is 2 */
                   *size += 2;
   #else
                   *size += 10;
   #endif
                   *processes = (struct conf_struct_process **)
                           realloc(*processes, sizeof(struct conf_struct_process*) * (*size));
   
                   if (*processes == NULL)
                           return 0;
           }
   
           (*processes)[items] = (struct conf_struct_process *)
                   malloc(sizeof(struct conf_struct_process));
           if ((*processes)[items] == NULL)
                   return 0;
   
           *((*processes)[items]) = process_cfg;
           (*processes)[items + 1] = NULL;
   
           return 1;
   }
   
   static int add_processes_to_processes(
                   struct conf_struct_process ***dest_processes,
                   struct conf_struct_process **src_processes)
   {
           register int i, dest_size, src_size;
   
           if (dest_processes == NULL)
                   return 0;
   
           for (i = 0; *dest_processes != NULL && (*dest_processes)[i] != NULL; i++)
                   ;
           dest_size = i;
   
           for (i = 0; src_processes != NULL && src_processes[i] != NULL; i++)
                   ;
           src_size = i;
   
           *dest_processes = (struct conf_struct_process **) realloc(*dest_processes,
                           sizeof(struct conf_struct_process*) * (dest_size + src_size + 1));
           if (*dest_processes == NULL)
                   return 0;
   
           for (i = 0; i < src_size; i++)
                   (*dest_processes)[dest_size + i] = src_processes[i];
   
           (*dest_processes)[dest_size + src_size] = NULL;
   
           return 1;
   }
   
   #if 0
   
 static PROCTABLE proc_ar_to_proctable(int n_proc_ar,  static PROCTABLE proc_ar_to_proctable(int n_proc_ar,
                 struct conf_struct_process *proc_ar);                  struct conf_struct_process *proc_ar);
 static int conf_cmdline_parse_process(int argc, char **argv, int silent);  static int conf_cmdline_parse_process(int argc, char **argv, int silent);
Line 84  PROCTABLE conf_process(int argc, char **
Line 567  PROCTABLE conf_process(int argc, char **
         proc_ar = NULL;          proc_ar = NULL;
         ptbl = NULL;          ptbl = NULL;
   
         memset((void *) &globalcfg, '\0',          memset((void *) &global_cfg, '\0',
                         sizeof(struct conf_struct_global));                          sizeof(struct conf_struct_global));
   
         for (first_loop = 1; idx != 0 && index < argc; first_loop = 0) {          for (first_loop = 1; idx != 0 && index < argc; first_loop = 0) {
Line 119  PROCTABLE conf_process(int argc, char **
Line 602  PROCTABLE conf_process(int argc, char **
                 }                  }
   
                 /* TODO: which process on command line? */                  /* TODO: which process on command line? */
                 if (processcfg.argv == NULL) {                  if (process_cfg.argv == NULL) {
                         msg_error_print("one of process doesn't have specified"                          msg_error_print("one of process doesn't have specified"
                                         " what to run\n");                                          " what to run\n");
                         if (proc_ar != NULL)                          if (proc_ar != NULL)
Line 135  PROCTABLE conf_process(int argc, char **
Line 618  PROCTABLE conf_process(int argc, char **
                         return NULL;                          return NULL;
                 }                  }
   
                 proc_ar[n_proc_ar] = processcfg;                  proc_ar[n_proc_ar] = process_cfg;
                 n_proc_ar++;                  n_proc_ar++;
   
                 index += idx + 1;                  index += idx + 1;
Line 263  static PROCTABLE proc_ar_to_proctable(in
Line 746  static PROCTABLE proc_ar_to_proctable(in
         return ptbl;          return ptbl;
 }  }
   
 static int conf_cmdline_parse_process(int argc, char **argv, int silent)  static int conf_cmdline_parse_global(int argc, char **argv)
 {  {
         struct cfg_context *con;          struct cfg_context *con;
         register int ret;          register int ret;
   
         /* Clearing all properties. Some of them need to be set to NULL,          con = cfg_get_cmdline_context(argc, argv, global_options);
          * because of valid handling of string multi lists.  
          */  
         memset((void *) &processcfg, '\0', sizeof(struct conf_struct_process));  
   
         con = cfg_get_cmdline_context(argc, argv, options_process);  
         if (con == NULL) {          if (con == NULL) {
                 msg_error_print("not enough memory for command line parsing"                  msg_error_print("not enough memory for command line parsing"
                                 " process options");                                  " global options\n");
                 return CFG_ERROR_NOMEM;                  return CFG_ERROR_NOMEM;
         }          }
   
Line 289  static int conf_cmdline_parse_process(in
Line 767  static int conf_cmdline_parse_process(in
         ret = cfg_parse(con);          ret = cfg_parse(con);
   
         if (ret < 0 && ret != CFG_ERR_STOP_STR_FOUND) {          if (ret < 0 && ret != CFG_ERR_STOP_STR_FOUND) {
                 if (! silent)                  msg_error_print("error on command line in global options"
                         /* TODO: better specification about error on command line */                                  " (error %d at %s)\n", ret, argv[cfg_get_cur_idx(con)]);
                         msg_error_print("error on command line (error %d at %s)\n",  
                                         ret, argv[cfg_get_cur_idx(con)]);  
   
                 cfg_free_context(con);                  cfg_free_context(con);
                 return ret;                  return ret;
         }          }
   
         if (cfg_get_cur_idx(con) == 0 && ret == CFG_ERR_STOP_STR_FOUND) {          if (cfg_get_cur_idx(con) == 0) {
                 if (! silent)                  msg_error_print("misplaced process separator '--'\n");
                         msg_error_print("misplaced process separator '--'\n");  
   
                 cfg_free_context(con);                  cfg_free_context(con);
                 return CFG_ERROR_STOP_STR;                  return CFG_ERROR_STOP_STR;
Line 316  static int conf_cmdline_parse_process(in
Line 791  static int conf_cmdline_parse_process(in
         return ret;          return ret;
 }  }
   
 static int conf_cmdline_parse_global(int argc, char **argv)  static int conf_cmdline_parse_process(int argc, char **argv, int silent)
 {  {
         struct cfg_context *con;          struct cfg_context *con;
         register int ret;          register int ret;
   
         con = cfg_get_cmdline_context(argc, argv, options_global);          /* Clearing all properties. Some of them need to be set to NULL,
            * because of valid handling of string multi lists.
            */
           memset((void *) &process_cfg, '\0', sizeof(struct conf_struct_process));
   
           con = cfg_get_cmdline_context(argc, argv, process_options);
         if (con == NULL) {          if (con == NULL) {
                 msg_error_print("not enough memory for command line parsing"                  msg_error_print("not enough memory for command line parsing"
                                 " global options\n");                                  " process options");
                 return CFG_ERROR_NOMEM;                  return CFG_ERROR_NOMEM;
         }          }
   
Line 337  static int conf_cmdline_parse_global(int
Line 817  static int conf_cmdline_parse_global(int
         ret = cfg_parse(con);          ret = cfg_parse(con);
   
         if (ret < 0 && ret != CFG_ERR_STOP_STR_FOUND) {          if (ret < 0 && ret != CFG_ERR_STOP_STR_FOUND) {
                 msg_error_print("error on command line in global options"                  if (! silent)
                                 " (error %d at %s)\n", ret, argv[cfg_get_cur_idx(con)]);                          /* TODO: better specification about error on command line */
                           msg_error_print("error on command line (error %d at %s)\n",
                                           ret, argv[cfg_get_cur_idx(con)]);
   
                 cfg_free_context(con);                  cfg_free_context(con);
                 return ret;                  return ret;
         }          }
   
         if (cfg_get_cur_idx(con) == 0) {          if (cfg_get_cur_idx(con) == 0 && ret == CFG_ERR_STOP_STR_FOUND) {
                 msg_error_print("misplaced process separator '--'\n");                  if (! silent)
                           msg_error_print("misplaced process separator '--'\n");
   
                 cfg_free_context(con);                  cfg_free_context(con);
                 return CFG_ERROR_STOP_STR;                  return CFG_ERROR_STOP_STR;
Line 361  static int conf_cmdline_parse_global(int
Line 844  static int conf_cmdline_parse_global(int
         return ret;          return ret;
 }  }
   
   #endif /* #if 0 */
   

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

Platon Group <platon@platon.org> http://platon.org/
Copyright © 2002-2006 Platon Group
Site powered by Metafox CMS
Go to Top