/** * 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; }
/** * 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 */ static options_t *manage_command_line_options(int argc, char **argv) { gboolean version = FALSE; /** True if -v was selected on the command line */ gint debug = -4; /** 0 == FALSE and other values == TRUE */ gchar *configfile = NULL; /** filename for the configuration file if any */ gchar *ip = NULL; /** IP address where is located server's program */ gint port = 0; /** Port number on which to send things to the server */ gchar *list = NULL; /** Should contain a filename or a directory to filter out */ gchar *restore = NULL; /** Must contain a filename or a directory name to be restored */ gchar *date = NULL; /** date at which we want to restore a file or directory */ gchar *where = NULL; /** Contains the directory where to restore a file / directory */ gchar *afterdate = NULL; /** afterdate: we want to restore a file that has its mtime after this date */ gchar *beforedate = NULL; /** beforedate: we want to restore a file that has its mtime before this date */ GOptionEntry entries[] = { { "version", 'v', 0, G_OPTION_ARG_NONE, &version, N_("Prints program version."), NULL}, { "list", 'l', 0, G_OPTION_ARG_FILENAME, &list, N_("Gives a list of saved files that correspond to the given REGEX."), "REGEX"}, { "restore", 'r', 0, G_OPTION_ARG_FILENAME, &restore, N_("Restores requested filename (REGEX) (by default latest version)."), "REGEX"}, { "date", 't', 0, G_OPTION_ARG_STRING, &date, N_("Restores the selected file at that specific DATE (YYYY-MM-DD HH:MM:SS format)."), "DATE"}, { "after", 'a', 0, G_OPTION_ARG_STRING, &afterdate, N_("Restores the selected file with mtime after DATE (YYYY-MM-DD HH:MM:SS format)."), "DATE"}, { "before", 'b', 0, G_OPTION_ARG_STRING, &beforedate, N_("Restores the selected file with mtime before DATE (YYYY-MM-DD HH:MM:SS format)."), "DATE"}, { "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")}, { "where", 'w', 0, G_OPTION_ARG_STRING, &where, N_("Specify a DIRECTORY where to restore a file."), N_("DIRECTORY")}, { "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 server program is listening."), N_("NUMBER")}, { NULL } }; GError *error = NULL; GOptionContext *context; options_t *opt = NULL; /** Structure to manage program's options */ gchar *bugreport = NULL; /** Bug Report message */ gchar *summary = NULL; /** Abstract for the program */ gchar *defaultconfigfilename = NULL; bugreport = g_strconcat(_("Please report bugs to: "), PACKAGE_BUGREPORT, NULL); summary = g_strdup(_("This program is restoring files from cdpfglserver's server.\n")); context = g_option_context_new(""); set_debug_mode(ENABLE_DEBUG); set_option_context_options(context, entries, TRUE, bugreport, summary); if (!g_option_context_parse(context, &argc, &argv, &error)) { g_print(_("Option parsing failed: %s\n"), error->message); exit(EXIT_FAILURE); } /* 0) Setting default values */ opt = (options_t *) g_malloc0(sizeof(options_t)); opt->configfile = NULL; opt->list = NULL; opt->restore = NULL; opt->ip = g_strdup("localhost"); opt->port = SERVER_PORT; opt->where = NULL; /* 1) Reading options from default configuration file * note: restore option will never be read into the configuration * file. */ defaultconfigfilename = get_probable_etc_path(PROGRAM_NAME, "restore.conf"); read_from_configuration_file(opt, defaultconfigfilename); defaultconfigfilename = free_variable(defaultconfigfilename); /* 2) Reading the configuration from the configuration file specified * on the command line (if any). * note: same note than 1) applies here too. */ if (configfile != NULL) { read_from_configuration_file(opt, configfile); } /* 3) retrieving other options from the command line. */ set_debug_mode_upon_cmdl(debug); opt->version = version; /* only TRUE if -v or --version was invoked */ if (date != NULL) { opt->date = g_strdup(date); } if (afterdate != NULL) { opt->afterdate = g_strdup(afterdate); } if (beforedate != NULL) { opt->beforedate = g_strdup(beforedate); } if (list != NULL) { opt->list = g_strdup(list); } if (restore != NULL) { opt->restore = g_strdup(restore); } if (ip != NULL) { free_variable(opt->ip); opt->ip = g_strdup(ip); } if (port > 1024 && port < 65535) { opt->port = port; } if (where != NULL) { opt->where = g_strdup(where); } g_option_context_free(context); free_variable(ip); free_variable(bugreport); free_variable(summary); free_variable(list); free_variable(restore); free_variable(date); free_variable(afterdate); free_variable(beforedate); free_variable(where); return opt; }