LCOV - code coverage report
Current view: top level - src/server - bu_get.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 124 126 98.4 %
Date: 2017-01-01 Functions: 8 8 100.0 %

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../alloc.h"
       3             : #include "../bu.h"
       4             : #include "../cstat.h"
       5             : #include "../fsops.h"
       6             : #include "../log.h"
       7             : #include "../prepend.h"
       8             : #include "sdirs.h"
       9             : #include "timestamp.h"
      10             : #include "bu_get.h"
      11             : 
      12             : static int get_link(const char *dir, const char *lnk, char real[], size_t r)
      13             : {
      14         845 :         return readlink_w_in_dir(dir, lnk, real, r);
      15             : }
      16             : 
      17        5327 : static void have_backup_file_name(struct bu *bu,
      18             :         const char *file, uint32_t bit)
      19             : {
      20             :         struct stat statp;
      21             :         static char path[256]="";
      22        5327 :         snprintf(path, sizeof(path), "%s/%s", bu->path, file);
      23       10529 :         if(lstat(path, &statp)) return;
      24         125 :         bu->flags|=bit;
      25             : }
      26             : 
      27        6537 : static void have_backup_file_name_w(struct bu *bu,
      28             :         const char *file, uint32_t bit)
      29             : {
      30             :         char compressed[32];
      31             :         snprintf(compressed, sizeof(compressed), "%s.gz", file);
      32        2179 :         have_backup_file_name(bu, file, bit);
      33        2179 :         have_backup_file_name(bu, compressed, bit);
      34        2179 : }
      35             : 
      36        1194 : static int maybe_add_ent(const char *dir, const char *d_name,
      37             :         struct bu **bu_list, uint16_t flags, struct cstat *cstat,
      38             :         int include_working)
      39             : {
      40        1194 :         int ret=-1;
      41        1194 :         char buf[32]="";
      42             :         struct stat statp;
      43        1194 :         char *fullpath=NULL;
      44        1194 :         char *timestamp=NULL;
      45        1194 :         char *timestampstr=NULL;
      46        1194 :         char *hlinkedpath=NULL;
      47        1194 :         char *basename=NULL;
      48        2163 :         struct bu *bu=NULL;
      49             : 
      50        1194 :         if(!(basename=prepend("", d_name))
      51        1194 :          || !(fullpath=prepend_s(dir, basename))
      52        1194 :          || !(timestamp=prepend_s(fullpath, "timestamp"))
      53        1194 :          || !(hlinkedpath=prepend_s(fullpath, "hardlinked")))
      54             :                 goto error;
      55             : 
      56        2388 :         if((!lstat(fullpath, &statp) && !S_ISDIR(statp.st_mode))
      57        2388 :           || lstat(timestamp, &statp) || !S_ISREG(statp.st_mode)
      58        1194 :           || timestamp_read(timestamp, buf, sizeof(buf))
      59             :         // A bit of paranoia to protect against loading directories moved
      60             :         // aside as if they were real storage directories.
      61        1194 :           || strncmp(buf, d_name, 8))
      62             :         {
      63             :                 ret=0; // For resilience.
      64             :                 goto error;
      65             :         }
      66             : 
      67        1192 :         free_w(&timestamp);
      68             : 
      69        1192 :         if(!(timestampstr=strdup_w(buf, __func__)))
      70             :                 goto error;
      71             : 
      72        2384 :         if(!lstat(hlinkedpath, &statp)) flags|=BU_HARDLINKED;
      73             : 
      74        1192 :         if(!(bu=bu_alloc())
      75        1192 :           || bu_init(bu, fullpath, basename, timestampstr, flags))
      76             :                 goto error;
      77             : 
      78        1192 :         if(*bu_list) bu->next=*bu_list;
      79        1192 :         *bu_list=bu;
      80        1192 :         have_backup_file_name_w(bu, "manifest", BU_MANIFEST);
      81        1192 :         if(include_working)
      82             :         {
      83         329 :                 have_backup_file_name_w(bu, "log", BU_LOG_BACKUP);
      84         329 :                 have_backup_file_name_w(bu, "restorelog", BU_LOG_RESTORE);
      85         329 :                 have_backup_file_name_w(bu, "verifylog", BU_LOG_VERIFY);
      86             :                 // Hack to include option for live counters.
      87         329 :                 if(cstat && cstat->run_status==RUN_STATUS_RUNNING)
      88             :                 {
      89          24 :                         switch(cstat->cntr->cntr_status)
      90             :                         {
      91             :                                 case CNTR_STATUS_SCANNING:
      92             :                                 case CNTR_STATUS_BACKUP:
      93             :                                 case CNTR_STATUS_MERGING:
      94             :                                 case CNTR_STATUS_SHUFFLING:
      95           6 :                                         bu->flags|=BU_STATS_BACKUP;
      96           6 :                                         break;
      97             :                                 case CNTR_STATUS_VERIFYING:
      98           6 :                                         bu->flags|=BU_STATS_VERIFY;
      99           6 :                                         break;
     100             :                                 case CNTR_STATUS_RESTORING:
     101           6 :                                         bu->flags|=BU_STATS_RESTORE;
     102           6 :                                         break;
     103             :                                 default:
     104             :                                         break;
     105             :                         }
     106             :                 }
     107         329 :                 if(!(bu->flags & BU_STATS_BACKUP))
     108         323 :                   have_backup_file_name(bu, "backup_stats", BU_STATS_BACKUP);
     109         329 :                 if(!(bu->flags & BU_STATS_RESTORE))
     110         323 :                   have_backup_file_name(bu, "restore_stats", BU_STATS_RESTORE);
     111         329 :                 if(!(bu->flags & BU_STATS_VERIFY))
     112         323 :                   have_backup_file_name(bu, "verify_stats", BU_STATS_VERIFY);
     113             :         }
     114             : 
     115        1192 :         free_w(&hlinkedpath);
     116        1192 :         return 0;
     117             : error:
     118           2 :         free_w(&basename);
     119           2 :         free_w(&fullpath);
     120           2 :         free_w(&timestamp);
     121           2 :         free_w(&timestampstr);
     122           2 :         free_w(&hlinkedpath);
     123           2 :         return ret;
     124             : }
     125             : 
     126         279 : static void setup_indices(struct bu *bu_list, enum protocol protocol)
     127             : {
     128             :         int i;
     129         279 :         int tr=0;
     130         279 :         struct bu *bu=NULL;
     131         279 :         struct bu *last=NULL;
     132             : 
     133         279 :         i=1;
     134        1463 :         for(bu=bu_list; bu; bu=bu->next)
     135             :         {
     136             :                 // Enumerate the position of each entry.
     137        1184 :                 bu->index=i++;
     138             : 
     139        1184 :                 if(protocol==PROTO_2)
     140             :                 {
     141             :                         // All PROTO_2 backups are deletable.
     142         545 :                         bu->flags|=BU_DELETABLE;
     143             :                 }
     144             :                 else
     145             :                 {
     146             :                         // Backups that come after hardlinked backups are
     147             :                         // deletable.
     148         639 :                         if((bu->flags & BU_HARDLINKED) && bu->next)
     149         111 :                                 bu->next->flags|=BU_DELETABLE;
     150             :                 }
     151             : 
     152             :                 // Also set up reverse linkage.
     153        1184 :                 bu->prev=last;
     154        1184 :                 last=bu;
     155             :         }
     156             : 
     157             :         // The oldest backup is deletable.
     158         279 :         if(bu_list) bu_list->flags|=BU_DELETABLE;
     159             : 
     160         279 :         if(last)
     161             :         {
     162             : 
     163         273 :                 if((tr=last->bno))
     164             :                 {
     165             :                         // Transpose bnos so that the oldest bno is set to 1.
     166        1184 :                         for(bu=bu_list; bu; bu=bu->next)
     167        1184 :                                 bu->trbno=tr-bu->bno+1;
     168             :                 }
     169             :         }
     170         279 : }
     171             : 
     172         280 : static int do_bu_get_list(struct sdirs *sdirs,
     173             :         struct bu **bu_list, struct cstat *cstat, int include_working)
     174             : {
     175         280 :         int i=0;
     176         280 :         int n=0;
     177         280 :         int ret=-1;
     178         280 :         char realwork[32]="";
     179         280 :         char realfinishing[32]="";
     180         280 :         char realcurrent[32]="";
     181         280 :         struct dirent **dp=NULL;
     182         280 :         const char *dir=NULL;
     183         280 :         uint16_t flags=0;
     184             :         struct stat statp;
     185             : 
     186         280 :         if(!sdirs)
     187             :         {
     188           1 :                 logp("%s() called with NULL sdirs\n", __func__);
     189           1 :                 goto end;
     190             :         }
     191             : 
     192         279 :         dir=sdirs->client;
     193             : 
     194         279 :         if(get_link(dir, "working", realwork, sizeof(realwork))
     195         279 :           || get_link(dir, "finishing", realfinishing, sizeof(realfinishing))
     196         279 :           || get_link(dir, "current", realcurrent, sizeof(realcurrent)))
     197             :                 goto end;
     198             : 
     199         279 :         if(!stat(dir, &statp)
     200         279 :           && (n=scandir(dir, &dp, filter_dot, alphasort))<0)
     201             :         {
     202           0 :                 logp("scandir failed in %s: %s\n", __func__, strerror(errno));
     203           0 :                 goto end;
     204             :         }
     205         279 :         i=n;
     206        2043 :         while(i--)
     207             :         {
     208             :                 // Each storage directory starts with a digit. The 'deleteme'
     209             :                 // directory does not. This check avoids loading 'deleteme'
     210             :                 // as a storage directory.
     211        1485 :                 if(!isdigit(dp[i]->d_name[0]))
     212         295 :                         continue;
     213        1190 :                 flags=0;
     214        1190 :                 if(!strcmp(dp[i]->d_name, realcurrent))
     215             :                 {
     216             :                         flags|=BU_CURRENT;
     217             :                 }
     218         917 :                 else if(!strcmp(dp[i]->d_name, realwork))
     219             :                 {
     220           9 :                         if(!include_working) continue;
     221             :                         flags|=BU_WORKING;
     222             :                 }
     223         908 :                 else if(!strcmp(dp[i]->d_name, realfinishing))
     224             :                 {
     225           9 :                         if(!include_working) continue;
     226             :                         flags|=BU_FINISHING;
     227             :                 }
     228        1186 :                 if(maybe_add_ent(dir, dp[i]->d_name, bu_list, flags,
     229             :                         cstat, include_working)) goto end;
     230             :         }
     231             : 
     232         279 :         setup_indices(*bu_list, sdirs->protocol);
     233             : 
     234         279 :         ret=0;
     235             : end:
     236         280 :         if(dp)
     237             :         {
     238        1485 :                 for(i=0; i<n; i++)
     239        1485 :                         free(dp[i]);
     240         273 :                 free(dp);
     241             :         }
     242         280 :         return ret;
     243             : }
     244             : 
     245         196 : int bu_get_list(struct sdirs *sdirs, struct bu **bu_list)
     246             : {
     247         196 :         return do_bu_get_list(sdirs, bu_list, NULL, 0/*include_working*/);
     248             : }
     249             : 
     250          84 : int bu_get_list_with_working(struct sdirs *sdirs, struct bu **bu_list,
     251             :         struct cstat *cstat)
     252             : {
     253          84 :         return do_bu_get_list(sdirs, bu_list, cstat, 1/*include_working*/);
     254             : }
     255             : 
     256           8 : int bu_get_current(struct sdirs *sdirs, struct bu **bu_list)
     257             : {
     258           8 :         char real[32]="";
     259             :         // FIX THIS: should not need to specify "current".
     260          16 :         if(get_link(sdirs->client, "current", real, sizeof(real)))
     261             :                 return -1;
     262           8 :         return maybe_add_ent(sdirs->client, real, bu_list, BU_CURRENT,
     263             :                 NULL, 0/*include_working*/);
     264             : }

Generated by: LCOV version 1.10