LCOV - code coverage report
Current view: top level - src/server - restore.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 183 287 63.8 %
Date: 2016-01-31 Functions: 12 15 80.0 %

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../alloc.h"
       3             : #include "../asfd.h"
       4             : #include "../async.h"
       5             : #include "../bu.h"
       6             : #include "../cmd.h"
       7             : #include "../cntr.h"
       8             : #include "../handy.h"
       9             : #include "../linkhash.h"
      10             : #include "../log.h"
      11             : #include "../pathcmp.h"
      12             : #include "../prepend.h"
      13             : #include "../protocol2/blk.h"
      14             : #include "../regexp.h"
      15             : #include "../slist.h"
      16             : #include "../strlist.h"
      17             : #include "bu_get.h"
      18             : #include "child.h"
      19             : #include "compress.h"
      20             : #include "manio.h"
      21             : #include "protocol1/restore.h"
      22             : #include "protocol2/dpth.h"
      23             : #include "protocol2/rblk.h"
      24             : #include "protocol2/restore.h"
      25             : #include "protocol2/restore_spool.h"
      26             : #include "sdirs.h"
      27             : 
      28           5 : static enum asl_ret restore_end_func(struct asfd *asfd,
      29             :         struct conf **confs, void *param)
      30             : {
      31           5 :         if(!strcmp(asfd->rbuf->buf, "restoreend_ok"))
      32             :                 return ASL_END_OK;
      33           0 :         iobuf_log_unexpected(asfd->rbuf, __func__);
      34           0 :         return ASL_END_ERROR;
      35             : }
      36             : 
      37           5 : static int restore_end(struct asfd *asfd, struct conf **confs)
      38             : {
      39           5 :         if(asfd->write_str(asfd, CMD_GEN, "restoreend")) return -1;
      40           5 :         return asfd->simple_loop(asfd, confs, NULL, __func__, restore_end_func);
      41             : }
      42             : 
      43           0 : static int srestore_matches(struct strlist *s, const char *path)
      44             : {
      45           0 :         int r=0;
      46           0 :         if(!s->flag) return 0; // Do not know how to do excludes yet.
      47           0 :         if((r=strncmp_w(path, s->path))) return 0; // no match
      48           0 :         if(!r) return 1; // exact match
      49           0 :         if(*(path+strlen(s->path)+1)=='/')
      50             :                 return 1; // matched directory contents
      51             :         return 0; // no match
      52             : }
      53             : 
      54             : // Used when restore is initiated from the server.
      55           0 : static int check_srestore(struct conf **confs, const char *path)
      56             : {
      57           0 :         struct strlist *l=get_strlist(confs[OPT_INCEXCDIR]);
      58             : 
      59             :         // If no includes specified, restore everything.
      60           0 :         if(!l) return 1;
      61             : 
      62           0 :         for(; l; l=l->next)
      63           0 :                 if(srestore_matches(l, path))
      64             :                         return 1;
      65             :         return 0;
      66             : }
      67             : 
      68          42 : int want_to_restore(int srestore, struct sbuf *sb,
      69             :         regex_t *regex, struct conf **cconfs)
      70             : {
      71           0 :         return (!srestore || check_srestore(cconfs, sb->path.buf))
      72          84 :           && (!regex || regex_check(regex, sb->path.buf));
      73             : }
      74             : 
      75           5 : static int setup_cntr(struct asfd *asfd, const char *manifest,
      76             :         regex_t *regex, int srestore,
      77             :         enum action act, char status, struct conf **cconfs)
      78             : {
      79           5 :         int ars=0;
      80           5 :         int ret=-1;
      81           5 :         struct fzp *fzp=NULL;
      82           5 :         struct sbuf *sb=NULL;
      83           5 :         struct cntr *cntr=NULL;
      84             : 
      85           5 :         cntr=get_cntr(cconfs);
      86           5 :         if(!cntr) return 0;
      87             : 
      88             : // FIX THIS: this is only trying to work for protocol1.
      89           0 :         if(get_protocol(cconfs)!=PROTO_1) return 0;
      90             : 
      91           0 :         if(!(sb=sbuf_alloc(PROTO_1))) goto end;
      92           0 :         if(!(fzp=fzp_gzopen(manifest, "rb")))
      93             :         {
      94           0 :                 log_and_send(asfd, "could not open manifest");
      95             :                 goto end;
      96             :         }
      97             :         while(1)
      98             :         {
      99           0 :                 if((ars=sbuf_fill_from_file(sb, fzp, NULL, NULL)))
     100             :                 {
     101           0 :                         if(ars<0) goto end;
     102             :                         // ars==1 means end ok
     103             :                         break;
     104             :                 }
     105             :                 else
     106             :                 {
     107           0 :                         if(want_to_restore(srestore, sb, regex, cconfs))
     108             :                         {
     109           0 :                                 cntr_add_phase1(cntr, sb->path.cmd, 0);
     110           0 :                                 if(sb->endfile.buf)
     111             :                                   cntr_add_val(cntr,
     112             :                                         CMD_BYTES_ESTIMATED,
     113             :                                         strtoull(sb->endfile.buf,
     114           0 :                                                 NULL, 10), 0);
     115             :                         }
     116             :                 }
     117           0 :                 sbuf_free_content(sb);
     118             :         }
     119           0 :         ret=0;
     120             : end:
     121           0 :         sbuf_free(&sb);
     122           0 :         fzp_close(&fzp);
     123             :         return ret;
     124             : }
     125             : 
     126             : static int restore_sbuf(struct asfd *asfd, struct sbuf *sb, struct bu *bu,
     127             :         enum action act, struct sdirs *sdirs, enum cntr_status cntr_status,
     128             :         struct conf **cconfs, struct sbuf *need_data, const char *manifest,
     129             :         struct slist *slist);
     130             : 
     131             : // Used when restoring a hard link that we have not restored the destination
     132             : // for. Read through the manifest from the beginning and substitute the path
     133             : // and data to the new location.
     134           0 : static int hard_link_substitution(struct asfd *asfd,
     135             :         struct sbuf *sb, struct f_link *lp,
     136             :         struct bu *bu, enum action act, struct sdirs *sdirs,
     137             :         enum cntr_status cntr_status, struct conf **cconfs,
     138             :         const char *manifest, struct slist *slist)
     139             : {
     140           0 :         int ret=-1;
     141           0 :         struct sbuf *need_data=NULL;
     142           0 :         int last_ent_was_dir=0;
     143           0 :         struct sbuf *hb=NULL;
     144           0 :         struct manio *manio=NULL;
     145           0 :         struct blk *blk=NULL;
     146             :         int pcmp;
     147           0 :         enum protocol protocol=get_protocol(cconfs);
     148           0 :         struct cntr *cntr=get_cntr(cconfs);
     149             : 
     150           0 :         if(!(manio=manio_open(manifest, "rb", protocol))
     151           0 :           || !(need_data=sbuf_alloc(protocol))
     152           0 :           || !(hb=sbuf_alloc(protocol)))
     153             :                 goto end;
     154             : 
     155           0 :         if(protocol==PROTO_2)
     156             :         {
     157           0 :                   if(!(blk=blk_alloc()))
     158             :                         goto end;
     159             :         }
     160             : 
     161             :         while(1)
     162             :         {
     163           0 :                 switch(manio_read_with_blk(manio,
     164           0 :                         hb, need_data->path.buf?blk:NULL, sdirs))
     165             :                 {
     166             :                         case 0: break; // Keep going.
     167           0 :                         case 1: ret=0; goto end; // Finished OK.
     168             :                         default: goto end; // Error;
     169             :                 }
     170             : 
     171           0 :                 if(protocol==PROTO_2)
     172             :                 {
     173           0 :                         if(hb->endfile.buf)
     174             :                         {
     175           0 :                                 sbuf_free_content(hb);
     176             :                                 continue;
     177             :                         }
     178           0 :                         if(blk->data)
     179             :                         {
     180           0 :                                 if(protocol2_extra_restore_stream_bits(asfd,
     181             :                                         blk, slist, act, need_data,
     182           0 :                                         last_ent_was_dir, cntr)) goto end;
     183             :                                 continue;
     184             :                         }
     185           0 :                         sbuf_free_content(need_data);
     186             :                 }
     187             : 
     188           0 :                 pcmp=pathcmp(lp->name, hb->path.buf);
     189             : 
     190           0 :                 if(!pcmp && (sbuf_is_filedata(hb) || sbuf_is_vssdata(hb)))
     191             :                 {
     192             :                         // Copy the path from sb to hb.
     193           0 :                         free_w(&hb->path.buf);
     194           0 :                         if(!(hb->path.buf=strdup_w(sb->path.buf, __func__)))
     195             :                                 goto end;
     196             :                         // Should now be able to restore the original data
     197             :                         // to the new location.
     198             :                         ret=restore_sbuf(asfd, hb, bu, act, sdirs,
     199           0 :                           cntr_status, cconfs, need_data, manifest, slist);
     200             :                         // May still need to get protocol2 data.
     201           0 :                         if(!ret && need_data->path.buf) continue;
     202             :                         break;
     203             :                 }
     204             : 
     205           0 :                 sbuf_free_content(hb);
     206             :                 // Break out once we have gone past the entry that we are
     207             :                 // interested in.
     208           0 :                 if(pcmp<0) break;
     209             :         }
     210             : end:
     211           0 :         blk_free(&blk);
     212           0 :         sbuf_free(&hb);
     213           0 :         manio_close(&manio);
     214           0 :         return ret;
     215             : }
     216             : 
     217          42 : static int restore_sbuf(struct asfd *asfd, struct sbuf *sb, struct bu *bu,
     218             :         enum action act, struct sdirs *sdirs, enum cntr_status cntr_status,
     219             :         struct conf **cconfs, struct sbuf *need_data, const char *manifest,
     220             :         struct slist *slist)
     221             : {
     222             :         //printf("%s: %s\n", act==ACTION_RESTORE?"restore":"verify", sb->path.buf);
     223          42 :         if(write_status(cntr_status, sb->path.buf, get_cntr(cconfs)))
     224             :                 return -1;
     225             : 
     226          42 :         if(sb->path.cmd==CMD_HARD_LINK)
     227             :         {
     228           1 :                 struct f_link *lp=NULL;
     229           1 :                 struct f_link **bucket=NULL;
     230           1 :                 if((lp=linkhash_search(&sb->statp, &bucket)))
     231             :                 {
     232             :                         // It is in the list of stuff that is in the manifest,
     233             :                         // but was skipped on this restore.
     234             :                         // Need to go through the manifest from the beginning,
     235             :                         // and substitute in the data to restore to this
     236             :                         // location.
     237             :                         return hard_link_substitution(asfd, sb, lp,
     238             :                                 bu, act, sdirs,
     239           0 :                                 cntr_status, cconfs, manifest, slist);
     240             :                         // FIX THIS: Would be nice to remember the new link
     241             :                         // location so that further hard links would link to
     242             :                         // it instead of doing the hard_link_substitution
     243             :                         // business over again.
     244             :                 }
     245             :         }
     246             : 
     247          42 :         if(get_protocol(cconfs)==PROTO_1)
     248             :         {
     249             :                 return restore_sbuf_protocol1(asfd, sb, bu,
     250          10 :                   act, sdirs, cntr_status, cconfs);
     251             :         }
     252             :         else
     253             :         {
     254             :                 return restore_sbuf_protocol2(asfd, sb,
     255          32 :                   act, cntr_status, get_cntr(cconfs), need_data);
     256             :         }
     257             : }
     258             : 
     259          42 : int restore_ent(struct asfd *asfd,
     260             :         struct sbuf **sb,
     261             :         struct slist *slist,
     262             :         struct bu *bu,
     263             :         enum action act,
     264             :         struct sdirs *sdirs,
     265             :         enum cntr_status cntr_status,
     266             :         struct conf **cconfs,
     267             :         struct sbuf *need_data,
     268             :         int *last_ent_was_dir,
     269             :         const char *manifest)
     270             : {
     271          42 :         int ret=-1;
     272             :         struct sbuf *xb;
     273             : 
     274          42 :         if(!(*sb)->path.buf)
     275             :         {
     276           0 :                 logp("Got NULL path!\n");
     277           0 :                 return -1;
     278             :         }
     279             : 
     280             :         // Check if we have any directories waiting to be restored.
     281          42 :         while((xb=slist->head))
     282             :         {
     283           0 :                 if(is_subdir(xb->path.buf, (*sb)->path.buf))
     284             :                 {
     285             :                         // We are still in a subdir.
     286             :                         break;
     287             :                 }
     288             :                 else
     289             :                 {
     290             :                         // Can now restore xb because nothing else is fiddling
     291             :                         // in a subdirectory.
     292           0 :                         if(restore_sbuf(asfd, xb, bu,
     293             :                           act, sdirs, cntr_status, cconfs, need_data, manifest,
     294           0 :                           slist))
     295             :                                 goto end;
     296           0 :                         slist->head=xb->next;
     297           0 :                         sbuf_free(&xb);
     298             :                 }
     299             :         }
     300             : 
     301             :         /* If it is a directory, need to remember it and restore it later, so
     302             :            that the permissions come out right. */
     303             :         /* Meta data of directories will also have the stat stuff set to be a
     304             :            directory, so will also come out at the end. */
     305             :         /* FIX THIS: for Windows, need to read and remember the blocks that
     306             :            go with the directories. Probably have to do the same for metadata
     307             :            that goes with directories. */
     308          42 :         if(S_ISDIR((*sb)->statp.st_mode))
     309             :         {
     310             :                 // Add to the head of the list instead of the tail.
     311           0 :                 (*sb)->next=slist->head;
     312           0 :                 slist->head=*sb;
     313             : 
     314           0 :                 *last_ent_was_dir=1;
     315             : 
     316             :                 // Allocate a new sb.
     317           0 :                 if(!(*sb=sbuf_alloc(get_protocol(cconfs)))) goto end;
     318             :         }
     319             :         else
     320             :         {
     321          42 :                 *last_ent_was_dir=0;
     322          42 :                 if(restore_sbuf(asfd, *sb, bu,
     323             :                   act, sdirs, cntr_status, cconfs, need_data, manifest,
     324          42 :                   slist))
     325             :                         goto end;
     326             :         }
     327             :         ret=0;
     328             : end:
     329          42 :         return ret;
     330             : }
     331             : 
     332           5 : static int restore_remaining_dirs(struct asfd *asfd, struct bu *bu,
     333             :         struct slist *slist, enum action act, struct sdirs *sdirs,
     334             :         enum cntr_status cntr_status, struct conf **cconfs)
     335             : {
     336           5 :         int ret=-1;
     337             :         struct sbuf *sb;
     338           5 :         struct sbuf *need_data=NULL;
     339           5 :         if(!(need_data=sbuf_alloc(get_protocol(cconfs)))) goto end;
     340             :         // Restore any directories that are left in the list.
     341           5 :         for(sb=slist->head; sb; sb=sb->next)
     342             :         {
     343           0 :                 if(get_protocol(cconfs)==PROTO_1)
     344             :                 {
     345           0 :                         if(restore_sbuf_protocol1(asfd, sb, bu, act,
     346           0 :                                 sdirs, cntr_status, cconfs))
     347             :                                         goto end;
     348             :                 }
     349             :                 else
     350             :                 {
     351           0 :                         if(restore_sbuf_protocol2(asfd, sb, act,
     352           0 :                                 cntr_status, get_cntr(cconfs), need_data))
     353             :                                         goto end;
     354             :                 }
     355             :         }
     356             :         ret=0;
     357             : end:
     358           5 :         sbuf_free(&need_data);
     359           5 :         return ret;
     360             : }
     361             : 
     362           5 : static int restore_stream(struct asfd *asfd, struct sdirs *sdirs,
     363             :         struct slist *slist, struct bu *bu, const char *manifest,
     364             :         regex_t *regex, int srestore, struct conf **cconfs, enum action act,
     365             :         enum cntr_status cntr_status)
     366             : {
     367           5 :         int ret=-1;
     368           5 :         int last_ent_was_dir=0;
     369           5 :         struct sbuf *sb=NULL;
     370           5 :         struct iobuf *rbuf=asfd->rbuf;
     371           5 :         struct manio *manio=NULL;
     372           5 :         struct blk *blk=NULL;
     373           5 :         struct sbuf *need_data=NULL;
     374           5 :         enum protocol protocol=get_protocol(cconfs);
     375           5 :         struct cntr *cntr=get_cntr(cconfs);
     376             :         struct iobuf interrupt;
     377           5 :         iobuf_init(&interrupt);
     378             : 
     379           5 :         if(protocol==PROTO_2)
     380             :         {
     381             :                 static int rs_sent=0;
     382           4 :                 if(!(blk=blk_alloc()))
     383             :                         goto end;
     384           4 :                 if(!rs_sent)
     385             :                 {
     386           4 :                         rs_sent=1;
     387           4 :                         if(asfd->write_str(asfd,
     388           4 :                                 CMD_GEN, "restore_stream")
     389           8 :                           || asfd_read_expect(asfd,
     390           4 :                                 CMD_GEN, "restore_stream_ok"))
     391             :                                         goto end;
     392             :                 }
     393             :         }
     394             : 
     395          10 :         if(!(manio=manio_open(manifest, "rb", protocol))
     396           5 :           || !(need_data=sbuf_alloc(protocol))
     397          10 :           || !(sb=sbuf_alloc(protocol)))
     398             :                 goto end;
     399             : 
     400             :         while(1)
     401             :         {
     402         421 :                 iobuf_free_content(rbuf);
     403         421 :                 if(asfd->as->read_quick(asfd->as))
     404             :                 {
     405           0 :                         logp("read quick error\n");
     406           0 :                         goto end;
     407             :                 }
     408         421 :                 if(rbuf->buf) switch(rbuf->cmd)
     409             :                 {
     410             :                         case CMD_MESSAGE:
     411             :                         case CMD_WARNING:
     412             :                         {
     413           0 :                                 log_recvd(rbuf, cntr, 0);
     414           0 :                                 continue;
     415             :                         }
     416             :                         case CMD_INTERRUPT:
     417           5 :                                 if(protocol==PROTO_2)
     418             :                                 {
     419           5 :                                         iobuf_free_content(&interrupt);
     420           5 :                                         iobuf_move(&interrupt, rbuf);
     421             :                                 }
     422             :                                 // PROTO_1:
     423             :                                 // Client wanted to interrupt the
     424             :                                 // sending of a file. But if we are
     425             :                                 // here, we have already moved on.
     426             :                                 // Ignore.
     427             :                                 continue;
     428             :                         default:
     429           0 :                                 iobuf_log_unexpected(rbuf, __func__);
     430           0 :                                 goto end;
     431             :                 }
     432             : 
     433         416 :                 switch(manio_read_with_blk(manio,
     434         416 :                         sb, need_data->path.buf?blk:NULL, sdirs))
     435             :                 {
     436             :                         case 0: break; // Keep going.
     437           5 :                         case 1: ret=0; goto end; // Finished OK.
     438             :                         default: goto end; // Error;
     439             :                 }
     440             : 
     441         411 :                 if(protocol==PROTO_2)
     442             :                 {
     443         401 :                         if(sb->endfile.buf)
     444             :                         {
     445          21 :                                 if(act==ACTION_RESTORE
     446          21 :                                   && asfd->write(asfd, &sb->endfile))
     447             :                                         goto end;
     448          21 :                                 sbuf_free_content(sb);
     449          21 :                                 iobuf_free_content(&interrupt);
     450          21 :                                 continue;
     451             :                         }
     452         380 :                         if(interrupt.buf)
     453             :                         {
     454          61 :                                 if(!need_data->path.buf)
     455             :                                 {
     456           1 :                                         iobuf_free_content(&interrupt);
     457             :                                 }
     458          60 :                                 else if(!iobuf_pathcmp(&need_data->path,
     459          60 :                                         &interrupt))
     460             :                                 {
     461          32 :                                         if(blk->data)
     462          32 :                                                 blk->data=NULL;
     463             :                                         continue;
     464             :                                 }
     465             :                         }
     466         348 :                         if(blk->data)
     467             :                         {
     468         316 :                                 if(protocol2_extra_restore_stream_bits(asfd,
     469             :                                         blk, slist, act, need_data,
     470         316 :                                         last_ent_was_dir, cntr)) goto end;
     471             :                                 continue;
     472             :                         }
     473          32 :                         sbuf_free_content(need_data);
     474             :                 }
     475             : 
     476          42 :                 if(want_to_restore(srestore, sb, regex, cconfs))
     477             :                 {
     478          42 :                         if(restore_ent(asfd, &sb, slist,
     479             :                                 bu, act, sdirs, cntr_status, cconfs,
     480          42 :                                 need_data, &last_ent_was_dir, manifest))
     481             :                                         goto end;
     482             :                 }
     483           0 :                 else if(sbuf_is_filedata(sb) || sbuf_is_vssdata(sb))
     484             :                 {
     485             :                         // Add it to the list of filedata that was not
     486             :                         // restored.
     487           0 :                         struct f_link **bucket=NULL;
     488           0 :                         if(!linkhash_search(&sb->statp, &bucket)
     489           0 :                           && linkhash_add(sb->path.buf, &sb->statp, bucket))
     490             :                                 goto end;
     491             :                 }
     492             : 
     493          42 :                 sbuf_free_content(sb);
     494             :         }
     495             : end:
     496           5 :         blk_free(&blk);
     497           5 :         sbuf_free(&sb);
     498           5 :         sbuf_free(&need_data);
     499           5 :         iobuf_free_content(rbuf);
     500           5 :         iobuf_free_content(&interrupt);
     501           5 :         manio_close(&manio);
     502           5 :         return ret;
     503             : }
     504             : 
     505           5 : static int actual_restore(struct asfd *asfd, struct bu *bu,
     506             :         const char *manifest, regex_t *regex, int srestore, enum action act,
     507             :         struct sdirs *sdirs, enum cntr_status cntr_status, struct conf **cconfs)
     508             : {
     509           5 :         int ret=-1;
     510           5 :         int do_restore_stream=1;
     511             :         // For out-of-sequence directory restoring so that the
     512             :         // timestamps come out right:
     513           5 :         struct slist *slist=NULL;
     514           5 :         struct cntr *cntr=NULL;
     515             : 
     516          10 :         if(linkhash_init()
     517           5 :           || !(slist=slist_alloc()))
     518             :                 goto end;
     519             : 
     520           5 :         if(get_protocol(cconfs)==PROTO_2)
     521             :         {
     522           4 :                 if(rblk_init())
     523             :                         goto end;
     524           4 :                 switch(maybe_restore_spool(asfd, manifest, sdirs, bu,
     525           4 :                         srestore, regex, cconfs, slist, act, cntr_status))
     526             :                 {
     527             :                         case 1: do_restore_stream=0; break;
     528           4 :                         case 0: do_restore_stream=1; break;
     529             :                         default: goto end; // Error;
     530             :                 }
     531             :         }
     532          10 :         if(do_restore_stream && restore_stream(asfd, sdirs, slist,
     533             :                 bu, manifest, regex,
     534           5 :                 srestore, cconfs, act, cntr_status))
     535             :                         goto end;
     536             : 
     537           5 :         if(restore_remaining_dirs(asfd, bu, slist,
     538           5 :                 act, sdirs, cntr_status, cconfs)) goto end;
     539             : 
     540           5 :         if(cconfs) cntr=get_cntr(cconfs);
     541           5 :         cntr_print(cntr, act);
     542           5 :         cntr_stats_to_file(cntr, bu->path, act, cconfs);
     543             : end:
     544           5 :         slist_free(&slist);
     545           5 :         linkhash_free();
     546           5 :         rblk_free();
     547           5 :         return ret;
     548             : }
     549             : 
     550           5 : static int get_logpaths(struct bu *bu, const char *file,
     551             :         char **logpath, char **logpathz)
     552             : {
     553          10 :         if(!(*logpath=prepend_s(bu->path, file))
     554           5 :           || !(*logpathz=prepend(*logpath, ".gz")))
     555             :                 return -1;
     556             :         return 0;
     557             : }
     558             : 
     559          10 : static int restore_manifest(struct asfd *asfd, struct bu *bu,
     560             :         regex_t *regex, int srestore, enum action act, struct sdirs *sdirs,
     561             :         char **dir_for_notify, struct conf **cconfs)
     562             : {
     563           5 :         int ret=-1;
     564           5 :         char *manifest=NULL;
     565           5 :         char *logpath=NULL;
     566           5 :         char *logpathz=NULL;
     567             :         // For sending status information up to the server.
     568           5 :         enum cntr_status cntr_status=CNTR_STATUS_RESTORING;
     569             : 
     570           5 :         if(act==ACTION_RESTORE) cntr_status=CNTR_STATUS_RESTORING;
     571           0 :         else if(act==ACTION_VERIFY) cntr_status=CNTR_STATUS_VERIFYING;
     572             : 
     573          10 :         if((act==ACTION_RESTORE && get_logpaths(bu, "restorelog",
     574           5 :                 &logpath, &logpathz))
     575           5 :           || (act==ACTION_VERIFY && get_logpaths(bu, "verifylog",
     576           0 :                 &logpath, &logpathz))
     577          10 :           || !(manifest=prepend_s(bu->path,
     578           5 :                 get_protocol(cconfs)==PROTO_1?
     579           5 :                         "manifest.gz":"manifest")))
     580             :         {
     581           0 :                 log_and_send_oom(asfd, __func__);
     582           0 :                 goto end;
     583             :         }
     584             : 
     585           5 :         if(log_fzp_set(logpath, cconfs))
     586             :         {
     587           0 :                 char msg[256]="";
     588             :                 snprintf(msg, sizeof(msg),
     589           0 :                                 "could not open log file: %s", logpath);
     590           0 :                 log_and_send(asfd, msg);
     591             :                 goto end;
     592             :         }
     593             : 
     594           5 :         *dir_for_notify=strdup_w(bu->path, __func__);
     595             : 
     596           5 :         log_restore_settings(cconfs, srestore);
     597             : 
     598             :         // First, do a pass through the manifest to set up cntr.
     599             :         // This is the equivalent of a phase1 scan during backup.
     600             : 
     601           5 :         if(setup_cntr(asfd, manifest,
     602           5 :                 regex, srestore, act, cntr_status, cconfs))
     603             :                         goto end;
     604             : 
     605          10 :         if(get_int(cconfs[OPT_SEND_CLIENT_CNTR])
     606           5 :           && cntr_send(get_cntr(cconfs)))
     607             :                 goto end;
     608             : 
     609             :         // Now, do the actual restore.
     610             :         ret=actual_restore(asfd, bu, manifest,
     611           5 :                   regex, srestore, act, sdirs, cntr_status, cconfs);
     612             : end:
     613           5 :         log_fzp_set(NULL, cconfs);
     614           5 :         compress_file(logpath, logpathz, get_int(cconfs[OPT_COMPRESSION]));
     615           5 :         free_w(&manifest);
     616           5 :         free_w(&logpath);
     617           5 :         free_w(&logpathz);
     618           5 :         return ret;
     619             : }
     620             : 
     621           6 : int do_restore_server(struct asfd *asfd, struct sdirs *sdirs,
     622             :         enum action act, int srestore,
     623             :         char **dir_for_notify, struct conf **confs)
     624             : {
     625           6 :         int ret=-1;
     626           6 :         uint8_t found=0;
     627           6 :         struct bu *bu=NULL;
     628           6 :         struct bu *bu_list=NULL;
     629           6 :         unsigned long bno=0;
     630           6 :         regex_t *regex=NULL;
     631           6 :         const char *regexstr=get_string(confs[OPT_REGEX]);
     632           6 :         const char *backup=get_string(confs[OPT_BACKUP]);
     633             : 
     634           6 :         logp("in do_restore\n");
     635             : 
     636           6 :         if(regexstr
     637           1 :           && *regexstr
     638           7 :           && !(regex=regex_compile(regexstr)))
     639             :         {
     640           1 :                 char msg[256]="";
     641             :                 snprintf(msg, sizeof(msg), "unable to compile regex: %s\n",
     642             :                         regexstr);
     643           1 :                 log_and_send(asfd, msg);
     644             :                 goto end;
     645             :         }
     646             : 
     647           5 :         if(bu_get_list(sdirs, &bu_list))
     648             :                 goto end;
     649             : 
     650          10 :         if(bu_list &&
     651             :            (!backup
     652           5 :          || !*backup
     653           5 :          || (!(bno=strtoul(backup, NULL, 10)) && *backup!='a')))
     654             :         {
     655           0 :                 found=1;
     656             :                 // No backup specified, do the most recent.
     657           0 :                 for(bu=bu_list; bu && bu->next; bu=bu->next) { }
     658             :                 ret=restore_manifest(asfd, bu, regex, srestore,
     659           0 :                                 act, sdirs, dir_for_notify, confs);
     660             :         }
     661             : 
     662           5 :         if(!found) for(bu=bu_list; bu; bu=bu->next)
     663             :         {
     664           5 :                 if(!strcmp(bu->timestamp, backup)
     665           5 :                   || bu->bno==bno || (backup && *backup=='a'))
     666             :                 {
     667           5 :                         found=1;
     668             :                         //logp("got: %s\n", bu->path);
     669             :                         ret|=restore_manifest(asfd, bu, regex, srestore,
     670           5 :                                 act, sdirs, dir_for_notify, confs);
     671           5 :                         if(backup && *backup=='a')
     672             :                                 continue;
     673             :                         break;
     674             :                 }
     675             :         }
     676             : 
     677           5 :         bu_list_free(&bu_list);
     678             : 
     679             : 
     680           5 :         if(found)
     681             :         {
     682             :                 // Restore has nearly completed OK.
     683           5 :                 ret=restore_end(asfd, confs);
     684             :         }
     685             :         else
     686             :         {
     687           0 :                 logp("backup not found\n");
     688           0 :                 asfd->write_str(asfd, CMD_ERROR, "backup not found");
     689           0 :                 ret=-1;
     690             :         }
     691             : end:
     692           6 :         regex_free(&regex);
     693           6 :         return ret;
     694             : }

Generated by: LCOV version 1.10