LCOV - code coverage report
Current view: top level - restore - options.c (source / functions) Hit Total Coverage
Test: coverage-restore.info Lines: 110 119 92.4 %
Date: 2016-02-03 22:31:47 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
       2             : /*
       3             :  *    options.c
       4             :  *    This file is part of "Sauvegarde" project.
       5             :  *
       6             :  *    (C) Copyright 2015 - 2016 Olivier Delhomme
       7             :  *     e-mail : olivier.delhomme@free.fr
       8             :  *
       9             :  *    "Sauvegarde" is free software: you can redistribute it and/or modify
      10             :  *    it under the terms of the GNU General Public License as published by
      11             :  *    the Free Software Foundation, either version 3 of the License, or
      12             :  *    (at your option) any later version.
      13             :  *
      14             :  *    "Sauvegarde" is distributed in the hope that it will be useful,
      15             :  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :  *    GNU General Public License for more details.
      18             :  *
      19             :  *    You should have received a copy of the GNU General Public License
      20             :  *    along with "Sauvegarde".  If not, see <http://www.gnu.org/licenses/>
      21             :  */
      22             : /**
      23             :  * @file restore/options.c
      24             :  *
      25             :  *  This file contains all the functions to manage command line options for
      26             :  *  'cdpfglrestore' program.
      27             :  */
      28             : 
      29             : #include "restore.h"
      30             : 
      31             : static void print_selected_options(options_t *opt);
      32             : static void read_from_group_all(GKeyFile *keyfile, gchar *filename);
      33             : static void read_from_group_server(options_t *opt, GKeyFile *keyfile, gchar *filename);
      34             : static options_t *manage_command_line_options(int argc, char **argv);
      35             : 
      36             : 
      37             : /**
      38             :  * Prints options as selected when invoking the program with -v option
      39             :  * @param opt the options_t * structure that contains all selected options
      40             :  *        from the command line and that will be used by the program.
      41             :  */
      42           1 : static void print_selected_options(options_t *opt)
      43             : {
      44           1 :     if (opt != NULL)
      45             :         {
      46           1 :             fprintf(stdout, _("\n%s options are:\n"), PROGRAM_NAME);
      47           1 :             print_string_option(_("Configuration file: %s\n"), opt->configfile);
      48           1 :             print_string_option(_("server's IP address: %s\n"), opt->ip);
      49           1 :             fprintf(stdout, _("server's port number: %d\n"), opt->port);
      50             :         }
      51           1 : }
      52             : 
      53             : 
      54             : /**
      55             :  * Reads keys in keyfile if group GN_ALL is in that keyfile.
      56             :  * @param keyfile is the GKeyFile structure that is used by glib to read
      57             :  *        groups and keys from.
      58             :  * @param filename : the filename of the configuration file to read from
      59             :  */
      60             : static void read_from_group_all(GKeyFile *keyfile, gchar *filename)
      61             : {
      62          16 :     read_debug_mode_from_file(keyfile, filename);
      63             : }
      64             : 
      65             : 
      66             : /**
      67             :  * Reads keys in keyfile if groupname is in that keyfile and fills
      68             :  * options_t *opt structure accordingly.
      69             :  * @param[in,out] opt : options_t * structure to store options read from the
      70             :  *                configuration file "filename".
      71             :  * @param keyfile is the GKeyFile structure that is used by glib to read
      72             :  *        groups and keys from.
      73             :  * @param filename : the filename of the configuration file to read from
      74             :  */
      75          16 : static void read_from_group_server(options_t *opt, GKeyFile *keyfile, gchar *filename)
      76             : {
      77          16 :     gint port = 0;
      78             : 
      79          16 :     if (opt != NULL && keyfile != NULL && filename != NULL && g_key_file_has_group(keyfile, GN_SERVER) == TRUE)
      80             :         {
      81             :             /* Reading the port number if any */
      82          16 :             port = read_int_from_file(keyfile, filename, GN_SERVER, KN_SERVER_PORT, _("Could not load server port number from file."), SERVER_PORT);
      83             : 
      84          16 :             if (port > 1024 && port < 65535)
      85             :                 {
      86          16 :                     opt->port = port;
      87             :                 }
      88             : 
      89             :             /* Reading IP address of server's host if any */
      90          16 :             opt->ip = read_string_from_file(keyfile, filename, GN_SERVER, KN_SERVER_IP, _("Could not load cache database name"));
      91             :         }
      92          16 : }
      93             : 
      94             : 
      95             : /**
      96             :  * Reads from the configuration file "filename" and fills the options_t *
      97             :  * opt structure.
      98             :  * @param[in,out] opt : options_t * structure to store options read from
      99             :  *                the configuration file "filename"
     100             :  * @param filename : the filename of the configuration file to read from
     101             :  */
     102          25 : static void read_from_configuration_file(options_t *opt, gchar *filename)
     103             : {
     104          25 :     GKeyFile *keyfile = NULL;      /** Configuration file parser   */
     105          25 :     GError *error = NULL;          /** Glib error handling         */
     106             : 
     107          25 :     if (filename != NULL)
     108             :         {
     109             : 
     110          16 :             if (opt->configfile != NULL)
     111             :                 {
     112           4 :                     free_variable(opt->configfile);
     113             :                 }
     114          16 :             opt->configfile = g_strdup(filename);
     115             : 
     116          16 :             print_debug(_("Reading configuration from file %s\n"), filename);
     117             : 
     118          16 :             keyfile = g_key_file_new();
     119             : 
     120          16 :             if (g_key_file_load_from_file(keyfile, filename, G_KEY_FILE_KEEP_COMMENTS, &error))
     121             :                 {
     122             :                     read_from_group_all(keyfile, filename);
     123          16 :                     read_from_group_server(opt, keyfile, filename);
     124             :                 }
     125           0 :             else if (error != NULL)
     126             :                 {
     127           0 :                     print_error(__FILE__, __LINE__, _("Failed to open %s configuration file: %s\n"), filename, error->message);
     128           0 :                     error = free_error(error);
     129             :                 }
     130             : 
     131          16 :             g_key_file_free(keyfile);
     132             :         }
     133          25 : }
     134             : 
     135             : 
     136             : /**
     137             :  * This function parses command line options. It sets the options in this
     138             :  * order. It means that the value used for an option is the one set in the
     139             :  * lastest step.
     140             :  * 0) default values are set into the options_t * structure
     141             :  * 1) reads the default configuration file if any.
     142             :  * 2) reads the configuration file mentionned on the command line.
     143             :  * 3) sets the command line options (except for the list of directories,
     144             :  *    all other values are replaced by thoses in the command line)
     145             :  * @param argc : number of arguments given on the command line.
     146             :  * @param argv : an array of strings that contains command line arguments.
     147             :  * @returns options_t structure malloc'ed and filled upon choosen command
     148             :  *          line's option
     149             :  */
     150          15 : static options_t *manage_command_line_options(int argc, char **argv)
     151             : {
     152          15 :     gboolean version = FALSE;      /** True if -v was selected on the command line                                */
     153          15 :     gint debug = -4;               /** 0 == FALSE and other values == TRUE                                        */
     154          15 :     gchar *configfile = NULL;      /** filename for the configuration file if any                                 */
     155          15 :     gchar *ip =  NULL;             /** IP address where is located server's program                               */
     156          15 :     gint port = 0;                 /** Port number on which to send things to the server                          */
     157          15 :     gchar *list = NULL;            /** Should contain a filename or a directory to filter out                     */
     158          15 :     gchar *restore = NULL;         /** Must contain a filename or a directory name to be restored                 */
     159          15 :     gchar *date = NULL;            /** date at which we want to restore a file or directory                       */
     160          15 :     gchar *where = NULL;           /** Contains the directory where to restore a file / directory                 */
     161          15 :     gchar *afterdate = NULL;       /** afterdate: we want to restore a file that has its mtime after this date    */
     162          15 :     gchar *beforedate = NULL;      /** beforedate:  we want to restore a file that has its mtime before this date */
     163             : 
     164          15 :     GOptionEntry entries[] =
     165             :     {
     166             :         { "version", 'v', 0, G_OPTION_ARG_NONE, &version, N_("Prints program version."), NULL},
     167             :         { "list", 'l', 0, G_OPTION_ARG_FILENAME, &list, N_("Gives a list of saved files that correspond to the given REGEX."), "REGEX"},
     168             :         { "restore", 'r', 0, G_OPTION_ARG_FILENAME, &restore, N_("Restores requested filename (REGEX) (by default latest version)."), "REGEX"},
     169             :         { "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"},
     170             :         { "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"},
     171             :         { "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"},
     172             :         { "debug", 'd', 0,  G_OPTION_ARG_INT, &debug, N_("Activates (1) or desactivates (0) debug mode."), N_("BOOLEAN")},
     173             :         { "configuration", 'c', 0, G_OPTION_ARG_STRING, &configfile, N_("Specify an alternative configuration file."), N_("FILENAME")},
     174             :         { "where", 'w', 0, G_OPTION_ARG_STRING, &where, N_("Specify a DIRECTORY where to restore a file."), N_("DIRECTORY")},
     175             :         { "ip", 'i', 0, G_OPTION_ARG_STRING, &ip, N_("IP address where server program is."), "IP"},
     176             :         { "port", 'p', 0, G_OPTION_ARG_INT, &port, N_("Port NUMBER on which server program is listening."), N_("NUMBER")},
     177             :         { NULL }
     178             :     };
     179             : 
     180          15 :     GError *error = NULL;
     181             :     GOptionContext *context;
     182          15 :     options_t *opt = NULL;    /** Structure to manage program's options            */
     183          15 :     gchar *bugreport = NULL;  /** Bug Report message                               */
     184          15 :     gchar *summary = NULL;    /** Abstract for the program                         */
     185          15 :     gchar *defaultconfigfilename = NULL;
     186             : 
     187          15 :     bugreport = g_strconcat(_("Please report bugs to: "), PACKAGE_BUGREPORT, NULL);
     188          15 :     summary = g_strdup(_("This program is restoring files from cdpfglserver's server.\n"));
     189          15 :     context = g_option_context_new("");
     190             : 
     191          15 :     set_debug_mode(ENABLE_DEBUG);
     192             : 
     193          15 :     set_option_context_options(context, entries, TRUE, bugreport, summary);
     194             : 
     195          15 :     if (!g_option_context_parse(context, &argc, &argv, &error))
     196             :         {
     197           0 :             g_print(_("Option parsing failed: %s\n"), error->message);
     198           0 :             exit(EXIT_FAILURE);
     199             :         }
     200             : 
     201             :     /* 0) Setting default values */
     202             : 
     203          13 :     opt = (options_t *) g_malloc0(sizeof(options_t));
     204             : 
     205          13 :     opt->configfile = NULL;
     206          13 :     opt->list = NULL;
     207          13 :     opt->restore = NULL;
     208          13 :     opt->ip = g_strdup("localhost");
     209          13 :     opt->port = SERVER_PORT;
     210          13 :     opt->where = NULL;
     211             : 
     212             : 
     213             :     /* 1) Reading options from default configuration file
     214             :      *    note: restore option will never be read into the configuration
     215             :      *          file.
     216             :      */
     217          13 :     defaultconfigfilename = get_probable_etc_path(PROGRAM_NAME, "restore.conf");
     218          13 :     read_from_configuration_file(opt,  defaultconfigfilename);
     219          13 :     defaultconfigfilename = free_variable(defaultconfigfilename);
     220             : 
     221             : 
     222             :     /* 2) Reading the configuration from the configuration file specified
     223             :      *    on the command line (if any).
     224             :      *    note: same note than 1) applies here too.
     225             :      */
     226          13 :     if (configfile != NULL)
     227             :         {
     228          12 :             read_from_configuration_file(opt, configfile);
     229             :         }
     230             : 
     231             : 
     232             :     /* 3) retrieving other options from the command line.
     233             :      */
     234          13 :     set_debug_mode_upon_cmdl(debug);
     235          13 :     opt->version = version; /* only TRUE if -v or --version was invoked */
     236             : 
     237          13 :     if (date != NULL)
     238             :         {
     239           0 :             opt->date = g_strdup(date);
     240             :         }
     241             : 
     242          13 :     if (afterdate != NULL)
     243             :         {
     244           2 :             opt->afterdate = g_strdup(afterdate);
     245             :         }
     246             : 
     247          13 :     if (beforedate != NULL)
     248             :         {
     249           1 :             opt->beforedate = g_strdup(beforedate);
     250             :         }
     251             : 
     252          13 :     if (list != NULL)
     253             :         {
     254           4 :             opt->list = g_strdup(list);
     255             :         }
     256             : 
     257          13 :     if (restore != NULL)
     258             :         {
     259           8 :             opt->restore = g_strdup(restore);
     260             :         }
     261             : 
     262          13 :     if (ip != NULL)
     263             :         {
     264           0 :             free_variable(opt->ip);
     265           0 :             opt->ip = g_strdup(ip);
     266             :         }
     267             : 
     268          13 :     if (port > 1024 && port < 65535)
     269             :         {
     270           0 :             opt->port = port;
     271             :         }
     272             : 
     273          13 :     if (where != NULL)
     274             :         {
     275           8 :             opt->where = g_strdup(where);
     276             :         }
     277             : 
     278          13 :     g_option_context_free(context);
     279          13 :     free_variable(ip);
     280          13 :     free_variable(bugreport);
     281          13 :     free_variable(summary);
     282          13 :     free_variable(list);
     283          13 :     free_variable(restore);
     284          13 :     free_variable(date);
     285          13 :     free_variable(afterdate);
     286          13 :     free_variable(beforedate);
     287          13 :     free_variable(where);
     288             : 
     289          13 :     return opt;
     290             : }
     291             : 
     292             : 
     293             : /**
     294             :  * Decides what to do upon command lines options passed to the program
     295             :  * @param argc : number of arguments given on the command line.
     296             :  * @param argv : an array of strings that contains command line arguments.
     297             :  * @returns options_t structure malloc'ed and filled upon choosen command
     298             :  *          line's option (in manage_command_line_options function).
     299             :  */
     300          15 : options_t *do_what_is_needed_from_command_line_options(int argc, char **argv)
     301             : {
     302          15 :     options_t *opt = NULL;  /** Structure to manage options from the command line can be freed when no longer needed */
     303             : 
     304          15 :     opt = manage_command_line_options(argc, argv);
     305             : 
     306          13 :     if (opt != NULL)
     307             :         {
     308          13 :             if (opt->version == TRUE)
     309             :                 {
     310           1 :                     print_program_version(PROGRAM_NAME, RESTORE_DATE, RESTORE_VERSION, RESTORE_AUTHORS, RESTORE_LICENSE);
     311           1 :                     print_libraries_versions(PROGRAM_NAME);
     312           1 :                     print_selected_options(opt);
     313           1 :                     exit(EXIT_SUCCESS);
     314             :                 }
     315             :         }
     316             : 
     317          12 :     return opt;
     318             : }
     319             : 
     320             : 
     321             : /**
     322             :  * Frees the option structure
     323             :  * @param opt is the structure to be freed
     324             :  */
     325          12 : void free_options_t(options_t *opt)
     326             : {
     327          12 :     if (opt != NULL)
     328             :         {
     329          12 :             free_variable(opt->list);
     330          12 :             free_variable(opt->restore);
     331          12 :             free_variable(opt->date);
     332          12 :             free_variable(opt->configfile);
     333          12 :             free_variable(opt->ip);
     334          12 :             free_variable(opt);
     335             :         }
     336          12 : }

Generated by: LCOV version 1.11