LCOV - code coverage report
Current view: top level - src/server/monitor - cstat.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 0 144 0.0 %
Date: 2015-10-31 Functions: 0 10 0.0 %

          Line data    Source code
       1             : #include "../../burp.h"
       2             : #include "../../alloc.h"
       3             : #include "../../bu.h"
       4             : #include "../../cstat.h"
       5             : #include "../../conffile.h"
       6             : #include "../../fsops.h"
       7             : #include "../../lock.h"
       8             : #include "../../log.h"
       9             : #include "../../strlist.h"
      10             : #include "../bu_get.h"
      11             : #include "../sdirs.h"
      12             : #include "cstat.h"
      13             : 
      14           0 : static int permitted(struct cstat *cstat,
      15             :         struct conf **parentconfs, struct conf **cconfs)
      16             : {
      17             :         struct strlist *rclient;
      18             : 
      19             :         // Allow clients to look at themselves.
      20           0 :         if(!strcmp(cstat->name, get_string(parentconfs[OPT_CNAME]))) return 1;
      21             : 
      22             :         // Do not allow clients using the restore_client option to see more
      23             :         // than the client that it is pretending to be.
      24           0 :         if(get_string(parentconfs[OPT_RESTORE_CLIENT])) return 0;
      25             : 
      26             :         // If we are listed in this restore_client list.
      27           0 :         for(rclient=get_strlist(cconfs[OPT_RESTORE_CLIENTS]);
      28             :           rclient; rclient=rclient->next)
      29           0 :                 if(!strcmp(get_string(parentconfs[OPT_CNAME]), rclient->path))
      30           0 :                         return 1;
      31           0 :         return 0;
      32             : }
      33             : 
      34           0 : static int set_cstat_from_conf(struct cstat *cstat,
      35             :         struct conf **parentconfs, struct conf **cconfs)
      36             : {
      37             :         // Make sure the permitted flag is set appropriately.
      38           0 :         cstat->permitted=permitted(cstat, parentconfs, cconfs);
      39             : 
      40           0 :         cstat->protocol=get_protocol(cconfs);
      41           0 :         sdirs_free((struct sdirs **)&cstat->sdirs);
      42           0 :         if(!(cstat->sdirs=sdirs_alloc())
      43           0 :           || sdirs_init_from_confs((struct sdirs *)cstat->sdirs, cconfs))
      44           0 :                 return -1;
      45           0 :         return 0;
      46             : }
      47             : 
      48           0 : static int get_client_names(struct cstat **clist, struct conf **confs)
      49             : {
      50           0 :         int i=0;
      51           0 :         int n=-1;
      52           0 :         int ret=-1;
      53             :         struct cstat *c;
      54             :         struct cstat *cnew;
      55           0 :         struct dirent **dir=NULL;
      56           0 :         const char *clientconfdir=get_string(confs[OPT_CLIENTCONFDIR]);
      57             : 
      58           0 :         if(entries_in_directory_no_sort(clientconfdir, &dir, &n, 1 /*atime*/))
      59             :         {
      60             :                 logp("scandir failed for %s in %s: %s\n",
      61           0 :                         clientconfdir, __func__, strerror(errno));
      62           0 :                 goto end;
      63             :         }
      64           0 :         for(i=0; i<n; i++)
      65             :         {
      66             :                 // looks_like...() also avoids '.' and '..'.
      67           0 :                 if(looks_like_tmp_or_hidden_file(dir[i]->d_name))
      68           0 :                         continue;
      69           0 :                 for(c=*clist; c; c=c->next)
      70             :                 {
      71           0 :                         if(!c->name) continue;
      72           0 :                         if(!strcmp(dir[i]->d_name, c->name))
      73           0 :                                 break;
      74             :                 }
      75           0 :                 if(c) continue;
      76             : 
      77             :                 // We do not have this client yet. Add it.
      78           0 :                 if(!(cnew=cstat_alloc())
      79           0 :                   || cstat_init_with_cntr(cnew, dir[i]->d_name, clientconfdir)
      80           0 :                   || cstat_add_to_list(clist, cnew))
      81           0 :                         goto end;
      82             :         }
      83             : 
      84           0 :         ret=0;
      85             : end:
      86           0 :         if(dir)
      87             :         {
      88           0 :                 for(i=0; i<n; i++) free_v((void **)&dir[i]);
      89           0 :                 free_v((void **)&dir);
      90             :         }
      91           0 :         return ret;
      92             : }
      93             : 
      94           0 : static void cstat_free_w(struct cstat **cstat)
      95             : {
      96           0 :         sdirs_free((struct sdirs **)(*cstat)->sdirs);
      97           0 :         cstat_free(cstat);
      98           0 : }
      99             : 
     100           0 : static void cstat_remove(struct cstat **clist, struct cstat **cstat)
     101             : {
     102             :         struct cstat *c;
     103           0 :         struct cstat *clast=NULL;
     104           0 :         if(!cstat || !*cstat) return;
     105           0 :         if(*clist==*cstat)
     106             :         {
     107           0 :                 *clist=(*cstat)->next;
     108           0 :                 cstat_free_w(cstat);
     109           0 :                 *cstat=*clist;
     110           0 :                 return;
     111             :         }
     112           0 :         for(c=*clist; c; c=c->next)
     113             :         {
     114           0 :                 if(c->next!=*cstat)
     115             :                 {
     116           0 :                         clast=c;
     117           0 :                         continue;
     118             :                 }
     119           0 :                 c->next=(*cstat)->next;
     120           0 :                 c->prev=clast;
     121           0 :                 cstat_free_w(cstat);
     122           0 :                 *cstat=*clist;
     123             : 
     124           0 :                 return;
     125             :         }
     126             : }
     127             : 
     128           0 : static int reload_from_client_confs(struct cstat **clist,
     129             :         struct conf **globalcs)
     130             : {
     131             :         struct cstat *c;
     132             :         struct stat statp;
     133             :         static struct conf **cconfs=NULL;
     134             :         static time_t global_mtime=0;
     135           0 :         time_t global_mtime_new=0;
     136           0 :         const char *globalconffile=get_string(globalcs[OPT_CONFFILE]);
     137             : 
     138           0 :         if(!cconfs && !(cconfs=confs_alloc())) goto error;
     139             : 
     140           0 :         if(stat(globalconffile, &statp)
     141           0 :           || !S_ISREG(statp.st_mode))
     142             :         {
     143             :                 logp("Could not stat main conf file %s: %s\n",
     144           0 :                         globalconffile, strerror(errno));
     145           0 :                 goto error;
     146             :         }
     147           0 :         global_mtime_new=statp.st_mtime;
     148             : 
     149             :         // FIX THIS: If '. included' conf files have changed, this code will
     150             :         // not detect them. I guess that conf.c should make a list of them.
     151             :         while(1)
     152             :         {
     153           0 :                 for(c=*clist; c; c=c->next)
     154             :                 {
     155             :                         // Look at the client conf files to see if they have
     156             :                         // changed, and reload bits and pieces if they have.
     157             : 
     158           0 :                         if(!c->conffile) continue;
     159           0 :                         if(stat(c->conffile, &statp)
     160           0 :                           || !S_ISREG(statp.st_mode))
     161             :                         {
     162           0 :                                 cstat_remove(clist, &c);
     163           0 :                                 break; // Go to the beginning of the list.
     164             :                         }
     165           0 :                         if(statp.st_mtime==c->conf_mtime
     166           0 :                           && global_mtime_new==global_mtime)
     167             :                         {
     168             :                                 // The conf files have not changed - no need to
     169             :                                 // do anything.
     170           0 :                                 continue;
     171             :                         }
     172           0 :                         c->conf_mtime=statp.st_mtime;
     173             : 
     174           0 :                         confs_free_content(cconfs);
     175           0 :                         if(set_string(cconfs[OPT_CNAME], c->name))
     176           0 :                                 goto error;
     177           0 :                         if(conf_load_clientconfdir(globalcs, cconfs))
     178             :                         {
     179           0 :                                 cstat_remove(clist, &c);
     180           0 :                                 break; // Go to the beginning of the list.
     181             :                         }
     182             : 
     183           0 :                         if(set_cstat_from_conf(c, globalcs, cconfs))
     184           0 :                                 goto error;
     185             :                 }
     186             :                 // Only stop if the end of the list was not reached.
     187           0 :                 if(!c) break;
     188             :         }
     189           0 :         if(global_mtime!=global_mtime_new)
     190           0 :                 global_mtime=global_mtime_new;
     191           0 :         return 0;
     192             : error:
     193           0 :         confs_free(&cconfs);
     194           0 :         return -1;
     195             : }
     196             : 
     197           0 : int cstat_set_run_status(struct cstat *cstat)
     198             : {
     199             :         struct stat statp;
     200           0 :         struct sdirs *sdirs=(struct sdirs *)cstat->sdirs;
     201           0 :         if(!cstat->permitted) return 0;
     202             : 
     203           0 :         if(lstat(sdirs->lock->path, &statp))
     204             :         {
     205           0 :                 if(lstat(sdirs->working, &statp))
     206           0 :                         cstat->run_status=RUN_STATUS_IDLE;
     207             :                 else
     208           0 :                         cstat->run_status=RUN_STATUS_CLIENT_CRASHED;
     209             :         }
     210             :         else
     211             :         {
     212           0 :                 if(!lock_test(sdirs->lock->path)) // Could have got lock.
     213           0 :                         cstat->run_status=RUN_STATUS_SERVER_CRASHED;
     214             :                 else
     215           0 :                         cstat->run_status=RUN_STATUS_RUNNING;
     216             :         }
     217             : 
     218           0 :         return 0;
     219             : }
     220             : 
     221           0 : static int reload_from_clientdir(struct cstat **clist, struct conf **confs)
     222             : {
     223             :         struct cstat *c;
     224           0 :         for(c=*clist; c; c=c->next)
     225             :         {
     226           0 :                 time_t ltime=0;
     227             :                 struct stat statp;
     228             :                 struct stat lstatp;
     229             :                 struct sdirs *sdirs;
     230             : 
     231           0 :                 if(!c->permitted) continue;
     232             : 
     233           0 :                 sdirs=(struct sdirs *)c->sdirs;
     234           0 :                 if(!sdirs->client) continue;
     235           0 :                 if(stat(sdirs->client, &statp))
     236             :                 {
     237             :                         // No clientdir.
     238           0 :                         if(!c->run_status
     239           0 :                           && cstat_set_run_status(c))
     240           0 :                                 goto error;
     241           0 :                         continue;
     242             :                 }
     243           0 :                 if(!lstat(sdirs->lock->path, &lstatp))
     244           0 :                         ltime=lstatp.st_mtime;
     245           0 :                 if(statp.st_mtime==c->clientdir_mtime
     246           0 :                   && ltime==c->lockfile_mtime
     247           0 :                   && c->run_status!=RUN_STATUS_SERVER_CRASHED)
     248             :                   //&& !c->cntr)
     249             :                 {
     250             :                         // clientdir has not changed - no need to do anything.
     251           0 :                         continue;
     252             :                 }
     253           0 :                 c->clientdir_mtime=statp.st_mtime;
     254           0 :                 c->lockfile_mtime=ltime;
     255           0 :                 if(cstat_set_run_status(c)) goto error;
     256             : 
     257           0 :                 bu_list_free(&c->bu);
     258             : // FIX THIS: should probably not load everything each time.
     259             : //              if(bu_get_current(sdirs, &c->bu))
     260             : //                      goto error;
     261           0 :                 if(bu_get_list_with_working(sdirs, &c->bu, c))
     262           0 :                         goto error;
     263             :         }
     264           0 :         return 0;
     265             : error:
     266           0 :         return -1;
     267             : }
     268             : 
     269           0 : int cstat_load_data_from_disk(struct cstat **clist, struct conf **globalcs)
     270             : {
     271           0 :         return get_client_names(clist, globalcs)
     272           0 :           || reload_from_client_confs(clist, globalcs)
     273           0 :           || reload_from_clientdir(clist, globalcs);
     274             : }
     275             : 
     276           0 : int cstat_set_backup_list(struct cstat *cstat)
     277             : {
     278           0 :         struct bu *bu=NULL;
     279             : 
     280           0 :         if(!cstat->permitted) return 0;
     281             : 
     282             :         // Free any previous list.
     283           0 :         bu_list_free(&cstat->bu);
     284             : 
     285           0 :         if(bu_get_list_with_working((struct sdirs *)cstat->sdirs, &bu, cstat))
     286             :         {
     287             :                 //logp("error when looking up current backups\n");
     288           0 :                 return 0;
     289             :         }
     290             : 
     291             :         // Find the end of the list just loaded, so we can traverse
     292             :         // it backwards later.
     293           0 :         while(bu && bu->next) bu=bu->next;
     294             : 
     295           0 :         cstat->bu=bu;
     296           0 :         return 0;
     297             : }

Generated by: LCOV version 1.10