/** * Reads keys in keyfile if group GN_CLIENT is in that keyfile and fills * options_t *opt structure accordingly. * @param[in,out] opt : options_t * structure to store options read from the * configuration file "filename". * @param keyfile is the GKeyFile structure that is used by glib to read * groups and keys from. * @param filename : the filename of the configuration file to read from */ static void read_from_group_client(options_t *opt, GKeyFile *keyfile, gchar *filename) { gchar *dircache = NULL; gint cmptype = 0; if (keyfile != NULL && filename != NULL && g_key_file_has_group(keyfile, GN_CLIENT) == TRUE) { /* Reading the directory list */ opt->dirname_list = read_list_from_file(keyfile, filename, GN_CLIENT, KN_DIR_LIST, _("Could not load directory list from file")); opt->exclude_list = read_list_from_file(keyfile, filename, GN_CLIENT, KN_EXC_LIST, _("Could not load exclude file list from file")); /* Reading blocksize */ opt->blocksize = read_int64_from_file(keyfile, filename, GN_CLIENT, KN_BLOCK_SIZE, _("Could not load blocksize from file"), CLIENT_BLOCK_SIZE); /* Reading the cache directory if any */ dircache = read_string_from_file(keyfile, filename, GN_CLIENT, KN_CACHE_DIR, _("Could not load directory name")); opt->dircache = normalize_directory(dircache); free_variable(dircache); /* Reading filename of the database if any */ opt->dbname = read_string_from_file(keyfile, filename, GN_CLIENT, KN_DB_NAME, _("Could not load cache database name")); /* Adaptative mode for blocksize ? */ opt->adaptive = read_boolean_from_file(keyfile, filename, GN_CLIENT, KN_ADAPTIVE, _("Could not load adaptive configuration from file.")); /* Scanning option */ opt->noscan = read_boolean_from_file(keyfile, filename, GN_CLIENT, KN_NOSCAN, _("Could not load scan configuration from file.")); /* Buffer size to be used to send data to server */ opt->buffersize = read_int_from_file(keyfile, filename, GN_CLIENT, KN_BUFFER_SIZE, _("Could not load buffersize from file"), CLIENT_MIN_BUFFER); /* Compression type if any */ cmptype = read_int_from_file(keyfile, filename, GN_CLIENT, KN_COMPRESSION_TYPE, _("Compression type not defined in configuration file"), opt->cmptype); set_compression_type(opt, cmptype); } }
/** * 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; }
static int parse(int *argc, char *argv[]) { int hasbs; //backstore int hastype; // algorithm type int success; int opt; char* ag; char **newargv; int newargc; int skipnext; char pwd[256]; pthread_mutexattr_t mattr; cinfo.bs_path = NULL; hasbs = hastype = 0; success = 1; newargv = (char**)malloc(sizeof(char*)**argc); newargc = 1; // disable getopt errors opterr = 0; // getopt changes argv order, let's save it for (opt = 0; opt < *argc; opt++) newargv[opt] = argv[opt]; while ( success && (opt = getopt(*argc, argv, "b:t:") ) != -1) { switch (opt) { // backstore path case 'b': hasbs = 1; if (optarg[0] == '/') { pwd[0] = '\0'; } else { getcwd(pwd, 256); strcat(pwd, "/"); } cinfo.bs_len = strlen(optarg) + strlen(pwd); cinfo.bs_path = (char*)malloc(sizeof(char)*cinfo.bs_len); strcpy(cinfo.bs_path, pwd); strcat(cinfo.bs_path, optarg); break; case 't': hastype = 1; success = set_compression_type(optarg); break; default: // maybe fuse parameters break; } } if (!hastype) { fprintf(stderr, "Using default compression type (%s).\n", DEFAULT_COMPRESSION); success = set_compression_type(DEFAULT_COMPRESSION); } if (!hasbs) { fprintf(stderr, "Must inform back store path.\n"); success = 0; } if (success) { // getopt has changed argv order, let's restore it for (opt = 0; opt < *argc; opt++) argv[opt] = newargv[opt]; skipnext = 0; // getopt is for shot options only, let's copy all other args for (opt = 1; opt < *argc; opt++) { if (skipnext) { skipnext = 0; continue; } ag = argv[opt]; // choose whether or not to skip this arg switch (strlen(ag)) { case 0: continue; case 1: if (ag[0] == '-') continue; break; default: // >= 2 if (ag[0] == '-' && ( ag[1] == 'b' || ag[1] == 't') ) { skipnext = 1; continue; } break; } // copy newargv[newargc++] = argv[opt]; } // copy back to the pointer *argc = newargc; for (opt = 0; opt < newargc; opt++) argv[opt] = newargv[opt]; free(newargv); // init recursive lock pthread_mutexattr_init(&mattr); pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE_NP); pthread_mutex_init(&cinfo.lock, &mattr); pthread_mutex_init(&cinfo.open_lock, &mattr); pthread_mutexattr_destroy(&mattr); cinfo.ftable = (struct cfile*)malloc(sizeof(struct cfile)); cinfo.ftable->next = NULL; cinfo.ftable->path[0] = '\0'; } else { // undo what is needed if (cinfo.bs_path) free(cinfo.bs_path); print_usage(); } return success; }