LCOV - code coverage report
Current view: top level - src/server/monitor - cache.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 0 90 0.0 %
Date: 2016-03-31 Functions: 0 9 0.0 %

          Line data    Source code
       1             : #include "../../burp.h"
       2             : #include "../../alloc.h"
       3             : #include "../../bu.h"
       4             : #include "../../cmd.h"
       5             : #include "../../cstat.h"
       6             : #include "../../log.h"
       7             : #include "../../sbuf.h"
       8             : #include "../manio.h"
       9             : #include "json_output.h"
      10             : 
      11             : typedef struct ent ent_t;
      12             : 
      13             : struct ent
      14             : {
      15             :         char *name;
      16             :         int count;
      17             :         struct stat statp;
      18             :         struct ent **ents;
      19             : };
      20             : 
      21           0 : static void ent_free(struct ent **ent)
      22             : {
      23           0 :         if(!ent || !*ent) return;
      24           0 :         free_w(&(*ent)->name);
      25           0 :         free_v((void **)&(*ent)->ents);
      26           0 :         free_v((void **)ent);
      27             : }
      28             : 
      29           0 : static struct ent *ent_alloc(const char *name)
      30             : {
      31             :         struct ent *ent;
      32           0 :         if(!(ent=(struct ent *)calloc_w(1, sizeof(struct ent), __func__))
      33           0 :           || !(ent->name=strdup_w(name, __func__)))
      34             :                 goto error;
      35           0 :         return ent;
      36             : error:
      37           0 :         ent_free(&ent);
      38           0 :         return NULL;
      39             : }
      40             : 
      41             : // FIX THIS:
      42             : // For extra kicks, could make the config option allow multiple caches -
      43             : // eg, 'monitor_browse_cache=5', then rotate out the oldest one.
      44             : 
      45             : static struct ent *root=NULL;
      46             : static char *cached_client=NULL;
      47             : static unsigned long cached_bno=0;
      48             : 
      49           0 : static int ent_add_to_list(struct ent *ent,
      50             :         struct sbuf *sb, const char *ent_name)
      51             : {
      52           0 :         struct ent *enew=NULL;
      53           0 :         if(!(ent->ents=(struct ent **)realloc_w(ent->ents,
      54           0 :                 (ent->count+1)*sizeof(struct ent *), __func__))
      55           0 :           || !(enew=ent_alloc(ent_name)))
      56             :         {
      57           0 :                 log_out_of_memory(__func__);
      58             :                 return -1;
      59             :         }
      60           0 :         memcpy(&enew->statp, &sb->statp, sizeof(struct stat));
      61           0 :         ent->ents[ent->count]=enew;
      62           0 :         ent->count++;
      63             :         return 0;
      64             : }
      65             : 
      66           0 : static void ents_free(struct ent *ent)
      67             : {
      68           0 :         int i=0;
      69           0 :         for(i=0; i<ent->count; i++)
      70           0 :                 ents_free(ent->ents[i]);
      71           0 :         ent_free(&ent);
      72           0 : }
      73             : 
      74           0 : void cache_free(void)
      75             : {
      76           0 :         if(!root) return;
      77           0 :         ents_free(root);
      78             : }
      79             : 
      80             : /*
      81             : static void cache_dump(struct ent *e, int *depth)
      82             : {
      83             :         int count;
      84             :         for(count=0; count<*depth; count++)
      85             :                 printf(" ");
      86             :         printf("'%s'\n", e->name);
      87             :         for(count=0; count<e->count; count++)
      88             :         {
      89             :                 (*depth)++;
      90             :                 cache_dump(e->ents[count], depth);
      91             :                 (*depth)--;
      92             :         }
      93             : }
      94             : */
      95             : 
      96           0 : int cache_load(struct asfd *srfd, struct manio *manio, struct sbuf *sb,
      97             :         struct cstat *cstat, struct bu *bu)
      98             : {
      99           0 :         int ret=-1;
     100           0 :         int ars=0;
     101             : //      int depth=0;
     102           0 :         char *tok=NULL;
     103           0 :         struct ent *point=NULL;
     104           0 :         struct ent *p=NULL;
     105             : 
     106             : //printf("in cache load\n");
     107             :         cache_free();
     108             : 
     109           0 :         if(!(root=ent_alloc(""))) goto end;
     110             : 
     111             :         while(1)
     112             :         {
     113           0 :                 sbuf_free_content(sb);
     114           0 :                 if((ars=manio_read(manio, sb)))
     115             :                 {
     116           0 :                         if(ars<0) goto end;
     117             :                         // ars==1 means it ended ok.
     118             :                         break;
     119             :                 }
     120             : 
     121           0 :                 if(manio->protocol==PROTO_2 && sb->endfile.buf)
     122             :                         continue;
     123             : 
     124           0 :                 if(sb->path.cmd!=CMD_DIRECTORY
     125           0 :                   && sb->path.cmd!=CMD_FILE
     126           0 :                   && sb->path.cmd!=CMD_ENC_FILE
     127           0 :                   && sb->path.cmd!=CMD_EFS_FILE
     128           0 :                   && sb->path.cmd!=CMD_SPECIAL
     129           0 :                   && !cmd_is_link(sb->path.cmd))
     130             :                         continue;
     131             : 
     132             :                 // Some messing around so that we can list '/'.
     133           0 :                 if(!*(root->name) && !strncmp(sb->path.buf, "/", 1))
     134             :                 {
     135           0 :                         memcpy(&root->statp, &sb->statp, sizeof(struct stat));
     136           0 :                         free_w(&root->name);
     137           0 :                         if(!(root->name=strdup_w("/", __func__)))
     138             :                                 goto end;
     139             :                 }
     140             : 
     141           0 :                 point=root;
     142           0 :                 if((tok=strtok(sb->path.buf, "/"))) do
     143             :                 {
     144           0 :                         if(point->count>0)
     145             :                         {
     146           0 :                                 p=point->ents[point->count-1];
     147           0 :                                 if(!strcmp(tok, p->name))
     148             :                                 {
     149             :                                         point=p;
     150             :                                         continue;
     151             :                                 }
     152             :                         }
     153             : 
     154           0 :                         if(sb->path.buf+sb->path.len!=tok+strlen(tok))
     155             :                         {
     156             :                                 // There is an entry in a directory where the
     157             :                                 // directory itself was not backed up.
     158             :                                 // We will make a fake entry for the directory,
     159             :                                 // and use the same stat data.
     160             :                                 // Make sure that we set the directory flag.
     161           0 :                                 sb->statp.st_mode&=S_IFDIR;
     162             :                         }
     163           0 :                         if(ent_add_to_list(point, sb, tok)) goto end;
     164           0 :                         point=point->ents[point->count-1];
     165             :                 } while((tok=strtok(NULL, "/")));
     166             :         }
     167             : 
     168           0 :         if(!(cached_client=strdup_w(cstat->name, __func__)))
     169             :                 goto end;
     170           0 :         cached_bno=bu->bno;
     171           0 :         ret=0;
     172             : //      cache_dump(root, &depth);
     173             : end:
     174           0 :         return ret;
     175             : }
     176             : 
     177           0 : int cache_loaded(struct cstat *cstat, struct bu *bu)
     178             : {
     179           0 :         if(cached_client
     180           0 :           && !strcmp(cstat->name, cached_client)
     181           0 :           && cached_bno==bu->bno)
     182             :                 return 1;
     183           0 :         return 0;
     184             : }
     185             : 
     186             : static int result_single(struct ent *ent)
     187             : {
     188             : //      printf("result: %s\n", ent->name);
     189           0 :         return json_from_statp(ent->name, &ent->statp);
     190             : }
     191             : 
     192           0 : static int result_list(struct ent *ent)
     193             : {
     194           0 :         int i=0;
     195             : //      printf("in results\n");
     196           0 :         for(i=0; i<ent->count; i++)
     197           0 :                 result_single(ent->ents[i]);
     198           0 :         return 0;
     199             : }
     200             : 
     201           0 : int cache_lookup(const char *browse)
     202             : {
     203           0 :         int i=0;
     204           0 :         int ret=-1;
     205           0 :         char *tok=NULL;
     206           0 :         char *copy=NULL;
     207           0 :         struct ent *point=root;
     208             : 
     209           0 :         if(!browse || !*browse)
     210             :         {
     211             :                 // The difference between the top level for Windows and the
     212             :                 // top level for non-Windows.
     213           0 :                 if(*(point->name)) ret=result_single(point);
     214           0 :                 else ret=result_list(point);
     215             :                 goto end;
     216             :         }
     217             : 
     218           0 :         if(!(copy=strdup_w(browse, __func__)))
     219             :                 goto end;
     220           0 :         if((tok=strtok(copy, "/"))) do
     221             :         {
     222             :                 // FIX THIS: Should do a binary search here, for monster speed
     223             :                 // increases when there are lots of files in a directory.
     224           0 :                 for(i=0; i<point->count; i++)
     225             :                 {
     226           0 :                         if(strcmp(tok, point->ents[i]->name)) continue;
     227             :                         point=point->ents[i];
     228             :                         break;
     229             :                 }
     230             :         } while((tok=strtok(NULL, "/")));
     231             : 
     232           0 :         ret=result_list(point);
     233             : end:
     234           0 :         free_w(&copy);
     235           0 :         return ret;
     236             : }

Generated by: LCOV version 1.10