LCOV - code coverage report
Current view: top level - src/server - restore.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 19 313 6.1 %
Date: 2015-11-30 Functions: 1 15 6.7 %

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

Generated by: LCOV version 1.10