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

Generated by: LCOV version 1.10