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

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../conffile.h"
       3             : #include "../action.h"
       4             : #include "../asfd.h"
       5             : #include "../async.h"
       6             : #include "../cmd.h"
       7             : #include "../cntr.h"
       8             : #include "../fsops.h"
       9             : #include "../handy.h"
      10             : #include "../iobuf.h"
      11             : #include "../log.h"
      12             : #include "../run_script.h"
      13             : #include "auth.h"
      14             : #include "backup.h"
      15             : #include "ca.h"
      16             : #include "delete.h"
      17             : #include "extra_comms.h"
      18             : #include "list.h"
      19             : #include "monitor.h"
      20             : #include "find_logic.h"
      21             : #include "monitor/status_client_ncurses.h"
      22             : #include "restore.h"
      23             : #include "main.h"
      24             : 
      25             : #ifndef HAVE_WIN32
      26             : #include <sys/utsname.h>
      27             : #endif
      28             : 
      29             : // These will also be used as the exit codes of the program and are therefore
      30             : // unsigned integers.
      31             : // Remember to update the man page if you update these.
      32             : enum cliret
      33             : {
      34             :         CLIENT_OK=0,
      35             :         CLIENT_ERROR=1,
      36             :         CLIENT_RESTORE_WARNINGS=2,
      37             :         CLIENT_SERVER_TIMER_NOT_MET=3,
      38             :         CLIENT_COULD_NOT_CONNECT=4,
      39             :         CLIENT_SERVER_MAX_PARALLEL_BACKUPS=5,
      40             :         // This one happens after a successful certificate signing request so
      41             :         // that it connects again straight away with the new key/certificate.
      42             :         CLIENT_RECONNECT=100
      43             : };
      44             : 
      45             : struct tchk
      46             : {
      47             :         int resume;
      48             :         enum cliret ret;
      49             : };
      50             : 
      51           0 : static enum asl_ret maybe_check_timer_func(struct asfd *asfd,
      52             :         struct conf **confs, void *param)
      53             : {
      54           0 :         int complen=0;
      55           0 :         struct tchk *tchk=(struct tchk *)param;
      56             : 
      57           0 :         if(!strcmp(asfd->rbuf->buf, "max parallel backups"))
      58             :         {
      59           0 :                 logp("Max parallel backups reached\n");
      60           0 :                 tchk->ret=CLIENT_SERVER_MAX_PARALLEL_BACKUPS;
      61           0 :                 return ASL_END_OK;
      62           0 :         } else if(!strcmp(asfd->rbuf->buf, "timer conditions not met"))
      63             :         {
      64           0 :                 logp("Timer conditions on the server were not met\n");
      65           0 :                 tchk->ret=CLIENT_SERVER_TIMER_NOT_MET;
      66           0 :                 return ASL_END_OK;
      67             :         }
      68           0 :         else if(!strcmp(asfd->rbuf->buf, "timer conditions met"))
      69             :         {
      70             :                 // Only happens on 'timer check only'.
      71           0 :                 logp("Timer conditions on the server were met\n");
      72           0 :                 tchk->ret=CLIENT_OK;
      73           0 :                 return ASL_END_OK;
      74             :         }
      75             : 
      76           0 :         if(!strncmp_w(asfd->rbuf->buf, "ok"))
      77             :                 complen=3;
      78           0 :         else if(!strncmp_w(asfd->rbuf->buf, "resume"))
      79             :         {
      80           0 :                 complen=7;
      81           0 :                 tchk->resume=1;
      82           0 :                 logp("server wants to resume previous backup.\n");
      83             :         }
      84             :         else
      85             :         {
      86           0 :                 iobuf_log_unexpected(asfd->rbuf, __func__);
      87           0 :                 return ASL_END_ERROR;
      88             :         }
      89             : 
      90             :         // The server now tells us the compression level in the OK response.
      91           0 :         if(strlen(asfd->rbuf->buf)>3)
      92           0 :                 set_int(confs[OPT_COMPRESSION], atoi(asfd->rbuf->buf+complen));
      93           0 :         logp("Compression level: %d\n",
      94             :                 get_int(confs[OPT_COMPRESSION]));
      95             : 
      96           0 :         return ASL_END_OK;
      97             : }
      98             : 
      99           0 : static enum cliret maybe_check_timer(struct asfd *asfd,
     100             :         const char *phase1str, struct conf **confs, int *resume)
     101             : {
     102             :         struct tchk tchk;
     103           0 :         memset(&tchk, 0, sizeof(tchk));
     104           0 :         if(asfd->write_str(asfd, CMD_GEN, phase1str))
     105             :                 return CLIENT_ERROR;
     106             : 
     107           0 :         if(asfd->simple_loop(asfd, confs, &tchk,
     108             :                 __func__, maybe_check_timer_func)) return CLIENT_ERROR;
     109           0 :         *resume=tchk.resume;
     110           0 :         return tchk.ret;
     111             : }
     112             : 
     113           0 : static enum cliret backup_wrapper(struct asfd *asfd,
     114             :         enum action action, const char *phase1str,
     115             :         const char *incexc, struct conf **confs)
     116             : {
     117           0 :         int resume=0;
     118           0 :         enum cliret ret=CLIENT_OK;
     119           0 :         const char *b_script_pre=get_string(confs[OPT_B_SCRIPT_PRE]);
     120           0 :         const char *b_script_post=get_string(confs[OPT_B_SCRIPT_POST]);
     121             : 
     122             :         // Set bulk packets quality of service flags on backup.
     123           0 :         if(incexc)
     124             :         {
     125           0 :                 logp("Server is overriding the configuration\n");
     126           0 :                 logp("with the following settings:\n");
     127           0 :                 if(log_incexcs_buf(incexc)) goto error;
     128             :         }
     129           0 :         if(!get_strlist(confs[OPT_STARTDIR]))
     130             :         {
     131           0 :                 logp("Found no include paths!\n");
     132           0 :                 goto error;
     133             :         }
     134             : 
     135           0 :         switch(maybe_check_timer(asfd, phase1str, confs, &resume))
     136             :         {
     137             :                 case CLIENT_OK:
     138           0 :                         if(action==ACTION_TIMER_CHECK) goto end;
     139             :                         break;
     140             :                 case CLIENT_SERVER_TIMER_NOT_MET:
     141             :                         goto timer_not_met;
     142             :                 case CLIENT_SERVER_MAX_PARALLEL_BACKUPS:
     143             :                         goto max_parallel_backups;
     144             :                 default:
     145             :                         goto error;
     146             :         }
     147             : 
     148           0 :         if(b_script_pre)
     149             :         {
     150           0 :                 int a=0;
     151             :                 const char *args[12];
     152           0 :                 args[a++]=b_script_pre;
     153           0 :                 if(get_int(confs[OPT_B_SCRIPT_RESERVED_ARGS]))
     154             :                 {
     155           0 :                         args[a++]="pre";
     156           0 :                         args[a++]="reserved2";
     157           0 :                         args[a++]="reserved3";
     158           0 :                         args[a++]="reserved4";
     159           0 :                         args[a++]="reserved5";
     160             :                 }
     161           0 :                 args[a++]=NULL;
     162           0 :                 if(run_script(asfd,
     163             :                         args, get_strlist(confs[OPT_B_SCRIPT_PRE_ARG]),
     164             :                         confs, 1, 1, 1))
     165           0 :                                  ret=CLIENT_ERROR;
     166             : 
     167           0 :                 if(get_int(confs[OPT_GLOB_AFTER_SCRIPT_PRE]))
     168             :                 {
     169           0 :                         if(reeval_glob(confs))
     170           0 :                                 ret=CLIENT_ERROR;
     171             :                 }
     172             :         }
     173             : 
     174           0 :         if(ret==CLIENT_OK && do_backup_client(asfd,
     175           0 :                 confs, action, resume)) ret=CLIENT_ERROR;
     176             : 
     177           0 :         if((ret==CLIENT_OK || get_int(confs[OPT_B_SCRIPT_POST_RUN_ON_FAIL]))
     178           0 :           && b_script_post)
     179             :         {
     180           0 :                 int a=0;
     181             :                 const char *args[12];
     182           0 :                 args[a++]=b_script_post;
     183           0 :                 if(get_int(confs[OPT_B_SCRIPT_RESERVED_ARGS]))
     184             :                 {
     185           0 :                         args[a++]="post";
     186             :                         // Tell post script whether the restore failed.
     187           0 :                         args[a++]=ret?"1":"0";
     188           0 :                         args[a++]="reserved3";
     189           0 :                         args[a++]="reserved4";
     190           0 :                         args[a++]="reserved5";
     191             :                 }
     192           0 :                 args[a++]=NULL;
     193             :                 // At this point, the server may have closed the connection,
     194             :                 // so cannot log remotely.
     195           0 :                 if(run_script(asfd,
     196             :                         args, get_strlist(confs[OPT_B_SCRIPT_POST_ARG]),
     197             :                         confs, 1, 1, /*log_remote*/ 0))
     198           0 :                                 ret=CLIENT_ERROR;
     199             :         }
     200             : 
     201           0 :         if(ret==CLIENT_OK) logp("backup finished ok\n");
     202             : 
     203             : end:
     204             :         // The include_logic/exclude_logic cache may have been populated
     205             :         // during backup so we clean it here
     206           0 :         free_logic_cache();
     207           0 :         return ret;
     208             : error:
     209           0 :         logp("error in backup\n");
     210           0 :         return CLIENT_ERROR;
     211             : timer_not_met:
     212             :         return CLIENT_SERVER_TIMER_NOT_MET;
     213             : max_parallel_backups:
     214           0 :         return CLIENT_SERVER_MAX_PARALLEL_BACKUPS;
     215             : }
     216             : 
     217             : static int s_server_session_id_context=1;
     218             : 
     219           0 : static int ssl_setup(int *rfd, SSL **ssl, SSL_CTX **ctx,
     220             :         enum action action, struct conf **confs, const char *server,
     221             :         struct strlist *failover)
     222             : {
     223           0 :         int ret=-1;
     224           0 :         int port=0;
     225           0 :         char portstr[8]="";
     226           0 :         BIO *sbio=NULL;
     227           0 :         ssl_load_globals();
     228           0 :         char *cp=NULL;
     229           0 :         char *server_copy=NULL;
     230             :         int ssl_ret;
     231             : 
     232           0 :         if(!(server_copy=strdup_w(server, __func__)))
     233             :                 goto end;
     234             : 
     235           0 :         if(!(*ctx=ssl_initialise_ctx(confs)))
     236             :         {
     237           0 :                 logp("error initialising ssl ctx\n");
     238             :                 goto end;
     239             :         }
     240             : 
     241           0 :         if((cp=strrchr(server_copy, ':')))
     242             :         {
     243           0 :                 *cp='\0';
     244           0 :                 port=atoi(cp+1);
     245             :         }
     246             : 
     247           0 :         SSL_CTX_set_session_id_context(*ctx,
     248             :                 (const uint8_t *)&s_server_session_id_context,
     249             :                 sizeof(s_server_session_id_context));
     250             : 
     251           0 :         switch(action)
     252             :         {
     253             :                 case ACTION_BACKUP:
     254             :                 case ACTION_BACKUP_TIMED:
     255             :                 case ACTION_TIMER_CHECK:
     256           0 :                         if(get_int(confs[OPT_PORT_BACKUP]))
     257           0 :                                 port=get_int(confs[OPT_PORT_BACKUP]);
     258             :                         break;
     259             :                 case ACTION_RESTORE:
     260           0 :                         if(get_int(confs[OPT_PORT_RESTORE]))
     261           0 :                                 port=get_int(confs[OPT_PORT_RESTORE]);
     262             :                         break;
     263             :                 case ACTION_VERIFY:
     264           0 :                         if(get_int(confs[OPT_PORT_VERIFY]))
     265           0 :                                 port=get_int(confs[OPT_PORT_VERIFY]);
     266             :                         break;
     267             :                 case ACTION_LIST:
     268             :                 case ACTION_LIST_LONG:
     269             :                 case ACTION_LIST_PARSEABLE:
     270             :                 case ACTION_DIFF:
     271             :                 case ACTION_DIFF_LONG:
     272           0 :                         if(get_int(confs[OPT_PORT_LIST]))
     273           0 :                                 port=get_int(confs[OPT_PORT_LIST]);
     274             :                         break;
     275             :                 case ACTION_DELETE:
     276           0 :                         if(get_int(confs[OPT_PORT_DELETE]))
     277           0 :                                 port=get_int(confs[OPT_PORT_DELETE]);
     278             :                         break;
     279             :                 case ACTION_MONITOR:
     280             :                 {
     281             :                         struct strlist *s;
     282           0 :                         if(!(s=get_strlist(confs[OPT_STATUS_PORT])))
     283             :                         {
     284           0 :                                 logp("%s not set\n",
     285           0 :                                         confs[OPT_STATUS_PORT]->field);
     286             :                                 goto end;
     287             :                         }
     288           0 :                         port=atoi(s->path);
     289             :                         break;
     290             :                 }
     291             :                 case ACTION_CHAMP_CHOOSER:
     292             :                 case ACTION_ESTIMATE:
     293             :                 case ACTION_STATUS:
     294             :                 case ACTION_STATUS_SNAPSHOT:
     295             :                 case ACTION_UNSET:
     296           0 :                         logp("Unexpected action in %s: %d\n",
     297             :                                 __func__, action);
     298             :                         goto end;
     299             :         }
     300             : 
     301           0 :         snprintf(portstr, sizeof(portstr), "%d", port);
     302           0 :         if((*rfd=init_client_socket(server_copy, portstr))<0)
     303             :                 goto end;
     304             : 
     305           0 :         if(!(*ssl=SSL_new(*ctx))
     306           0 :           || !(sbio=BIO_new_socket(*rfd, BIO_NOCLOSE)))
     307             :         {
     308           0 :                 logp_ssl_err("Problem joining SSL to the socket\n");
     309             :                 goto end;
     310             :         }
     311           0 :         SSL_set_bio(*ssl, sbio, sbio);
     312           0 :         if((ssl_ret=SSL_connect(*ssl))<=0)
     313             :         {
     314           0 :                 logp_ssl_err("SSL connect error: %d\n",
     315             :                         SSL_get_error(*ssl, ssl_ret));
     316             :                 goto end;
     317             :         }
     318             : 
     319             :         ret=0;
     320             : end:
     321           0 :         free_w(&server_copy);
     322           0 :         return ret;
     323             : }
     324             : 
     325           0 : static enum cliret initial_comms(struct async *as,
     326             :         enum action *action, char **incexc, struct conf **confs,
     327             :         struct strlist *failover)
     328             : {
     329             :         struct asfd *asfd;
     330           0 :         char *server_version=NULL;
     331           0 :         enum cliret ret=CLIENT_OK;
     332           0 :         asfd=as->asfd;
     333             : 
     334           0 :         if(authorise_client(asfd, &server_version,
     335           0 :           get_string(confs[OPT_CNAME]),
     336           0 :           get_string(confs[OPT_PASSWORD]),
     337             :           get_cntr(confs)))
     338             :                 goto error;
     339             : 
     340           0 :         if(server_version)
     341             :         {
     342           0 :                 logp("Server version: %s\n", server_version);
     343             :                 // Servers before 1.3.2 did not tell us their versions.
     344             :                 // 1.3.2 and above can do the automatic CA stuff that
     345             :                 // follows.
     346           0 :                 switch(ca_client_setup(asfd, confs))
     347             :                 {
     348             :                         case 0:
     349             :                                 break; // All OK.
     350             :                         case 1:
     351             :                                 // Certificate signed successfully.
     352             :                                 // Everything is OK, but we will reconnect now,
     353             :                                 // in order to use the new keys/certificates.
     354             :                                 goto reconnect;
     355             :                         default:
     356           0 :                                 logp("Error with cert signing request\n");
     357           0 :                                 goto error;
     358             :                 }
     359             :         }
     360             : 
     361           0 :         if(ssl_check_cert(asfd->ssl, NULL, confs))
     362             :         {
     363           0 :                 logp("check cert failed\n");
     364           0 :                 goto error;
     365             :         }
     366             : 
     367           0 :         if(extra_comms_client(as, confs, action, failover, incexc))
     368             :         {
     369           0 :                 logp("extra comms failed\n");
     370           0 :                 goto error;
     371             :         }
     372             : 
     373             :         ret=CLIENT_OK; goto end;
     374             : error:
     375             :         ret=CLIENT_ERROR; goto end;
     376             : reconnect:
     377             :         ret=CLIENT_RECONNECT; goto end;
     378             : end:
     379           0 :         free_w(&server_version);
     380           0 :         return ret;
     381             : }
     382             : 
     383           0 : static enum cliret restore_wrapper(struct asfd *asfd, enum action action,
     384             :         struct conf **confs)
     385             : {
     386           0 :         enum cliret ret=CLIENT_OK;
     387           0 :         const char *r_script_pre=get_string(confs[OPT_R_SCRIPT_PRE]);
     388           0 :         const char *r_script_post=get_string(confs[OPT_R_SCRIPT_POST]);
     389             : 
     390           0 :         if(r_script_pre)
     391             :         {
     392           0 :                 int a=0;
     393             :                 const char *args[12];
     394           0 :                 args[a++]=r_script_pre;
     395           0 :                 if(get_int(confs[OPT_R_SCRIPT_RESERVED_ARGS]))
     396             :                 {
     397           0 :                         args[a++]="pre";
     398           0 :                         args[a++]="reserved2";
     399           0 :                         args[a++]="reserved3";
     400           0 :                         args[a++]="reserved4";
     401           0 :                         args[a++]="reserved5";
     402             :                 }
     403           0 :                 args[a++]=NULL;
     404           0 :                 if(run_script(asfd,
     405             :                         args, get_strlist(confs[OPT_R_SCRIPT_PRE_ARG]),
     406             :                         confs, 1, 1, 1))
     407           0 :                                 ret=CLIENT_ERROR;
     408             :         }
     409           0 :         if(ret==CLIENT_OK)
     410             :         {
     411           0 :                 if(do_restore_client(asfd, confs,
     412           0 :                         action)) ret=CLIENT_ERROR;
     413             :         }
     414           0 :         if((ret==CLIENT_OK || get_int(confs[OPT_R_SCRIPT_POST_RUN_ON_FAIL]))
     415           0 :           && r_script_post)
     416             :         {
     417           0 :                 int a=0;
     418             :                 const char *args[12];
     419           0 :                 args[a++]=r_script_post;
     420           0 :                 if(get_int(confs[OPT_R_SCRIPT_RESERVED_ARGS]))
     421             :                 {
     422           0 :                         args[a++]="post";
     423             :                         // Tell post script whether the restore failed.
     424           0 :                         args[a++]=ret?"1":"0";
     425           0 :                         args[a++]="reserved3";
     426           0 :                         args[a++]="reserved4";
     427           0 :                         args[a++]="reserved5";
     428             :                 }
     429           0 :                 args[a++]=NULL;
     430           0 :                 if(run_script(asfd,
     431             :                         args, get_strlist(confs[OPT_R_SCRIPT_POST_ARG]),
     432             :                         confs, 1, 1, /*log_remote*/ 0))
     433           0 :                                 ret=CLIENT_ERROR;
     434             :         }
     435             : 
     436             :         // Return non-zero if there were warnings,
     437             :         // so that the test script can easily check.
     438           0 :         if(ret==CLIENT_OK && get_cntr(confs)->ent[CMD_WARNING]->count)
     439           0 :                 ret=CLIENT_RESTORE_WARNINGS;
     440             : 
     441           0 :         return ret;
     442             : }
     443             : 
     444           0 : static enum cliret do_client(struct conf **confs,
     445             :         enum action action, const char *server,
     446             :         struct strlist *failover)
     447             : {
     448           0 :         enum cliret ret=CLIENT_OK;
     449           0 :         int rfd=-1;
     450           0 :         SSL *ssl=NULL;
     451           0 :         SSL_CTX *ctx=NULL;
     452           0 :         struct cntr *cntr=NULL;
     453           0 :         char *incexc=NULL;
     454           0 :         enum action act=action;
     455           0 :         struct async *as=NULL;
     456           0 :         struct asfd *asfd=NULL;
     457             : 
     458             : //      as->settimers(0, 100);
     459             : 
     460             : //      logp("begin client\n");
     461             : //      logp("action %d\n", action);
     462             : 
     463             :         // Status monitor forks a child process instead of connecting to
     464             :         // the server directly.
     465           0 :         if(action==ACTION_STATUS
     466           0 :           || action==ACTION_STATUS_SNAPSHOT)
     467             :         {
     468             : #ifdef HAVE_WIN32
     469             :                 logp("Status mode not implemented on Windows.\n");
     470             :                 goto error;
     471             : #endif
     472           0 :                 if(status_client_ncurses_init(act)
     473           0 :                   || status_client_ncurses(confs)) ret=CLIENT_ERROR;
     474             :                 goto end;
     475             :         }
     476             : 
     477           0 :         if(!(cntr=cntr_alloc())
     478           0 :           || cntr_init(cntr, get_string(confs[OPT_CNAME]), getpid()))
     479             :                 goto error;
     480           0 :         set_cntr(confs[OPT_CNTR], cntr);
     481             : 
     482           0 :         if(act!=ACTION_ESTIMATE)
     483             :         {
     484           0 :                 if(ssl_setup(&rfd,
     485             :                         &ssl, &ctx, action, confs, server, failover))
     486             :                                 goto could_not_connect;
     487             : 
     488           0 :                 if(!(as=async_alloc())
     489           0 :                   || as->init(as, act==ACTION_ESTIMATE)
     490           0 :                   || !(asfd=setup_asfd_ssl(as, "main socket", &rfd, ssl)))
     491             :                         goto end;
     492           0 :                 asfd->set_timeout(asfd, get_int(confs[OPT_NETWORK_TIMEOUT]));
     493           0 :                 asfd->ratelimit=get_float(confs[OPT_RATELIMIT]);
     494             : 
     495             :                 // Set quality of service bits on backup packets.
     496           0 :                 if(act==ACTION_BACKUP
     497           0 :                                 || act==ACTION_BACKUP_TIMED
     498           0 :                                 || act==ACTION_TIMER_CHECK)
     499           0 :                         as->asfd->set_bulk_packets(as->asfd);
     500             : 
     501           0 :                 if((ret=initial_comms(as, &act, &incexc, confs, failover)))
     502             :                         goto end;
     503             :         }
     504             : 
     505           0 :         rfd=-1;
     506           0 :         switch(act)
     507             :         {
     508             :                 case ACTION_BACKUP:
     509           0 :                         ret=backup_wrapper(asfd, act, "backupphase1",
     510             :                           incexc, confs);
     511           0 :                         break;
     512             :                 case ACTION_BACKUP_TIMED:
     513           0 :                         ret=backup_wrapper(asfd, act, "backupphase1timed",
     514             :                           incexc, confs);
     515           0 :                         break;
     516             :                 case ACTION_TIMER_CHECK:
     517           0 :                         ret=backup_wrapper(asfd, act, "backupphase1timedcheck",
     518             :                           incexc, confs);
     519           0 :                         break;
     520             :                 case ACTION_RESTORE:
     521             :                 case ACTION_VERIFY:
     522           0 :                         ret=restore_wrapper(asfd, act, confs);
     523           0 :                         break;
     524             :                 case ACTION_ESTIMATE:
     525           0 :                         if(do_backup_client(asfd, confs, act, 0))
     526             :                                 goto error;
     527             :                         break;
     528             :                 case ACTION_DELETE:
     529           0 :                         if(do_delete_client(asfd, confs))
     530             :                                 goto error;
     531             :                         break;
     532             :                 case ACTION_MONITOR:
     533           0 :                         if(do_monitor_client(asfd))
     534             :                                 goto error;
     535             :                         break;
     536             :                 case ACTION_DIFF:
     537             :                 case ACTION_DIFF_LONG:
     538             : /*
     539             :                         if(!strcmp(get_string(confs[OPT_BACKUP2]), "n"))
     540             :                                 // Do a phase1 scan and diff that.
     541             :                                 ret=backup_wrapper(asfd, act,
     542             :                                         "backupphase1diff", incexc, confs);
     543             :                         else
     544             : */
     545             :                         // Diff two backups that already exist.
     546             :                         // Fall through, the list code is all we need
     547             :                         // for simple diffs on the client side.
     548             :                 case ACTION_LIST:
     549             :                 case ACTION_LIST_LONG:
     550             :                 case ACTION_LIST_PARSEABLE:
     551             :                 default:
     552           0 :                         if(do_list_client(asfd, act, confs)) goto error;
     553             :                         break;
     554             :         }
     555             : 
     556           0 :         if(asfd_flush_asio(asfd))
     557           0 :                 ret=CLIENT_ERROR;
     558             : 
     559             :         goto end;
     560             : error:
     561             :         ret=CLIENT_ERROR; goto end;
     562             : could_not_connect:
     563             :         ret=CLIENT_COULD_NOT_CONNECT;
     564             : end:
     565           0 :         close_fd(&rfd);
     566           0 :         async_free(&as);
     567           0 :         asfd_free(&asfd);
     568           0 :         if(ctx) ssl_destroy_ctx(ctx);
     569           0 :         free_w(&incexc);
     570           0 :         set_cntr(confs[OPT_CNTR], NULL);
     571           0 :         cntr_free(&cntr);
     572             : 
     573             :         //logp("end client\n");
     574           0 :         return ret;
     575             : }
     576             : 
     577           0 : int client(struct conf **confs,
     578             :         enum action action)
     579             : {
     580           0 :         int finished=0;
     581           0 :         enum cliret ret=CLIENT_OK;
     582           0 :         const char *server=NULL;
     583           0 :         struct strlist *failover=NULL;
     584             : 
     585           0 :         if(!get_int(confs[OPT_ENABLED]))
     586             :         {
     587           0 :                 logp("Client not enabled\n");
     588           0 :                 return ret;
     589             :         }
     590             : 
     591             : #ifdef HAVE_WIN32
     592             :         // prevent sleep when idle
     593             :         SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
     594             : #endif
     595           0 :         server=get_string(confs[OPT_SERVER]);
     596           0 :         failover=get_strlist(confs[OPT_SERVER_FAILOVER]);
     597             : 
     598           0 :         while(!finished)
     599             :         {
     600           0 :                 ret=do_client(confs,
     601             :                         action, server, failover);
     602           0 :                 if(ret==CLIENT_RECONNECT)
     603             :                 {
     604           0 :                         logp("Re-opening connection to %s\n", server);
     605           0 :                         sleep(5);
     606           0 :                         ret=do_client(confs,
     607             :                                 action, server, failover);
     608             :                 }
     609           0 :                 switch(ret)
     610             :                 {
     611             :                         case CLIENT_OK:
     612             :                         case CLIENT_SERVER_TIMER_NOT_MET:
     613             :                         case CLIENT_SERVER_MAX_PARALLEL_BACKUPS:
     614             :                         case CLIENT_RESTORE_WARNINGS:
     615           0 :                                 finished=1;
     616           0 :                                 break;
     617             :                         case CLIENT_ERROR:
     618           0 :                                 if(action!=ACTION_BACKUP
     619           0 :                                   && action!=ACTION_BACKUP_TIMED)
     620             :                                 {
     621             :                                         finished=1;
     622             :                                         break;
     623             :                                 }
     624           0 :                                 if(!get_int(
     625             :                                         confs[OPT_FAILOVER_ON_BACKUP_ERROR]))
     626             :                                 {
     627             :                                         finished=1;
     628             :                                         break;
     629             :                                 }
     630             :                                 // Fall through to failover.
     631             :                         case CLIENT_COULD_NOT_CONNECT:
     632           0 :                                 if(!failover)
     633             :                                 {
     634             :                                         finished=1;
     635             :                                         break;
     636             :                                 }
     637           0 :                                 logp("Failing over\n");
     638             :                                 // Use a failover server.
     639           0 :                                 server=failover->path;
     640           0 :                                 failover=failover->next;
     641           0 :                                 break;
     642             :                         case CLIENT_RECONNECT:
     643           0 :                                 logp("Multiple reconnect requests to %s- this should not happen!", server);
     644           0 :                                 finished=1;
     645           0 :                                 break;
     646             :                 }
     647             :         }
     648             : 
     649             : #ifdef HAVE_WIN32
     650             :         // allow sleep when idle
     651             :         SetThreadExecutionState(ES_CONTINUOUS);
     652             : #endif
     653             : 
     654             :         // See enum cliret for return codes.
     655           0 :         return (int)ret;
     656             : }

Generated by: LCOV version 1.13