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

Generated by: LCOV version 1.10