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

          Line data    Source code
       1             : #include "../../burp.h"
       2             : #include "../../alloc.h"
       3             : #include "../../asfd.h"
       4             : #include "../../async.h"
       5             : #include "../../bu.h"
       6             : #include "../../cstat.h"
       7             : #include "../../handy.h"
       8             : #include "../../iobuf.h"
       9             : #include "../../log.h"
      10             : #include "json_input.h"
      11             : #include "lline.h"
      12             : #include "status_client_ncurses.h"
      13             : #ifdef HAVE_WIN32
      14             : #include <yajl/yajl_parse.h>
      15             : #else
      16             : #include "../../yajl/api/yajl_parse.h"
      17             : #endif
      18             : 
      19             : static int map_depth=0;
      20             : 
      21             : static unsigned long number=0;
      22             : static char *timestamp=NULL;
      23             : static uint16_t flags=0;
      24             : static struct cstat *cnew=NULL;
      25             : static struct cstat *current=NULL;
      26             : static struct cstat **cslist=NULL;
      27             : static struct cntr_ent *cntr_ent=NULL;
      28             : static char lastkey[32]="";
      29             : static int in_backups=0;
      30             : static int in_flags=0;
      31             : static int in_counters=0;
      32             : static int in_logslist=0;
      33             : static int in_log_content=0;
      34             : static struct bu **sselbu=NULL;
      35             : static struct lline *ll_list=NULL;
      36             : static struct lline **sllines=NULL;
      37             : 
      38           0 : static int is_wrap(const char *val, const char *key, uint16_t bit)
      39             : {
      40           0 :         if(!strcmp(val, key))
      41             :         {
      42           0 :                 flags|=bit;
      43           0 :                 return 1;
      44             :         }
      45           0 :         return 0;
      46             : }
      47             : 
      48           0 : static int input_integer(void *ctx, long long val)
      49             : {
      50           0 :         if(in_counters)
      51             :         {
      52           0 :                 if(!strcmp(lastkey, "count"))
      53             :                 {
      54           0 :                         if(!cntr_ent) goto error;
      55           0 :                         cntr_ent->count=(uint64_t)val;
      56             :                 }
      57           0 :                 else if(!strcmp(lastkey, "changed"))
      58             :                 {
      59           0 :                         if(!cntr_ent) goto error;
      60           0 :                         cntr_ent->changed=(uint64_t)val;
      61             :                 }
      62           0 :                 else if(!strcmp(lastkey, "same"))
      63             :                 {
      64           0 :                         if(!cntr_ent) goto error;
      65           0 :                         cntr_ent->same=(uint64_t)val;
      66             :                 }
      67           0 :                 else if(!strcmp(lastkey, "deleted"))
      68             :                 {
      69           0 :                         if(!cntr_ent) goto error;
      70           0 :                         cntr_ent->deleted=(uint64_t)val;
      71             :                 }
      72           0 :                 else if(!strcmp(lastkey, "scanned"))
      73             :                 {
      74           0 :                         if(!cntr_ent) goto error;
      75           0 :                         cntr_ent->phase1=(uint64_t)val;
      76             :                 }
      77             :                 else
      78             :                 {
      79           0 :                         goto error;
      80             :                 }
      81           0 :                 return 1;
      82             :         }
      83           0 :         else if(in_backups && !in_flags && !in_counters && !in_logslist)
      84             :         {
      85           0 :                 if(!current) goto error;
      86           0 :                 if(!strcmp(lastkey, "number"))
      87             :                 {
      88           0 :                         number=(unsigned long)val;
      89           0 :                         return 1;
      90             :                 }
      91           0 :                 else if(!strcmp(lastkey, "timestamp"))
      92             :                 {
      93             :                         time_t t;
      94           0 :                         t=(unsigned long)val;
      95           0 :                         free_w(&timestamp);
      96           0 :                         if(!(timestamp=strdup_w(getdatestr(t), __func__)))
      97           0 :                                 return 0;
      98           0 :                         return 1;
      99             :                 }
     100             :         }
     101             : error:
     102           0 :         logp("Unexpected integer: %s %llu\n", lastkey, val);
     103           0 :         return 0;
     104             : }
     105             : 
     106           0 : static int input_string(void *ctx, const unsigned char *val, size_t len)
     107             : {
     108             :         char *str;
     109           0 :         if(!(str=(char *)malloc_w(len+2, __func__)))
     110           0 :                 return 0;
     111           0 :         snprintf(str, len+1, "%s", val);
     112             : 
     113           0 :         if(in_counters)
     114             :         {
     115           0 :                 if(!strcmp(lastkey, "name"))
     116             :                 {
     117             :                         // Ignore 'name' in a counters object. We use 'type'
     118             :                         // instead.
     119             :                 }
     120           0 :                 else if(!strcmp(lastkey, "type"))
     121             :                 {
     122           0 :                         if(!current) goto error;
     123           0 :                         cntr_ent=current->cntr->ent[(uint8_t)*str];
     124             :                 }
     125             :                 else
     126             :                 {
     127           0 :                         goto error;
     128             :                 }
     129           0 :                 goto end;
     130             :         }
     131           0 :         else if(!strcmp(lastkey, "name"))
     132             :         {
     133           0 :                 if(cnew) goto error;
     134           0 :                 if(!(current=cstat_get_by_name(*cslist, str)))
     135             :                 {
     136           0 :                         if(!(cnew=cstat_alloc())
     137           0 :                           || cstat_init_with_cntr(cnew, str, NULL))
     138           0 :                                 goto error;
     139           0 :                         current=cnew;
     140             :                 }
     141           0 :                 goto end;
     142             :         }
     143           0 :         else if(!strcmp(lastkey, "run_status"))
     144             :         {
     145           0 :                 if(!current) goto error;
     146           0 :                 current->run_status=run_str_to_status(str);
     147           0 :                 goto end;
     148             :         }
     149           0 :         else if(!strcmp(lastkey, "phase"))
     150             :         {
     151           0 :                 if(!current) goto error;
     152           0 :                 current->cntr->cntr_status=cntr_str_to_status(str);
     153           0 :                 goto end;
     154             :         }
     155           0 :         else if(!strcmp(lastkey, "flags"))
     156             :         {
     157           0 :                 if(!current) goto error;
     158           0 :                 if(is_wrap(str, "hardlinked", BU_HARDLINKED)
     159           0 :                   || is_wrap(str, "deletable", BU_DELETABLE)
     160           0 :                   || is_wrap(str, "working", BU_WORKING)
     161           0 :                   || is_wrap(str, "finishing", BU_FINISHING)
     162           0 :                   || is_wrap(str, "current", BU_CURRENT)
     163           0 :                   || is_wrap(str, "manifest", BU_MANIFEST))
     164           0 :                         goto end;
     165             :         }
     166           0 :         else if(!strcmp(lastkey, "counters")) // Do we need this?
     167             :         {
     168           0 :                 goto end;
     169             :         }
     170           0 :         else if(!strcmp(lastkey, "list"))
     171             :         {
     172           0 :                 if(is_wrap(str, "backup", BU_LOG_BACKUP)
     173           0 :                   || is_wrap(str, "restore", BU_LOG_RESTORE)
     174           0 :                   || is_wrap(str, "verify", BU_LOG_VERIFY)
     175           0 :                   || is_wrap(str, "backup_stats", BU_STATS_BACKUP)
     176           0 :                   || is_wrap(str, "restore_stats", BU_STATS_RESTORE)
     177           0 :                   || is_wrap(str, "verify_stats", BU_STATS_VERIFY))
     178           0 :                         goto end;
     179             :         }
     180           0 :         else if(!strcmp(lastkey, "logs"))
     181             :         {
     182           0 :                 goto end;
     183             :         }
     184           0 :         else if(!strcmp(lastkey, "logline"))
     185             :         {
     186           0 :                 goto end;
     187             :         }
     188           0 :         else if(!strcmp(lastkey, "backup")
     189           0 :           || !strcmp(lastkey, "restore")
     190           0 :           || !strcmp(lastkey, "verify")
     191           0 :           || !strcmp(lastkey, "backup_stats")
     192           0 :           || !strcmp(lastkey, "restore_stats")
     193           0 :           || !strcmp(lastkey, "verify_stats"))
     194             :         {
     195             :                 // Log file contents.
     196           0 :                 if(lline_add(&ll_list, str))
     197           0 :                         goto error;
     198           0 :                 goto end;
     199             :         }
     200             : error:
     201           0 :         logp("Unexpected string: %s %s\n", lastkey, str);
     202           0 :         free_w(&str);
     203           0 :         return 0;
     204             : end:
     205           0 :         free_w(&str);
     206           0 :         return 1;
     207             : }
     208             : 
     209           0 : static int input_map_key(void *ctx, const unsigned char *val, size_t len)
     210             : {
     211           0 :         snprintf(lastkey, len+1, "%s", val);
     212             : //      logp("mapkey: %s\n", lastkey);
     213           0 :         return 1;
     214             : }
     215             : 
     216             : static struct bu *bu_list=NULL;
     217             : 
     218           0 : static int add_to_bu_list(void)
     219             : {
     220             :         struct bu *bu;
     221             :         struct bu *last;
     222           0 :         if(!number) return 0;
     223           0 :         if(!(bu=bu_alloc())) return -1;
     224           0 :         bu->bno=number;
     225           0 :         bu->flags=flags;
     226           0 :         bu->timestamp=timestamp;
     227             : 
     228             :         // FIX THIS: Inefficient to find the end each time.
     229           0 :         for(last=bu_list; last && last->next; last=last->next) { }
     230           0 :         if(last)
     231             :         {
     232           0 :                 last->next=bu;
     233           0 :                 bu->prev=last;
     234             :         }
     235             :         else
     236             :         {
     237           0 :                 bu_list=bu;
     238           0 :                 bu_list->prev=NULL;
     239             :         }
     240             :         
     241           0 :         number=0;
     242           0 :         flags=0;
     243           0 :         timestamp=NULL;
     244           0 :         return 0;
     245             : }
     246             : 
     247           0 : static int input_start_map(void *ctx)
     248             : {
     249           0 :         map_depth++;
     250             :         //logp("startmap: %d\n", map_depth);
     251           0 :         return 1;
     252             : }
     253             : 
     254           0 : static int input_end_map(void *ctx)
     255             : {
     256           0 :         map_depth--;
     257             :         //logp("endmap: %d\n", map_depth);
     258           0 :         if(in_backups && !in_flags && !in_counters && !in_logslist)
     259             :         {
     260           0 :                 if(add_to_bu_list()) return 0;
     261             :         }
     262           0 :         return 1;
     263             : }
     264             : 
     265           0 : static int input_start_array(void *ctx)
     266             : {
     267             :         //logp("start arr\n");
     268           0 :         if(!strcmp(lastkey, "backups"))
     269             :         {
     270           0 :                 in_backups=1;
     271             :         }
     272           0 :         else if(!strcmp(lastkey, "flags"))
     273             :         {
     274           0 :                 in_flags=1;
     275             :         }
     276           0 :         else if(!strcmp(lastkey, "counters"))
     277             :         {
     278           0 :                 in_counters=1;
     279             :         }
     280           0 :         else if(!strcmp(lastkey, "list"))
     281             :         {
     282           0 :                 in_logslist=1;
     283             :         }
     284           0 :         else if(!strcmp(lastkey, "backup")
     285           0 :           || !strcmp(lastkey, "restore")
     286           0 :           || !strcmp(lastkey, "verify")
     287           0 :           || !strcmp(lastkey, "backup_stats")
     288           0 :           || !strcmp(lastkey, "restore_stats")
     289           0 :           || !strcmp(lastkey, "verify_stats"))
     290             :         {
     291           0 :                 in_log_content=1;
     292             :         }
     293           0 :         return 1;
     294             : }
     295             : 
     296           0 : static void merge_bu_lists(void)
     297             : {
     298             :         struct bu *n;
     299             :         struct bu *o;
     300           0 :         struct bu *lastn=NULL;
     301           0 :         struct bu *lasto=NULL;
     302             : 
     303           0 :         for(o=current->bu; o; )
     304             :         {
     305           0 :                 int found_in_new=0;
     306           0 :                 lastn=NULL;
     307           0 :                 for(n=bu_list; n; n=n->next)
     308             :                 {
     309           0 :                         if(o->bno==n->bno)
     310             :                         {
     311             :                                 // Found o in new list.
     312             :                                 // Copy the fields from new to old.
     313           0 :                                 found_in_new=1;
     314           0 :                                 o->flags=n->flags;
     315           0 :                                 free_w(&o->timestamp);
     316           0 :                                 o->timestamp=n->timestamp;
     317           0 :                                 n->timestamp=NULL;
     318             : 
     319             :                                 // Remove it from new list.
     320           0 :                                 if(lastn)
     321             :                                 {
     322           0 :                                         lastn->next=n->next;
     323           0 :                                         if(n->next) n->next->prev=lastn;
     324             :                                 }
     325             :                                 else
     326             :                                 {
     327           0 :                                         bu_list=n->next;
     328           0 :                                         if(bu_list) bu_list->prev=NULL;
     329             :                                 }
     330           0 :                                 bu_free(&n);
     331           0 :                                 n=lastn;
     332           0 :                                 break;
     333             :                         }
     334           0 :                         lastn=n;
     335             :                 }
     336           0 :                 if(!found_in_new)
     337             :                 {
     338             :                         // Could not find o in new list.
     339             :                         // Remove it from old list.
     340           0 :                         if(lasto)
     341             :                         {
     342           0 :                                 lasto->next=o->next;
     343           0 :                                 if(o->next) o->next->prev=lasto;
     344             :                         }
     345             :                         else
     346             :                         {
     347           0 :                                 current->bu=o->next;
     348           0 :                                 if(current->bu) current->bu->prev=NULL;
     349             :                         }
     350             :                         // Need to reset if the one that was removed was
     351             :                         // selected in ncurses.
     352           0 :                         if(o==*sselbu) *sselbu=NULL;
     353           0 :                         bu_free(&o);
     354           0 :                         o=lasto;
     355             :                 }
     356           0 :                 lasto=o;
     357           0 :                 if(o) o=o->next;
     358             :         }
     359             : 
     360             :         // Now, new list only has entries missing from old list.
     361           0 :         n=bu_list;
     362           0 :         lastn=NULL;
     363           0 :         while(n)
     364             :         {
     365           0 :                 o=current->bu;
     366           0 :                 lasto=NULL;
     367           0 :                 while(o && n->bno < o->bno)
     368             :                 {
     369           0 :                         lasto=o;
     370           0 :                         o=o->next;
     371             :                 }
     372             :                 // Found the place to insert it.
     373           0 :                 if(lasto)
     374             :                 {
     375           0 :                         lasto->next=n;
     376           0 :                         n->prev=lasto;
     377             :                 }
     378             :                 else
     379             :                 {
     380           0 :                         if(current->bu) current->bu->prev=n;
     381           0 :                         current->bu=n;
     382           0 :                         current->bu->prev=NULL;
     383             :                 }
     384           0 :                 lastn=n->next;
     385           0 :                 n->next=o;
     386           0 :                 n=lastn;
     387             :         }
     388           0 : }
     389             : 
     390           0 : static int input_end_array(void *ctx)
     391             : {
     392           0 :         if(in_backups && !in_flags && !in_counters && !in_logslist)
     393             :         {
     394           0 :                 in_backups=0;
     395           0 :                 if(add_to_bu_list()) return 0;
     396             :                 // Now may have two lists. Want to keep the old one is intact
     397             :                 // as possible, so that we can keep a pointer to its entries
     398             :                 // in the ncurses stuff.
     399             :                 // Merge the new list into the old.
     400           0 :                 merge_bu_lists();
     401           0 :                 bu_list=NULL;
     402           0 :                 if(cnew)
     403             :                 {
     404           0 :                         if(cstat_add_to_list(cslist, cnew)) return -1;
     405           0 :                         cnew=NULL;
     406             :                 }
     407           0 :                 current=NULL;
     408             :         }
     409           0 :         else if(in_flags)
     410             :         {
     411           0 :                 in_flags=0;
     412             :         }
     413           0 :         else if(in_counters)
     414             :         {
     415           0 :                 in_counters=0;
     416             :         }
     417           0 :         else if(in_logslist)
     418             :         {
     419           0 :                 in_logslist=0;
     420             :         }
     421           0 :         else if(in_log_content)
     422             :         {
     423           0 :                 in_log_content=0;
     424           0 :                 llines_free(sllines);
     425           0 :                 *sllines=ll_list;
     426           0 :                 ll_list=NULL;
     427             :         }
     428           0 :         return 1;
     429             : }
     430             : 
     431             : static yajl_callbacks callbacks = {
     432             :         NULL,
     433             :         NULL,
     434             :         input_integer,
     435             :         NULL,
     436             :         NULL,
     437             :         input_string,
     438             :         input_start_map,
     439             :         input_map_key,
     440             :         input_end_map,
     441             :         input_start_array,
     442             :         input_end_array
     443             : };
     444             : 
     445           0 : static void do_yajl_error(yajl_handle yajl, struct asfd *asfd)
     446             : {
     447             :         unsigned char *str;
     448             :         str=yajl_get_error(yajl, 1,
     449           0 :                 (const unsigned char *)asfd->rbuf->buf, asfd->rbuf->len);
     450           0 :         logp("yajl error: %s\n", (const char *)str);
     451           0 :         yajl_free_error(yajl, str);
     452           0 : }
     453             : 
     454             : // Client records will be coming through in alphabetical order.
     455             : // FIX THIS: If a client is deleted on the server, it is not deleted from
     456             : // clist.
     457           0 : int json_input(struct asfd *asfd, struct sel *sel)
     458             : {
     459             :         static yajl_handle yajl=NULL;
     460           0 :         cslist=&sel->clist;
     461           0 :         sselbu=&sel->backup;
     462           0 :         sllines=&sel->llines;
     463             : 
     464           0 :         if(!yajl)
     465             :         {
     466           0 :                 if(!(yajl=yajl_alloc(&callbacks, NULL, NULL)))
     467           0 :                         goto error;
     468           0 :                 yajl_config(yajl, yajl_dont_validate_strings, 1);
     469             :         }
     470           0 :         if(yajl_parse(yajl, (const unsigned char *)asfd->rbuf->buf,
     471           0 :                 asfd->rbuf->len)!=yajl_status_ok)
     472             :         {
     473           0 :                 do_yajl_error(yajl, asfd);
     474           0 :                 goto error;
     475             :         }
     476             : 
     477           0 :         if(!map_depth)
     478             :         {
     479             :                 // Got to the end of the JSON object.
     480           0 :                 if(!sel->gotfirstresponse) sel->gotfirstresponse=1;
     481           0 :                 if(yajl_complete_parse(yajl)!=yajl_status_ok)
     482             :                 {
     483           0 :                         do_yajl_error(yajl, asfd);
     484           0 :                         goto error;
     485             :                 }
     486           0 :                 yajl_free(yajl);
     487           0 :                 yajl=NULL;
     488             :         }
     489             : 
     490           0 :         return 0;
     491             : error:
     492           0 :         yajl_free(yajl);
     493           0 :         yajl=NULL;
     494           0 :         return -1;
     495             : }

Generated by: LCOV version 1.10