LCOV - code coverage report
Current view: top level - src - prog.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 0 302 0.0 %
Date: 2022-12-03 01:09:05 Functions: 0 8 0.0 %

          Line data    Source code
       1             : #include "burp.h"
       2             : #include "base64.h"
       3             : #include "cmd.h"
       4             : #include "conf.h"
       5             : #include "conffile.h"
       6             : #include "client/main.h"
       7             : #include "handy.h"
       8             : #include "hexmap.h"
       9             : #include "lock.h"
      10             : #include "log.h"
      11             : #include "strlist.h"
      12             : #include "server/bedup.h"
      13             : #include "server/main.h"
      14             : 
      15           0 : static void usage_server(void)
      16             : {
      17             : #ifndef HAVE_WIN32
      18           0 :         printf("\nThe configuration file specifies whether %s runs in server or client mode.\n", PACKAGE_TARNAME);
      19           0 :         printf("\nServer usage: %s [options]\n", progname());
      20           0 :         printf("\n");
      21           0 :         printf(" Options:\n");
      22           0 :         printf("  -c <path>     Path to conf file (default: %s).\n", config_default_path());
      23           0 :         printf("  -d <path>     a single client in the status monitor.\n");
      24           0 :         printf("  -o <option>   Override a given configuration option\n");
      25           0 :         printf("                (you can use this flag several times).\n");
      26           0 :         printf("  -F            Stay in the foreground.\n");
      27           0 :         printf("  -g            Generate initial CA certificates and exit.\n");
      28           0 :         printf("  -h|-?         Print this text and exit.\n");
      29           0 :         printf("  -i            Print index of symbols and exit.\n");
      30           0 :         printf("  -n            Do not fork any children (implies '-F').\n");
      31           0 :         printf("  -Q            Do not log to stdout\n");
      32           0 :         printf("  -t            Dry-run to test config file syntax.\n");
      33           0 :         printf("  -v            Log to stdout.\n");
      34           0 :         printf("  -V            Print version and exit.\n");
      35           0 :         printf("Options to use with '-a c':\n");
      36           0 :         printf("  -C <client>   Run as if forked via a connection from this client.\n");
      37           0 :         printf("\n");
      38             : #endif
      39           0 : }
      40             : 
      41           0 : static void usage_client(void)
      42             : {
      43           0 :         printf("\nClient usage: %s [options]\n", progname());
      44           0 :         printf("\n");
      45           0 :         printf(" Options:\n");
      46           0 :         printf("  -a <action>    The action can be one of the following.\n");
      47           0 :         printf("                  b: backup\n");
      48           0 :         printf("                  delete: delete\n");
      49           0 :         printf("                  d: diff\n");
      50           0 :         printf("                  e: estimate\n");
      51           0 :         printf("                  l: list (this is the default when an action is not given)\n");
      52           0 :         printf("                  L: long list\n");
      53           0 :         printf("                  m: monitor interface\n");
      54           0 :         printf("                  p: parseable list\n");
      55           0 :         printf("                  r: restore\n");
      56           0 :         printf("                  R: Restore (matching ordered paths on stdin)\n");
      57             : #ifndef HAVE_WIN32
      58           0 :         printf("                  s: status monitor (ncurses)\n");
      59           0 :         printf("                  S: status monitor snapshot\n");
      60             : #endif
      61           0 :         printf("                  t: timed backup\n");
      62           0 :         printf("                  T: check backup timer, but do not actually backup\n");
      63           0 :         printf("                  v: verify\n");
      64           0 :         printf("                  V: Verify (matching ordered paths on stdin)\n");
      65           0 :         printf("  -b <number>    Backup number (default: the most recent backup).\n");
      66           0 :         printf("  -c <path>      Path to conf file (default: %s).\n", config_default_path());
      67           0 :         printf("  -d <directory> Directory to restore to, or directory to list.\n");
      68           0 :         printf("  -o <option>    Override a given configuration option (you can use this flag several times).\n");
      69           0 :         printf("  -f             Allow overwrite during restore.\n");
      70           0 :         printf("  -h|-?          Print this text and exit.\n");
      71           0 :         printf("  -i             Print index of symbols and exit.\n");
      72           0 :         printf("  -q <max secs>  Randomised delay of starting a timed backup.\n");
      73           0 :         printf("  -Q             Do not log to stdout\n");
      74           0 :         printf("  -r|-R <regex> Specify a regular expression (case sensitive or insensitive.\n");
      75           0 :         printf("  -s <number>    Number of leading path components to strip during restore.\n");
      76           0 :         printf("  -t             Dry-run to test config file syntax.\n");
      77           0 :         printf("  -V             Print version and exit.\n");
      78           0 :         printf("  -v             Log to stdout.\n");
      79             : #ifdef HAVE_WIN32
      80             :         printf("  -X             Do not use the Windows VSS API when restoring.\n");
      81             :         printf("  -x             Do not use the Windows VSS API when restoring,\n");
      82             :         printf("                 and strip out VSS data.\n");
      83             : #else
      84           0 :         printf("  -x             Strip Windows VSS data when restoring.\n");
      85           0 :         printf("Options to use with '-a S':\n");
      86           0 :         printf("  -C <client>   Show a particular client.\n");
      87           0 :         printf("  -b <number>   Show listable files in a particular backup (requires -C).\n");
      88           0 :         printf("  -d <path>     Show a particular path in a backup (requires -C and -b).\n");
      89           0 :         printf("  -l <path>     Log file for the status monitor.\n");
      90           0 :         printf("  -z <file>     Dump a particular log file in a backup (requires -C and -b).\n");
      91             : #endif
      92           0 :         printf("\n");
      93             : #ifndef HAVE_WIN32
      94           0 :         printf(" See ");
      95             :         // Older versions of autoconf do not pick up PACKAGE_URL.
      96             :         #ifdef PACKAGE_URL
      97           0 :                 printf("%s or ", PACKAGE_URL);
      98             :         #endif
      99           0 :         printf( "the man page ('man %s') for usage examples\n",
     100             :                         PACKAGE_TARNAME);
     101           0 :         printf(" and additional configuration options.\n\n");
     102             : #else
     103             :         printf(" See %s for usage examples and additional configuration\n",
     104             :                 PACKAGE_TARNAME);
     105             :         printf(" options.\n\n");
     106             : #endif
     107           0 : }
     108             : 
     109           0 : int reload(struct conf **confs, const char *conffile, bool firsttime)
     110             : {
     111           0 :         if(!firsttime) logp("Reloading config\n");
     112             : 
     113           0 :         if(confs_init(confs)) return -1;
     114             : 
     115           0 :         if(conf_load_global_only(conffile, confs)) return -1;
     116             : 
     117           0 :         umask(get_mode_t(confs[OPT_UMASK]));
     118             : 
     119             :         // This will turn on syslogging which could not be turned on before
     120             :         // conf_load.
     121           0 :         log_fzp_set(NULL, confs);
     122             : 
     123             : #ifndef HAVE_WIN32
     124           0 :         if(get_e_burp_mode(confs[OPT_BURP_MODE])==BURP_MODE_SERVER)
     125           0 :                 setup_signals();
     126             : #endif
     127             : 
     128             :         return 0;
     129             : }
     130             : 
     131             : static int replace_conf_str(struct conf *conf, const char *newval)
     132             : {
     133           0 :         if(!newval) return 0;
     134           0 :         return set_string(conf, newval);
     135             : }
     136             : 
     137             : static void usage(void)
     138             : {
     139           0 :         usage_server();
     140           0 :         usage_client();
     141             : }
     142             : 
     143           0 : static int parse_action(enum action *act, const char *optarg,
     144             :         struct strlist **cli_overrides)
     145             : {
     146           0 :         if(!strncmp(optarg, "backup", 1))
     147           0 :                 *act=ACTION_BACKUP;
     148           0 :         else if(!strncmp(optarg, "timedbackup", 1))
     149           0 :                 *act=ACTION_BACKUP_TIMED;
     150           0 :         else if(!strncmp(optarg, "Timercheck", 1))
     151           0 :                 *act=ACTION_TIMER_CHECK;
     152           0 :         else if(!strncmp(optarg, "restore", 1))
     153           0 :                 *act=ACTION_RESTORE;
     154           0 :         else if(!strncmp(optarg, "Restore", 1))
     155             :         {
     156           0 :                 *act=ACTION_RESTORE;
     157           0 :                 strlist_add(cli_overrides, "restore_list=/dev/stdin", 0);
     158             :         }
     159           0 :         else if(!strncmp(optarg, "verify", 1))
     160           0 :                 *act=ACTION_VERIFY;
     161           0 :         else if(!strncmp(optarg, "Verify", 1))
     162             :         {
     163           0 :                 *act=ACTION_VERIFY;
     164           0 :                 strlist_add(cli_overrides, "restore_list=/dev/stdin", 0);
     165             :         }
     166           0 :         else if(!strncmp(optarg, "list", 1))
     167           0 :                 *act=ACTION_LIST;
     168           0 :         else if(!strncmp(optarg, "List", 1))
     169           0 :                 *act=ACTION_LIST_LONG;
     170           0 :         else if(!strncmp(optarg, "parseablelist", 1))
     171           0 :                 *act=ACTION_LIST_PARSEABLE;
     172           0 :         else if(!strncmp(optarg, "status", 1))
     173           0 :                 *act=ACTION_STATUS;
     174           0 :         else if(!strncmp(optarg, "Status", 1))
     175           0 :                 *act=ACTION_STATUS_SNAPSHOT;
     176           0 :         else if(!strncmp(optarg, "estimate", 1))
     177           0 :                 *act=ACTION_ESTIMATE;
     178             :         // Make them spell 'delete' out fully so that it is less likely to be
     179             :         // used accidently.
     180           0 :         else if(!strncmp_w(optarg, "delete"))
     181           0 :                 *act=ACTION_DELETE;
     182           0 :         else if(!strncmp(optarg, "diff", 1))
     183           0 :                 *act=ACTION_DIFF;
     184           0 :         else if(!strncmp(optarg, "Diff", 1))
     185           0 :                 *act=ACTION_DIFF_LONG;
     186           0 :         else if(!strncmp(optarg, "monitor", 1))
     187           0 :                 *act=ACTION_MONITOR;
     188             :         else
     189             :         {
     190             :                 usage();
     191           0 :                 return -1;
     192             :         }
     193             :         return 0;
     194             : }
     195             : 
     196           0 : static void random_delay(struct conf **confs)
     197             : {
     198             :         int delay;
     199           0 :         int randomise=get_int(confs[OPT_RANDOMISE]);
     200           0 :         if(!randomise) return;
     201           0 :         srand(getpid());
     202           0 :         delay=rand()%randomise;
     203           0 :         logp("Sleeping %d seconds\n", delay);
     204           0 :         sleep(delay);
     205             : }
     206             : 
     207           0 : static int run_test_confs(struct conf **confs, const char *client)
     208             : {
     209           0 :         int ret=-1;
     210           0 :         struct conf **cconfs=NULL;
     211           0 :         if(!client)
     212             :         {
     213           0 :                 confs_dump(confs, 0);
     214           0 :                 ret=0;
     215           0 :                 goto end;
     216             :         }
     217           0 :         if(!(cconfs=confs_alloc()))
     218             :                 goto end;
     219           0 :         confs_init(cconfs);
     220           0 :         if(set_string(cconfs[OPT_CNAME], client)
     221           0 :           || set_string(cconfs[OPT_PEER_VERSION], PACKAGE_VERSION)
     222           0 :           || conf_load_clientconfdir(confs, cconfs))
     223             :                 goto end;
     224           0 :         confs_dump(cconfs, CONF_FLAG_CC_OVERRIDE|CONF_FLAG_INCEXC);
     225             : 
     226             : end:
     227           0 :         confs_free(&cconfs);
     228           0 :         return ret;
     229             : }
     230             : 
     231           0 : static struct lock *get_prog_lock(struct conf **confs)
     232             : {
     233           0 :         struct lock *lock=NULL;
     234           0 :         const char *lockfile=confs_get_lockfile(confs);
     235           0 :         if(!(lock=lock_alloc_and_init(lockfile)))
     236             :                 goto error;
     237           0 :         lock_get(lock);
     238           0 :         switch(lock->status)
     239             :         {
     240             :                 case GET_LOCK_GOT:
     241             :                         return lock;
     242             :                 case GET_LOCK_NOT_GOT:
     243           0 :                         logp("Could not get lockfile.\n");
     244           0 :                         logp("Another process is probably running.\n");
     245           0 :                         goto error;
     246             :                 case GET_LOCK_ERROR:
     247             :                 default:
     248           0 :                         logp("Could not get lockfile.\n");
     249           0 :                         logp("Maybe you do not have permissions to write to %s.\n", lockfile);
     250           0 :                         goto error;
     251             :         }
     252             : error:
     253           0 :         lock_free(&lock);
     254           0 :         return NULL;
     255             : }
     256             : 
     257             : #ifdef HAVE_WIN32
     258             : #define main RealMain
     259             : #endif
     260             : #ifndef UTEST
     261             : static
     262             : #endif
     263           0 : int real_main(int argc, char *argv[])
     264             : {
     265           0 :         int ret=1;
     266           0 :         int option=0;
     267           0 :         int daemon=1;
     268           0 :         int forking=1;
     269           0 :         int strip=0;
     270           0 :         int randomise=0;
     271           0 :         struct lock *lock=NULL;
     272           0 :         struct conf **confs=NULL;
     273           0 :         int forceoverwrite=0;
     274           0 :         enum action act=ACTION_LIST;
     275           0 :         const char *backup=NULL;
     276           0 :         const char *backup2=NULL;
     277           0 :         char *restoreprefix=NULL;
     278           0 :         char *stripfrompath=NULL;
     279           0 :         const char *regex=NULL;
     280           0 :         const char *browsefile=NULL;
     281           0 :         char *browsedir=NULL;
     282           0 :         const char *conffile=config_default_path();
     283           0 :         const char *orig_client=NULL;
     284           0 :         const char *logfile=NULL;
     285             :         // The orig_client is the original client that the normal client
     286             :         // would like to restore from.
     287             : #ifndef HAVE_WIN32
     288           0 :         int generate_ca_only=0;
     289             : #endif
     290           0 :         enum vss_restore vss_restore=VSS_RESTORE_ON;
     291           0 :         int test_confs=0;
     292             :         enum burp_mode mode;
     293           0 :         struct strlist *cli_overrides=NULL;
     294           0 :         int keep_readall_caps=0;
     295           0 :         int regex_case_insensitive=0;
     296             : 
     297           0 :         log_init(argv[0]);
     298             : #ifndef HAVE_WIN32
     299           0 :         if(!strcmp(prog, "bedup"))
     300           0 :                 return run_bedup(argc, argv);
     301             : #endif
     302             : 
     303           0 :         while((option=getopt(argc, argv, "a:b:C:c:d:o:Ffghijl:nQq:R:r:s:tVvXxz:?"))!=-1)
     304             :         {
     305           0 :                 switch(option)
     306             :                 {
     307             :                         case 'a':
     308           0 :                                 if(parse_action(&act, optarg,
     309             :                                         &cli_overrides)) goto end;
     310             :                                 break;
     311             :                         case 'b':
     312             :                                 // The diff command may have two backups
     313             :                                 // specified.
     314           0 :                                 if(!backup2 && backup) backup2=optarg;
     315           0 :                                 if(!backup) backup=optarg;
     316             :                                 break;
     317             :                         case 'C':
     318           0 :                                 orig_client=optarg;
     319           0 :                                 break;
     320             :                         case 'c':
     321           0 :                                 conffile=optarg;
     322           0 :                                 break;
     323             :                         case 'd':
     324           0 :                                 restoreprefix=optarg; // for restores
     325           0 :                                 browsedir=optarg; // for lists
     326           0 :                                 break;
     327             :                         case 'F':
     328             :                                 daemon=0;
     329             :                                 break;
     330             :                         case 'f':
     331           0 :                                 forceoverwrite=1;
     332           0 :                                 break;
     333             :                         case 'g':
     334             : #ifndef HAVE_WIN32
     335           0 :                                 generate_ca_only=1;
     336             : #endif
     337           0 :                                 break;
     338             :                         case 'i':
     339           0 :                                 cmd_print_all();
     340           0 :                                 ret=0;
     341           0 :                                 goto end;
     342             :                         case 'l':
     343           0 :                                 logfile=optarg;
     344           0 :                                 break;
     345             :                         case 'n':
     346           0 :                                 forking=0;
     347           0 :                                 break;
     348             :                         case 'o':
     349           0 :                                 strlist_add(&cli_overrides, optarg, 0);
     350           0 :                                 break;
     351             :                         case 'Q':
     352           0 :                                 strlist_add(&cli_overrides, "progress_counter=0", 0);
     353           0 :                                 strlist_add(&cli_overrides, "stdout=0", 0);
     354           0 :                                 break;
     355             :                         case 'q':
     356           0 :                                 randomise=atoi(optarg);
     357           0 :                                 break;
     358             :                         case 'R':
     359           0 :                                 regex_case_insensitive=1;
     360           0 :                                 regex=optarg;
     361           0 :                                 break;
     362             :                         case 'r':
     363           0 :                                 regex_case_insensitive=0;
     364           0 :                                 regex=optarg;
     365           0 :                                 break;
     366             :                         case 's':
     367           0 :                                 strip=atoi(optarg);
     368           0 :                                 break;
     369             :                         case 'V':
     370           0 :                                 printf("%s-%s\n", progname(), PACKAGE_VERSION);
     371           0 :                                 ret=0;
     372           0 :                                 goto end;
     373             :                         case 'v':
     374           0 :                                 strlist_add(&cli_overrides, "stdout=1", 0);
     375           0 :                                 break;
     376             :                         case 'X':
     377           0 :                                 vss_restore=VSS_RESTORE_OFF;
     378           0 :                                 break;
     379             :                         case 'x':
     380           0 :                                 vss_restore=VSS_RESTORE_OFF_STRIP;
     381           0 :                                 break;
     382             :                         case 't':
     383           0 :                                 test_confs=1;
     384           0 :                                 break;
     385             :                         case 'z':
     386           0 :                                 browsefile=optarg;
     387           0 :                                 break;
     388             :                         case 'h':
     389             :                         case '?':
     390             :                         default:
     391             :                                 usage();
     392             :                                 goto end;
     393             :                 }
     394             :         }
     395           0 :         if(optind<argc)
     396             :         {
     397             :                 usage();
     398             :                 goto end;
     399             :         }
     400             : 
     401           0 :         if(act==ACTION_MONITOR)
     402             :         {
     403             :                 // Try to output everything in JSON.
     404           0 :                 log_set_json(1);
     405             :                 // Need to do this so that processes reading stdout get the
     406             :                 // result of the printfs of logp straight away.
     407           0 :                 setvbuf(stdout, NULL, _IONBF, 0);
     408             :         }
     409             : 
     410           0 :         if(act==ACTION_LIST_PARSEABLE)
     411           0 :                 strlist_add(&cli_overrides, "stdout=0", 0);
     412             : 
     413           0 :         conf_set_cli_overrides(cli_overrides);
     414           0 :         if(!(confs=confs_alloc()))
     415             :                 goto end;
     416             : 
     417           0 :         if(reload(confs, conffile, 1))
     418             :                 goto end;
     419             : 
     420             :         // Dry run to test config file syntax.
     421           0 :         if(test_confs)
     422             :         {
     423           0 :                 ret=run_test_confs(confs, orig_client);
     424           0 :                 goto end;
     425             :         }
     426             : 
     427           0 :         if(!backup) switch(act)
     428             :         {
     429             :                 case ACTION_DELETE:
     430           0 :                         logp("No backup specified for deletion.\n");
     431           0 :                         goto end;
     432             :                 case ACTION_RESTORE:
     433             :                 case ACTION_VERIFY:
     434             :                 case ACTION_DIFF:
     435             :                 case ACTION_DIFF_LONG:
     436           0 :                         logp("No backup specified. Using the most recent.\n");
     437           0 :                         backup="0";
     438             :                 default:
     439             :                         break;
     440             :         }
     441           0 :         if(!backup2) switch(act)
     442             :         {
     443             :                 case ACTION_DIFF:
     444             :                 case ACTION_DIFF_LONG:
     445           0 :                         logp("No second backup specified. Using file system scan.\n");
     446           0 :                         backup2="n"; // For 'next'.
     447             :                 default:
     448             :                         break;
     449             :         }
     450             : 
     451             :         // The logfile option is only used for the status client stuff.
     452           0 :         if(logfile
     453           0 :           && (act!=ACTION_STATUS
     454           0 :                 && act!=ACTION_STATUS_SNAPSHOT))
     455           0 :                         logp("-l <logfile> option obsoleted\n");
     456             : 
     457           0 :         if(orig_client
     458           0 :           && *orig_client
     459           0 :           && set_string(confs[OPT_ORIG_CLIENT], orig_client))
     460             :                 goto end;
     461             : 
     462             :         // The random delay needs to happen before the lock is got, otherwise
     463             :         // you would never be able to use burp by hand.
     464           0 :         if(randomise) set_int(confs[OPT_RANDOMISE], randomise);
     465           0 :         mode=get_e_burp_mode(confs[OPT_BURP_MODE]);
     466           0 :         if(mode==BURP_MODE_CLIENT
     467           0 :           && (act==ACTION_BACKUP_TIMED || act==ACTION_TIMER_CHECK))
     468           0 :                 random_delay(confs);
     469             : 
     470           0 :         if(mode==BURP_MODE_SERVER)
     471             :         {
     472           0 :                 switch(act)
     473             :                 {
     474             :                         case ACTION_CHAMP_CHOOSER:
     475             :                                 // Need to run without getting the lock.
     476             :                                 break;
     477             :                         default:
     478           0 :                                 if(!(lock=get_prog_lock(confs)))
     479             :                                         goto end;
     480             :                                 break;
     481             :                 }
     482             :         }
     483           0 :         else if(mode==BURP_MODE_CLIENT)
     484             :         {
     485           0 :                 set_int(confs[OPT_VSS_RESTORE], vss_restore);
     486           0 :                 switch(act)
     487             :                 {
     488             :                         case ACTION_BACKUP:
     489             :                         case ACTION_BACKUP_TIMED:
     490             :                         case ACTION_TIMER_CHECK:
     491             : #ifdef ENABLE_KEEP_READALL_CAPS_SUPPORT
     492             :                                 keep_readall_caps=get_int(confs[OPT_READALL]);
     493             :                                 // readall=1 cannot work with atime=0 (O_NOATIME)
     494             :                                 if (keep_readall_caps)
     495             :                                         set_int(confs[OPT_ATIME], 1);
     496             : #endif
     497             :                                 // Need to get the lock.
     498           0 :                                 if(!(lock=get_prog_lock(confs)))
     499             :                                         goto end;
     500             :                                 break;
     501             :                         default:
     502             :                                 break;
     503             :                 }
     504             :         }
     505             : 
     506             :         // Change privileges after having got the lock, for convenience.
     507           0 :         if(chuser_and_or_chgrp(
     508           0 :                 get_string(confs[OPT_USER]), get_string(confs[OPT_GROUP]),
     509             :                 keep_readall_caps))
     510             :                         return -1;
     511             : 
     512           0 :         set_int(confs[OPT_OVERWRITE], forceoverwrite);
     513           0 :         set_int(confs[OPT_STRIP], strip);
     514           0 :         set_int(confs[OPT_FORK], forking);
     515           0 :         set_int(confs[OPT_DAEMON], daemon);
     516           0 :         set_int(confs[OPT_REGEX_CASE_INSENSITIVE], regex_case_insensitive);
     517             : 
     518           0 :         strip_trailing_slashes(&restoreprefix);
     519           0 :         strip_trailing_slashes(&browsedir);
     520           0 :         if(replace_conf_str(confs[OPT_BACKUP], backup)
     521           0 :           || replace_conf_str(confs[OPT_BACKUP2], backup2)
     522           0 :           || replace_conf_str(confs[OPT_RESTOREPREFIX], restoreprefix)
     523           0 :           || replace_conf_str(confs[OPT_STRIP_FROM_PATH], stripfrompath)
     524           0 :           || replace_conf_str(confs[OPT_REGEX], regex)
     525           0 :           || replace_conf_str(confs[OPT_BROWSEFILE], browsefile)
     526           0 :           || replace_conf_str(confs[OPT_BROWSEDIR], browsedir)
     527           0 :           || replace_conf_str(confs[OPT_MONITOR_LOGFILE], logfile))
     528             :                 goto end;
     529             : 
     530           0 :         base64_init();
     531             : 
     532           0 :         if(mode==BURP_MODE_SERVER)
     533             :         {
     534             : #ifdef HAVE_WIN32
     535             :                 logp("Sorry, server mode is not implemented for Windows.\n");
     536             : #else
     537           0 :                 return server(confs, conffile, lock, generate_ca_only);
     538             : #endif
     539             :         }
     540             :         else
     541             :         {
     542           0 :                 ret=client(confs, act);
     543             :         }
     544             : 
     545             : end:
     546           0 :         lock_release(lock);
     547           0 :         lock_free(&lock);
     548           0 :         confs_free(&confs);
     549           0 :         strlists_free(&cli_overrides);
     550           0 :         return ret;
     551             : }
     552             : 
     553             : #ifndef UTEST
     554             : int main(int argc, char *argv[])
     555             : {
     556             :         return real_main(argc, argv);
     557             : }
     558             : #endif

Generated by: LCOV version 1.13