LCOV - code coverage report
Current view: top level - src/server - diff.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 18 101 17.8 %
Date: 2020-11-06 04:06:22 Functions: 1 4 25.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 "../conf.h"
       7             : #include "../cmd.h"
       8             : #include "../cntr.h"
       9             : #include "../cstat.h"
      10             : #include "../log.h"
      11             : #include "../prepend.h"
      12             : #include "../sbuf.h"
      13             : #include "bu_get.h"
      14             : #include "child.h"
      15             : #include "manio.h"
      16             : #include "diff.h"
      17             : 
      18             : static char *get_manifest_path(const char *fullpath, enum protocol protocol)
      19             : {
      20           0 :         return prepend_s(fullpath, protocol==PROTO_1?"manifest.gz":"manifest");
      21             : }
      22             : 
      23           0 : static int send_diff(struct asfd *asfd, const char *symbol, struct sbuf *sb)
      24             : {
      25           0 :         int ret=-1;
      26           0 :         char *dpath=NULL;
      27           0 :         if(!(dpath=prepend_s(symbol, sb->path.buf))
      28           0 :           || asfd->write(asfd, &sb->attr)
      29           0 :           || asfd->write_str(asfd, sb->path.cmd, dpath))
      30             :                 goto end;
      31           0 :         if(sbuf_is_link(sb)
      32           0 :           && asfd->write(asfd, &sb->link))
      33             :                 goto end;
      34             :         ret=0;
      35             : end:
      36           0 :         free_w(&dpath);
      37           0 :         return ret;
      38             : }
      39             : 
      40             : static int send_deletion(struct asfd *asfd, struct sbuf *sb)
      41             : {
      42           0 :         return send_diff(asfd, "- ", sb);
      43             : }
      44             : 
      45             : static int send_addition(struct asfd *asfd, struct sbuf *sb)
      46             : {
      47           0 :         return send_diff(asfd, "+ ", sb);
      48             : }
      49             : 
      50           0 : static int diff_manifests(struct asfd *asfd, const char *fullpath1,
      51             :         const char *fullpath2, enum protocol protocol)
      52             : {
      53           0 :         int ret=-1;
      54             :         int pcmp;
      55           0 :         struct sbuf *sb1=NULL;
      56           0 :         struct sbuf *sb2=NULL;
      57           0 :         struct manio *manio1=NULL;
      58           0 :         struct manio *manio2=NULL;
      59           0 :         char *manifest_dir1=NULL;
      60           0 :         char *manifest_dir2=NULL;
      61             : 
      62           0 :         if(!(manifest_dir1=get_manifest_path(fullpath1, protocol))
      63           0 :           || !(manifest_dir2=get_manifest_path(fullpath2, protocol))
      64           0 :           || !(manio1=manio_open(manifest_dir1, "rb", protocol))
      65           0 :           || !(manio2=manio_open(manifest_dir2, "rb", protocol))
      66           0 :           || !(sb1=sbuf_alloc(protocol))
      67           0 :           || !(sb2=sbuf_alloc(protocol)))
      68             :         {
      69           0 :                 log_and_send_oom(asfd);
      70           0 :                 goto end;
      71             :         }
      72             : 
      73           0 :         while(manio1 || manio2)
      74             :         {
      75           0 :                 if(manio1
      76           0 :                   && !sb1->path.buf)
      77             :                 {
      78           0 :                         switch(manio_read(manio1, sb1))
      79             :                         {
      80             :                                 case -1: goto end;
      81           0 :                                 case 1: manio_close(&manio1);
      82             :                         }
      83             :                 }
      84             : 
      85           0 :                 if(manio2
      86           0 :                   && !sb2->path.buf)
      87             :                 {
      88           0 :                         switch(manio_read(manio2, sb2))
      89             :                         {
      90             :                                 case -1: goto end;
      91           0 :                                 case 1: manio_close(&manio2);
      92             :                         }
      93             :                 }
      94             : 
      95           0 :                 if(sb1->path.buf && !sb2->path.buf)
      96             :                 {
      97           0 :                         if(send_deletion(asfd, sb1))
      98             :                                 goto end;
      99           0 :                         sbuf_free_content(sb1);
     100             :                 }
     101           0 :                 else if(!sb1->path.buf && sb2->path.buf)
     102             :                 {
     103           0 :                         if(send_addition(asfd, sb2))
     104             :                                 goto end;
     105           0 :                         sbuf_free_content(sb2);
     106             :                 }
     107           0 :                 else if(!sb1->path.buf && !sb2->path.buf)
     108             :                 {
     109           0 :                         continue;
     110             :                 }
     111           0 :                 else if(!(pcmp=sbuf_pathcmp(sb1, sb2)))
     112             :                 {
     113           0 :                         if(sb1->statp.st_mtime!=sb2->statp.st_mtime)
     114             :                         {
     115           0 :                                 if(send_deletion(asfd, sb1)
     116           0 :                                   || send_addition(asfd, sb2))
     117             :                                         goto end;
     118             :                         }
     119           0 :                         sbuf_free_content(sb1);
     120           0 :                         sbuf_free_content(sb2);
     121             :                 }
     122           0 :                 else if(pcmp<0)
     123             :                 {
     124           0 :                         if(send_deletion(asfd, sb1))
     125             :                                 goto end;
     126           0 :                         sbuf_free_content(sb1);
     127             :                 }
     128             :                 else
     129             :                 {
     130           0 :                         if(send_addition(asfd, sb2))
     131             :                                 goto end;
     132           0 :                         sbuf_free_content(sb2);
     133             :                 }
     134             :         }
     135             : 
     136             :         ret=0;
     137             : end:
     138           0 :         sbuf_free(&sb1);
     139           0 :         sbuf_free(&sb2);
     140           0 :         free_w(&manifest_dir1);
     141           0 :         free_w(&manifest_dir2);
     142           0 :         manio_close(&manio1);
     143           0 :         manio_close(&manio2);
     144           0 :         return ret;
     145             : }
     146             : 
     147           0 : static int send_backup_name_to_client(struct asfd *asfd, struct bu *bu)
     148             : {
     149           0 :         char msg[64]="";
     150           0 :         snprintf(msg, sizeof(msg), "%s", bu->timestamp);
     151           0 :         return asfd->write_str(asfd, CMD_TIMESTAMP, msg);
     152             : }
     153             : 
     154           1 : int do_diff_server(struct asfd *asfd, struct sdirs *sdirs, struct conf **confs,
     155             :         enum protocol protocol, const char *backup1, const char *backup2)
     156             : {
     157           1 :         int ret=-1;
     158           1 :         unsigned long bno1=0;
     159           1 :         unsigned long bno2=0;
     160           1 :         struct bu *bu1=NULL;
     161           1 :         struct bu *bu2=NULL;
     162           1 :         struct bu *bu_list=NULL;
     163           1 :         struct cntr *cntr=NULL;
     164             : 
     165           1 :         if(confs)
     166           1 :                 cntr=get_cntr(confs);
     167             : 
     168             :         //printf("in do_diff_server\n");
     169             : 
     170           1 :         if(bu_get_list(sdirs, &bu_list))
     171             :                 goto end;
     172             : 
     173           1 :         if(backup2 && *backup2)
     174           0 :                 bno2=strtoul(backup2, NULL, 10);
     175           1 :         if(backup1 && *backup1)
     176           0 :                 bno1=strtoul(backup1, NULL, 10);
     177             : 
     178           1 :         if(!bno1 || !bno2 || bno1==bno2)
     179             :         {
     180           1 :                 asfd->write_str(asfd, CMD_ERROR,
     181             :                         "you need to specify two backups");
     182           1 :                 goto end;
     183             :         }
     184             : 
     185           0 :         for(bu1=bu_list; bu1; bu1=bu1->next)
     186           0 :                 if(bu1->bno==bno1) break;
     187           0 :         for(bu2=bu_list; bu2; bu2=bu2->next)
     188           0 :                 if(bu2->bno==bno2) break;
     189           0 :         if(!bu1 || !bu2)
     190             :         {
     191           0 :                 asfd->write_str(asfd, CMD_ERROR,
     192             :                         "could not find specified backups");
     193           0 :                 goto end;
     194             :         }
     195             : 
     196           0 :         if(send_backup_name_to_client(asfd, bu1)
     197           0 :           || send_backup_name_to_client(asfd, bu2))
     198             :                 goto end;
     199             : 
     200           0 :         cntr->bno=(int)bu2->bno;
     201           0 :         if(timed_operation_status_only(CNTR_STATUS_DIFFING, NULL, confs))
     202             :                 goto end;
     203             : 
     204           0 :         if(diff_manifests(asfd, bu1->path, bu2->path, protocol))
     205             :                 goto end;
     206             : 
     207           0 :         ret=0;
     208             : end:
     209           1 :         bu_list_free(&bu_list);
     210           1 :         return ret;
     211             : }

Generated by: LCOV version 1.13