void set_option(const std::string& opt, const T& val) { if (boost::is_convertible<T, std::string>::value) { set_option_str(opt, robust_cast<std::string>(val)); } else { options[opt].strval = robust_cast<std::string>(val); options[opt].intval = robust_cast<int>(val); options[opt].dblval = robust_cast<double>(val); options[opt].boolval = robust_cast<bool>(val); } }
/** Allow a config option to be added to rc_handle from inside a program * * @param rh a handle to parsed configuration. * @param option_name the name of the option. * @param option_val the value to be added. * @param source typically should be %__FILE__ or %__func__ for logging purposes. * @param line %__LINE__ for logging purposes. * @return 0 on success, -1 on failure. */ int rc_add_config(rc_handle *rh, char const *option_name, char const *option_val, char const *source, int line) { OPTION *option; if ((option = find_option(rh, option_name, OT_ANY)) == NULL) { rc_log(LOG_ERR, "ERROR: unrecognized option: %s", option_name); return -1; } if (option->status != ST_UNDEF) { rc_log(LOG_ERR, "ERROR: duplicate option: %s", option_name); return -1; } switch (option->type) { case OT_STR: if (set_option_str(source, line, option, option_val) < 0) { return -1; } break; case OT_INT: if (set_option_int(source, line, option, option_val) < 0) { return -1; } break; case OT_SRV: if (set_option_srv(source, line, option, option_val) < 0) { return -1; } break; case OT_AUO: if (set_option_auo(source, line, option, option_val) < 0) { return -1; } break; default: rc_log(LOG_CRIT, "rc_add_config: impossible case branch!"); abort(); } if (strcmp(option->name, "bindaddr") == 0) { memset(&rh->own_bind_addr, 0, sizeof(rh->own_bind_addr)); rh->own_bind_addr_set = 0; rc_own_bind_addr(rh, &rh->own_bind_addr); rh->own_bind_addr_set = 1; } return 0; }
/** * Parses an option stream of the form "a=b c=d ..." */ inline bool parse_options(std::istream& s) { options.clear(); std::string opt, value; // read till the equal while(s.good()) { getline(s, opt, '='); if (s.bad() || s.eof()) return false; getline(s, value, ' '); if (s.bad()) return false; set_option_str(trim(opt), trim(value)); } return true; }
int rc_add_config(rc_handle *rh, const char *option_name, const char *option_val, const char *source, const int line) { OPTION *option; if ((option = find_option(rh, option_name, OT_ANY)) == NULL) { rc_log(LOG_ERR, "ERROR: unrecognized option: %s", option_name); return -1; } if (option->status != ST_UNDEF) { rc_log(LOG_ERR, "ERROR: duplicate option: %s", option_name); return -1; } switch (option->type) { case OT_STR: if (set_option_str(source, line, option, option_val) < 0) { return -1; } break; case OT_INT: if (set_option_int(source, line, option, option_val) < 0) { return -1; } break; case OT_SRV: if (set_option_srv(source, line, option, option_val) < 0) { return -1; } break; case OT_AUO: if (set_option_auo(source, line, option, option_val) < 0) { return -1; } break; default: rc_log(LOG_CRIT, "rc_read_config: impossible case branch!"); abort(); } return 0; }
int rc_read_config(char *filename) { FILE *configfd; char buffer[512], *p; OPTION *option; int line, pos; if ((configfd = fopen(filename,"r")) == NULL) { errorlog("rc_read_config: can't open %s: %m", filename); return (-1); } line = 0; while ((fgets(buffer, sizeof(buffer), configfd) != NULL)) { line++; p = buffer; if ((*p == '\n') || (*p == '#') || (*p == '\0')) continue; p[strlen(p)-1] = '\0'; if ((pos = strcspn(p, "\t ")) == 0) { errorlog("%s: line %d: bogus format: %s", filename, line, p); return (-1); } p[pos] = '\0'; if ((option = find_option(p, OT_ANY)) == NULL) { errorlog("%s: line %d: unrecognized keyword: %s", filename, line, p); return (-1); } if (option->status != ST_UNDEF) { errorlog("%s: line %d: duplicate option line: %s", filename, line, p); return (-1); } p += pos+1; while (isspace(*p)) p++; switch (option->type) { case OT_STR: if (set_option_str(filename, line, option, p) < 0) return (-1); break; case OT_INT: if (set_option_int(filename, line, option, p) < 0) return (-1); break; case OT_SRV: if (set_option_srv(filename, line, option, p) < 0) return (-1); break; case OT_AUO: if (set_option_auo(filename, line, option, p) < 0) return (-1); break; default: fatallog("rc_read_config: impossible case branch!"); abort(); } } fclose(configfd); return test_config(filename); }
rc_handle * rc_read_config(const char *filename) { FILE *configfd; char buffer[512], *p; OPTION *option; int line; size_t pos; rc_handle *rh; rh = rc_new(); if (rh == NULL) return NULL; rh->config_options = malloc(sizeof(config_options_default)); if (rh->config_options == NULL) { rc_log(LOG_CRIT, "rc_read_config: out of memory"); rc_destroy(rh); return NULL; } memcpy(rh->config_options, &config_options_default, sizeof(config_options_default)); if ((configfd = fopen(filename,"r")) == NULL) { rc_log(LOG_ERR,"rc_read_config: can't open %s: %s", filename, strerror(errno)); rc_destroy(rh); return NULL; } line = 0; while ((fgets(buffer, sizeof(buffer), configfd) != NULL)) { line++; p = buffer; if ((*p == '\n') || (*p == '#') || (*p == '\0')) continue; p[strlen(p)-1] = '\0'; if ((pos = strcspn(p, "\t ")) == 0) { rc_log(LOG_ERR, "%s: line %d: bogus format: %s", filename, line, p); fclose(configfd); rc_destroy(rh); return NULL; } p[pos] = '\0'; if ((option = find_option(rh, p, OT_ANY)) == NULL) { rc_log(LOG_ERR, "%s: line %d: unrecognized keyword: %s", filename, line, p); fclose(configfd); rc_destroy(rh); return NULL; } if (option->status != ST_UNDEF) { rc_log(LOG_ERR, "%s: line %d: duplicate option line: %s", filename, line, p); fclose(configfd); rc_destroy(rh); return NULL; } p += pos+1; while (isspace(*p)) p++; pos = strlen(p) - 1; while(pos >= 0 && isspace(p[pos])) pos--; p[pos + 1] = '\0'; switch (option->type) { case OT_STR: if (set_option_str(filename, line, option, p) < 0) { fclose(configfd); rc_destroy(rh); return NULL; } break; case OT_INT: if (set_option_int(filename, line, option, p) < 0) { fclose(configfd); rc_destroy(rh); return NULL; } break; case OT_SRV: if (set_option_srv(filename, line, option, p) < 0) { fclose(configfd); rc_destroy(rh); return NULL; } break; case OT_AUO: if (set_option_auo(filename, line, option, p) < 0) { fclose(configfd); rc_destroy(rh); return NULL; } break; default: rc_log(LOG_CRIT, "rc_read_config: impossible case branch!"); abort(); } } fclose(configfd); if (test_config(rh, filename) == -1) { rc_destroy(rh); return NULL; } return rh; }
/** * This function parses command line options. It sets the options in this * order. It means that the value used for an option is the one set in the * lastest step. * 0) default values are set into the options_t * structure * 1) reads the default configuration file if any. * 2) reads the configuration file mentionned on the command line. * 3) sets the command line options (except for the list of directories, * all other values are replaced by thoses in the command line) * @param argc : number of arguments given on the command line. * @param argv : an array of strings that contains command line arguments. * @returns options_t structure malloc'ed and filled upon choosen command * line's option */ options_t *manage_command_line_options(int argc, char **argv) { options_t *opt = NULL; /** Structure to manage program's options */ gchar *summary = NULL; /** Abstract for the program */ gchar *defaultconfigfilename = NULL; gboolean version = FALSE; /** True if -v was selected on the command line */ gint debug = -4; /** 0 == FALSE and other values == TRUE */ gint adaptive = -1; /** 0 == FALSE and other positive values == TRUE */ gchar **dirname_array = NULL; /** array of dirnames left on the command line */ gchar **exclude_array = NULL; /** array of dirnames and filenames to be excluded */ gchar *configfile = NULL; /** filename for the configuration file if any */ gint64 blocksize = 0; /** computed block size in bytes */ gint buffersize = 0; /** buffer size used to send data to server */ gchar *dircache = NULL; /** Directory used to store cache files */ gchar *dbname = NULL; /** Database filename where data and meta data are cached */ gchar *ip = NULL; /** IP address where is located server's program */ gint port = 0; /** Port number on which to send things to the server */ gshort cmptype = -1; /** compression type to be used when communicating */ gboolean noscan = FALSE; /** If set to TRUE then do not do the first directory scan */ srv_conf_t *srv_conf = NULL; GOptionEntry entries[] = { { "version", 'v', 0, G_OPTION_ARG_NONE, &version, N_("Prints program version"), NULL }, { "debug", 'd', 0, G_OPTION_ARG_INT, &debug, N_("Activates (1) or desactivates (0) debug mode."), N_("BOOLEAN")}, { "configuration", 'c', 0, G_OPTION_ARG_STRING, &configfile, N_("Specify an alternative configuration file."), N_("FILENAME")}, { "blocksize", 'b', 0, G_OPTION_ARG_INT64, &blocksize, N_("Fixed block SIZE used to compute hashs."), N_("SIZE")}, { "adaptive", 'a', 0, G_OPTION_ARG_INT, &adaptive, N_("Adapative block size used to compute hashs."), N_("BOOLEAN")}, { "buffersize", 's', 0, G_OPTION_ARG_INT, &buffersize, N_("SIZE of the cache used to send data to server."), N_("SIZE")}, { "dircache", 'r', 0, G_OPTION_ARG_STRING, &dircache, N_("Directory DIRNAME where to cache files."), N_("DIRNAME")}, { "dbname", 'f', 0, G_OPTION_ARG_STRING, &dbname, N_("Database FILENAME."), N_("FILENAME")}, { "ip", 'i', 0, G_OPTION_ARG_STRING, &ip, N_("IP address where server program is."), "IP"}, { "port", 'p', 0, G_OPTION_ARG_INT, &port, N_("Port NUMBER on which to listen."), N_("NUMBER")}, { "exclude", 'x', 0, G_OPTION_ARG_FILENAME_ARRAY, &exclude_array, N_("Exclude FILENAME from being saved."), N_("FILENAME")}, { "no-scan", 'n', 0, G_OPTION_ARG_NONE, &noscan, N_("Does not do the first directory scan."), NULL}, { "compression", 'z', 0, G_OPTION_ARG_INT, &cmptype, N_("Compression type to use: 0 is NONE, 1 is ZLIB"), N_("NUMBER")}, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &dirname_array, "", NULL}, { NULL } }; summary = g_strdup(_("This program is monitoring file changes in the filesystem and is hashing\nfiles with SHA256 algorithms from Glib.")); parse_command_line(argc, argv, entries, summary); set_debug_mode(ENABLE_DEBUG); /* 0) Setting default values */ opt = (options_t *) g_malloc0(sizeof(options_t)); opt->dirname_list = NULL; opt->exclude_list = NULL; opt->blocksize = CLIENT_BLOCK_SIZE; opt->configfile = NULL; opt->dircache = g_strdup("/var/tmp/cdpfgl"); opt->dbname = g_strdup("filecache.db"); opt->buffersize = -1; opt->adaptive = FALSE; opt->cmptype = 0; opt->srv_conf = NULL; srv_conf = new_srv_conf_t(); srv_conf->ip = g_strdup("localhost"); srv_conf->port = SERVER_PORT; /* 1) Reading options from default configuration file */ defaultconfigfilename = get_probable_etc_path(PROGRAM_NAME, "client.conf"); read_from_configuration_file(opt, defaultconfigfilename); free_variable(defaultconfigfilename); opt->version = version; /* only TRUE if -v or --version was invoked */ opt->noscan = noscan; /* only TRUE if -n or --no-scan was invoked */ /* 2) Reading the configuration from the configuration file specified * on the command line (if any). */ if (configfile != NULL) { read_from_configuration_file(opt, configfile); } if (opt->srv_conf != NULL) { free_srv_conf_t(srv_conf); srv_conf = NULL; } else { opt->srv_conf = srv_conf; } /* 3) retrieving other options from the command line. Directories are * added to the existing directory list and then the array is freed * as every string has been copied with g_strdup(). */ set_debug_mode_upon_cmdl(debug); opt->dirname_list = convert_gchar_array_to_GSList(dirname_array, opt->dirname_list); opt->exclude_list = convert_gchar_array_to_GSList(exclude_array, opt->exclude_list); if (cmptype >= 0) { set_compression_type(opt, cmptype); } g_strfreev(dirname_array); g_strfreev(exclude_array); if (blocksize > 0) { opt->blocksize = blocksize; } opt->dircache = set_option_str(dircache, opt->dircache); opt->dbname = set_option_str(dbname, opt->dbname); if (opt->srv_conf != NULL) { opt->srv_conf->ip = set_option_str(ip, opt->srv_conf->ip); if (port > 1024 && port < 65535) { opt->srv_conf->port = port; } } if (adaptive > 0) { opt->adaptive = TRUE; } else if (adaptive == 0) { opt->adaptive = FALSE; } if (buffersize > 0) { opt->buffersize = buffersize; } else if (opt->buffersize <= 0) { opt->buffersize = CLIENT_MIN_BUFFER; } free_variable(ip); free_variable(dbname); free_variable(dircache); free_variable(summary); return opt; }