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

Generated by: LCOV version 1.10