LCOV - code coverage report
Current view: top level - src/server - sdirs.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 123 136 90.4 %
Date: 2022-05-01 01:22:11 Functions: 12 12 100.0 %

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "sdirs.h"
       3             : #include "../alloc.h"
       4             : #include "../conf.h"
       5             : #include "../fsops.h"
       6             : #include "../lock.h"
       7             : #include "../log.h"
       8             : #include "../prepend.h"
       9             : #include "timestamp.h"
      10             : 
      11             : #define RELINK_DIR      "relink"
      12             : 
      13         177 : struct sdirs *sdirs_alloc(void)
      14             : {
      15         177 :         return (struct sdirs *)calloc_w(1, sizeof(struct sdirs), __func__);
      16             : }
      17             : 
      18         177 : static int do_lock_dirs(struct sdirs *sdirs,
      19             :         const char *cname, const char *conf_lockdir)
      20             : {
      21         177 :         int ret=-1;
      22         177 :         char *lockbase=NULL;
      23         177 :         char *lockfile=NULL;
      24         177 :         if(conf_lockdir)
      25             :         {
      26           1 :                 if(!(sdirs->lockdir=strdup_w(conf_lockdir, __func__))
      27           1 :                   || !(lockbase=prepend_s(sdirs->lockdir, cname)))
      28             :                         goto end;
      29             :         }
      30             :         else
      31             :         {
      32         176 :                 if(!(sdirs->lockdir=strdup_w(sdirs->client, __func__))
      33         176 :                   || !(lockbase=strdup_w(sdirs->client, __func__)))
      34             :                         goto end;
      35             :         }
      36         177 :         if(!(lockfile=prepend_s(lockbase, "lockfile"))
      37         177 :           || !(sdirs->lock_storage_for_write=lock_alloc_and_init(lockfile)))
      38             :                 goto end;
      39         177 :         ret=0;
      40             : end:
      41         177 :         free_w(&lockbase);
      42         177 :         free_w(&lockfile);
      43         177 :         return ret;
      44             : }
      45             : 
      46             : static int free_prepend_s(char **dst, const char *a, const char *b)
      47             : {
      48          26 :         free_w(dst);
      49          26 :         return !(*dst=prepend_s(a, b));
      50             : }
      51             : 
      52           2 : int sdirs_get_real_manifest(struct sdirs *sdirs)
      53             : {
      54           4 :         return free_prepend_s(&sdirs->rmanifest,
      55           2 :                 sdirs->rworking, "manifest.gz");
      56             : }
      57             : 
      58           6 : int sdirs_get_real_working_from_symlink(struct sdirs *sdirs)
      59             : {
      60           6 :         char real[256]="";
      61           6 :         if(readlink_w(sdirs->working, real, sizeof(real))<0)
      62             :         {
      63           0 :                 logp("Could not readlink %s: %s\n",
      64           0 :                         sdirs->working, strerror(errno));
      65           0 :                 return -1;
      66             :         }
      67          12 :         if(free_prepend_s(&sdirs->rworking, sdirs->client, real)
      68          12 :           || free_prepend_s(&sdirs->treepath,
      69             :                 sdirs->rworking, DATA_DIR "/" TREE_DIR)
      70          12 :           || free_prepend_s(&sdirs->relink, sdirs->rworking, RELINK_DIR))
      71             :                 return -1;
      72             :         return 0;
      73             : }
      74             : 
      75           2 : int sdirs_create_real_working(
      76             :         struct sdirs *sdirs,
      77             :         uint64_t bno,
      78             :         const char *timestamp_format
      79             : ) {
      80           2 :         char tstmp[64]="";
      81           2 :         char fname[64]="";
      82             : 
      83           2 :         if(build_path_w(sdirs->working))
      84             :                 return -1;
      85           2 :         if(timestamp_get_new(bno,
      86             :                 tstmp, sizeof(tstmp), fname, sizeof(fname), timestamp_format)
      87           4 :           || free_prepend_s(&sdirs->rworking, sdirs->client, fname)
      88           4 :           || free_prepend_s(&sdirs->treepath,
      89             :                 sdirs->rworking, DATA_DIR "/" TREE_DIR)
      90           4 :           || free_prepend_s(&sdirs->relink, sdirs->rworking, RELINK_DIR))
      91             :                 return -1;
      92             : 
      93             :         // Add the working symlink before creating the directory.
      94             :         // This is because bedup checks the working symlink before
      95             :         // going into a directory. If the directory got created first,
      96             :         // bedup might go into it in the moment before the symlink
      97             :         // gets added.
      98           2 :         if(do_symlink(fname, sdirs->working))
      99             :                 // relative link to the real work dir
     100             :         {
     101           0 :                 logp("could not point working symlink to: %s\n",
     102             :                         sdirs->rworking);
     103           0 :                 return -1;
     104             :         }
     105           2 :         if(mkdir(sdirs->rworking, 0777))
     106             :         {
     107           0 :                 logp("could not mkdir for next backup: %s\n", sdirs->rworking);
     108           0 :                 unlink(sdirs->working);
     109           0 :                 return -1;
     110             :         }
     111           2 :         if(timestamp_write(sdirs->timestamp, tstmp))
     112             :         {
     113           0 :                 logp("unable to write timestamp %s to %s\n",
     114             :                         tstmp, sdirs->timestamp);
     115           0 :                 return -1;
     116             :         }
     117             : 
     118             :         return 0;
     119             : }
     120             : 
     121         177 : static int do_common_dirs(struct sdirs *sdirs, const char *manual_delete)
     122             : {
     123         177 :         if(!(sdirs->created=prepend_s(sdirs->client, ".created"))
     124         177 :           || !(sdirs->command=prepend_s(sdirs->client, ".command"))
     125         177 :           || !(sdirs->working=prepend_s(sdirs->client, "working"))
     126         177 :           || !(sdirs->finishing=prepend_s(sdirs->client, "finishing"))
     127         177 :           || !(sdirs->current=prepend_s(sdirs->client, "current"))
     128         177 :           || !(sdirs->currenttmp=prepend_s(sdirs->client, "current.tmp"))
     129         177 :           || !(sdirs->timestamp=prepend_s(sdirs->working, "timestamp"))
     130         177 :           || !(sdirs->phase1data=prepend_s(sdirs->working, "phase1.gz"))
     131         177 :           || !(sdirs->changed=prepend_s(sdirs->working, "changed"))
     132         177 :           || !(sdirs->unchanged=prepend_s(sdirs->working, "unchanged"))
     133         177 :           || !(sdirs->counters_d=prepend_s(sdirs->working, "counters_d"))
     134         177 :           || !(sdirs->counters_n=prepend_s(sdirs->working, "counters_n"))
     135         177 :           || !(sdirs->restore_list=prepend_s(sdirs->client, "restore_list")))
     136             :                 return -1;
     137         177 :         if(manual_delete)
     138             :         {
     139           0 :                 if(!(sdirs->deleteme=strdup_w(manual_delete, __func__)))
     140             :                         return -1;
     141             :         }
     142             :         else
     143             :         {
     144         177 :                 if(!(sdirs->deleteme=prepend_s(sdirs->client, "deleteme")))
     145             :                         return -1;
     146             :         }
     147             :         return 0;
     148             : }
     149             : 
     150             : // Maybe should be in a protocol1 directory.
     151         177 : static int do_protocol1_dirs(struct sdirs *sdirs, const char *cname,
     152             :         const char *manual_delete)
     153             : {
     154         177 :         if(!(sdirs->clients=strdup_w(sdirs->base, __func__))
     155         177 :           || !(sdirs->client=prepend_s(sdirs->clients, cname))
     156         177 :           || do_common_dirs(sdirs, manual_delete)
     157         177 :           || !(sdirs->currentdata=prepend_s(sdirs->current, DATA_DIR))
     158         177 :           || !(sdirs->manifest=prepend_s(sdirs->working, "manifest.gz"))
     159         177 :           || !(sdirs->datadirtmp=prepend_s(sdirs->working, "data.tmp"))
     160         177 :           || !(sdirs->cmanifest=prepend_s(sdirs->current, "manifest.gz"))
     161         177 :           || !(sdirs->cincexc=prepend_s(sdirs->current, "incexc"))
     162         177 :           || !(sdirs->deltmppath=prepend_s(sdirs->working, "deltmppath")))
     163             :                         return -1;
     164             :         // sdirs->rworking gets set later.
     165             :         // sdirs->treepath gets set later.
     166             :         // sdirs->relink gets set later.
     167             :         return 0;
     168             : }
     169             : 
     170          25 : int sdirs_init_from_confs_plus_cname(
     171             :         struct sdirs *sdirs,
     172             :         struct conf **confs,
     173             :         const char *cname
     174             : ) {
     175          25 :         return sdirs_init(
     176             :                 sdirs,
     177          25 :                 get_string(confs[OPT_DIRECTORY]),
     178             :                 cname,
     179          25 :                 get_string(confs[OPT_CLIENT_LOCKDIR]),
     180          25 :                 get_string(confs[OPT_DEDUP_GROUP]),
     181          25 :                 get_string(confs[OPT_MANUAL_DELETE])
     182             :         );
     183             : }
     184             : 
     185          25 : int sdirs_init_from_confs(
     186             :         struct sdirs *sdirs,
     187             :         struct conf **confs
     188             : ) {
     189          25 :         return sdirs_init_from_confs_plus_cname(
     190             :                 sdirs,
     191             :                 confs,
     192          25 :                 get_string(confs[OPT_CNAME])
     193             :         );
     194             : }
     195             : 
     196         177 : int sdirs_init(struct sdirs *sdirs,
     197             :         const char *directory, const char *cname, const char *conf_lockdir,
     198             :         const char *dedup_group, const char *manual_delete)
     199             : {
     200         177 :         if(!directory)
     201             :         {
     202           0 :                 logp("directory unset in %s\n", __func__);
     203           0 :                 goto error;
     204             :         }
     205             : 
     206         177 :         if(!(sdirs->base=strdup_w(directory, __func__)))
     207             :                 goto error;
     208             : 
     209         177 :         if(do_protocol1_dirs(sdirs, cname, manual_delete))
     210             :                 goto error;
     211             : 
     212         177 :         if(do_lock_dirs(sdirs, cname, conf_lockdir)) goto error;
     213             : 
     214             :         return 0;
     215             : error:
     216             :         return -1;
     217             : }
     218             : 
     219         178 : void sdirs_free_content(struct sdirs *sdirs)
     220             : {
     221         178 :         free_w(&sdirs->base);
     222         178 :         free_w(&sdirs->dedup);
     223         178 :         free_w(&sdirs->champlock);
     224         178 :         free_w(&sdirs->champsock);
     225         178 :         free_w(&sdirs->champlog);
     226         178 :         free_w(&sdirs->champ_dindex_lock);
     227         178 :         free_w(&sdirs->data);
     228         178 :         free_w(&sdirs->clients);
     229         178 :         free_w(&sdirs->client);
     230         178 :         free_w(&sdirs->created);
     231         178 :         free_w(&sdirs->command);
     232             : 
     233         178 :         free_w(&sdirs->working);
     234         178 :         free_w(&sdirs->rworking);
     235         178 :         free_w(&sdirs->finishing);
     236         178 :         free_w(&sdirs->current);
     237         178 :         free_w(&sdirs->currenttmp);
     238         178 :         free_w(&sdirs->deleteme);
     239         178 :         free_w(&sdirs->dindex);
     240         178 :         free_w(&sdirs->dfiles);
     241         178 :         free_w(&sdirs->cfiles);
     242             : 
     243         178 :         free_w(&sdirs->timestamp);
     244         178 :         free_w(&sdirs->changed);
     245         178 :         free_w(&sdirs->unchanged);
     246         178 :         free_w(&sdirs->counters_d);
     247         178 :         free_w(&sdirs->counters_n);
     248         178 :         free_w(&sdirs->manifest);
     249         178 :         free_w(&sdirs->rmanifest);
     250         178 :         free_w(&sdirs->cmanifest);
     251         178 :         free_w(&sdirs->phase1data);
     252             : 
     253         178 :         free_w(&sdirs->restore_list);
     254             : 
     255         178 :         free_w(&sdirs->lockdir);
     256         178 :         lock_free(&sdirs->lock_storage_for_write);
     257             : 
     258             :         // Protocol1 directories.
     259         178 :         free_w(&sdirs->currentdata);
     260         178 :         free_w(&sdirs->datadirtmp);
     261         178 :         free_w(&sdirs->cincexc);
     262         178 :         free_w(&sdirs->deltmppath);
     263         178 :         free_w(&sdirs->treepath);
     264         178 :         free_w(&sdirs->relink);
     265         178 : }
     266             : 
     267         214 : void sdirs_free(struct sdirs **sdirs)
     268             : {
     269         214 :         if(!sdirs || !*sdirs) return;
     270         177 :         sdirs_free_content(*sdirs);
     271             : 
     272         177 :         free_v((void **)sdirs);
     273             : }

Generated by: LCOV version 1.13