LCOV - code coverage report
Current view: top level - src/server/monitor - json_output.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 0 283 0.0 %
Date: 2015-10-31 Functions: 0 21 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 "../../cmd.h"
       7             : #include "../../cstat.h"
       8             : #include "../../fzp.h"
       9             : #include "../../prepend.h"
      10             : #include "../../yajl_gen_w.h"
      11             : #include "browse.h"
      12             : #include "json_output.h"
      13             : 
      14             : static int pretty_print=1;
      15             : 
      16           0 : void json_set_pretty_print(int value)
      17             : {
      18           0 :         pretty_print=value;
      19           0 : }
      20             : 
      21           0 : static int write_all(struct asfd *asfd)
      22             : {
      23           0 :         int ret=-1;
      24           0 :         size_t w=0;
      25           0 :         size_t len=0;
      26             :         const unsigned char *buf;
      27             : 
      28           0 :         yajl_gen_get_buf(yajl, &buf, &len);
      29           0 :         while(len)
      30             :         {
      31           0 :                 w=len;
      32           0 :                 if(w>ASYNC_BUF_LEN) w=ASYNC_BUF_LEN;
      33           0 :                 if((ret=asfd->write_strn(asfd, CMD_GEN /* not used */,
      34           0 :                         (const char *)buf, w)))
      35           0 :                                 break;
      36           0 :                 buf+=w;
      37           0 :                 len-=w;
      38             :         }
      39           0 :         if(!ret && !pretty_print)
      40           0 :                 ret=asfd->write_strn(asfd, CMD_GEN /* not used */, "\n", 1);
      41             : 
      42           0 :         yajl_gen_clear(yajl);
      43           0 :         return ret;
      44             : }
      45             : 
      46           0 : static int json_start(struct asfd *asfd)
      47             : {
      48           0 :         if(!yajl)
      49             :         {
      50           0 :                 if(!(yajl=yajl_gen_alloc(NULL)))
      51           0 :                         return -1;
      52           0 :                 yajl_gen_config(yajl, yajl_gen_beautify, pretty_print);
      53             :         }
      54           0 :         if(yajl_map_open_w()) return -1;
      55           0 :         return 0;
      56             : }
      57             : 
      58           0 : static int json_clients(void)
      59             : {
      60           0 :         if(yajl_gen_str_w("clients")
      61           0 :           || yajl_array_open_w())
      62           0 :                 return -1;
      63           0 :         return 0;
      64             : }
      65             : 
      66           0 : static int json_clients_end(void)
      67             : {
      68           0 :         if(yajl_array_close_w()) return -1;
      69           0 :         return 0;
      70             : }
      71             : 
      72           0 : static int json_end(struct asfd *asfd)
      73             : {
      74           0 :         int ret=-1;
      75           0 :         if(yajl_map_close_w())
      76           0 :                 goto end;
      77           0 :         ret=write_all(asfd);
      78             : end:
      79           0 :         yajl_gen_free(yajl);
      80           0 :         yajl=NULL;
      81           0 :         return ret;
      82             : }
      83             : 
      84           0 : static long timestamp_to_long(const char *buf)
      85             : {
      86             :         struct tm tm;
      87           0 :         const char *b=NULL;
      88           0 :         if(!(b=strchr(buf, ' '))) return 0;
      89           0 :         memset(&tm, 0, sizeof(struct tm));
      90           0 :         if(!strptime(b, " %Y-%m-%d %H:%M:%S", &tm)) return 0;
      91             :         // Tell mktime to use the daylight savings time setting
      92             :         // from the time zone of the system.
      93           0 :         tm.tm_isdst=-1;
      94           0 :         return (long)mktime(&tm);
      95             : }
      96             : 
      97           0 : static int flag_matches(struct bu *bu, uint16_t flag)
      98             : {
      99           0 :         return (bu && (bu->flags & flag));
     100             : }
     101             : 
     102           0 : static int flag_wrap_str(struct bu *bu, uint16_t flag, const char *field)
     103             : {
     104           0 :         if(!flag_matches(bu, flag)) return 0;
     105           0 :         return yajl_gen_str_w(field);
     106             : }
     107             : 
     108           0 : static struct fzp *open_backup_log(struct bu *bu, const char *logfile)
     109             : {
     110           0 :         char *path=NULL;
     111           0 :         struct fzp *fzp=NULL;
     112             : 
     113           0 :         char logfilereal[32]="";
     114           0 :         if(!strcmp(logfile, "backup"))
     115           0 :                 snprintf(logfilereal, sizeof(logfilereal), "log");
     116           0 :         else if(!strcmp(logfile, "restore"))
     117           0 :                 snprintf(logfilereal, sizeof(logfilereal), "restorelog");
     118           0 :         else if(!strcmp(logfile, "verify"))
     119           0 :                 snprintf(logfilereal, sizeof(logfilereal), "verifylog");
     120           0 :         else if(!strcmp(logfile, "backup_stats"))
     121           0 :                 snprintf(logfilereal, sizeof(logfilereal), "backup_stats");
     122           0 :         else if(!strcmp(logfile, "restore_stats"))
     123           0 :                 snprintf(logfilereal, sizeof(logfilereal), "restore_stats");
     124           0 :         else if(!strcmp(logfile, "verify_stats"))
     125           0 :                 snprintf(logfilereal, sizeof(logfilereal), "verify_stats");
     126             : 
     127           0 :         if(!(path=prepend_s(bu->path, logfilereal)))
     128           0 :                 goto end;
     129           0 :         if(!(fzp=fzp_gzopen(path, "rb")))
     130             :         {
     131           0 :                 if(astrcat(&path, ".gz", __func__)
     132           0 :                   || !(fzp=fzp_gzopen(path, "rb")))
     133           0 :                         goto end;
     134             :         }
     135             : end:
     136           0 :         free_w(&path);
     137           0 :         return fzp;
     138             : 
     139             : }
     140             : 
     141           0 : static int flag_wrap_str_zp(struct bu *bu, uint16_t flag, const char *field,
     142             :         const char *logfile)
     143             : {
     144           0 :         int ret=-1;
     145           0 :         struct fzp *fzp=NULL;
     146           0 :         if(!flag_matches(bu, flag)
     147           0 :           || !logfile || strcmp(logfile, field))
     148           0 :                 return 0;
     149           0 :         if(!(fzp=open_backup_log(bu, logfile))) goto end;
     150           0 :         if(yajl_gen_str_w(field)) goto end;
     151           0 :         if(yajl_array_open_w()) goto end;
     152           0 :         if(fzp)
     153             :         {
     154           0 :                 char *cp=NULL;
     155           0 :                 char buf[1024]="";
     156           0 :                 while(fzp_gets(fzp, buf, sizeof(buf)))
     157             :                 {
     158           0 :                         if((cp=strrchr(buf, '\n'))) *cp='\0';
     159           0 :                         if(yajl_gen_str_w(buf))
     160           0 :                                 goto end;
     161             :                 }
     162             :         }
     163           0 :         if(yajl_array_close_w()) goto end;
     164           0 :         ret=0;
     165             : end:
     166           0 :         fzp_close(&fzp);
     167           0 :         return ret;
     168             : }
     169             : 
     170           0 : static int do_counters(struct cntr *cntr)
     171             : {
     172             :         static char type[2];
     173             :         struct cntr_ent *e;
     174             : 
     175           0 :         cntr->ent[(uint8_t)CMD_TIMESTAMP_END]->count=(uint64_t)time(NULL);
     176           0 :         if(yajl_gen_str_w("counters")
     177           0 :           || yajl_array_open_w()) return -1;
     178           0 :         for(e=cntr->list; e; e=e->next)
     179             :         {
     180           0 :                 if(e->flags & CNTR_SINGLE_FIELD)
     181             :                 {
     182           0 :                         if(!e->count) continue;
     183           0 :                         snprintf(type, sizeof(type), "%c", e->cmd);
     184           0 :                         if(yajl_map_open_w()
     185           0 :                           || yajl_gen_str_pair_w("name", e->field)
     186           0 :                           || yajl_gen_str_pair_w("type", type)
     187           0 :                           || yajl_gen_int_pair_w("count", e->count)
     188           0 :                           || yajl_map_close_w())
     189           0 :                                 return -1;
     190             :                 }
     191           0 :                 else if(e->flags & CNTR_TABULATE)
     192             :                 {
     193           0 :                         if(!e->count
     194           0 :                           && !e->changed
     195           0 :                           && !e->same
     196           0 :                           && !e->deleted
     197           0 :                           && !e->phase1)
     198           0 :                                 continue;
     199           0 :                         snprintf(type, sizeof(type), "%c", e->cmd);
     200           0 :                         if(yajl_map_open_w()
     201           0 :                           || yajl_gen_str_pair_w("name", e->field)
     202           0 :                           || yajl_gen_str_pair_w("type", type)
     203           0 :                           || yajl_gen_int_pair_w("count", e->count)
     204           0 :                           || yajl_gen_int_pair_w("changed", e->changed)
     205           0 :                           || yajl_gen_int_pair_w("same", e->same)
     206           0 :                           || yajl_gen_int_pair_w("deleted", e->deleted)
     207           0 :                           || yajl_gen_int_pair_w("scanned", e->phase1)
     208           0 :                           || yajl_map_close_w())
     209           0 :                                 return -1;
     210             :                 }
     211             :         }
     212             : 
     213           0 :         if(yajl_array_close_w())
     214           0 :                 return -1;
     215           0 :         return 0;
     216             : }
     217             : 
     218           0 : static int json_send_backup(struct asfd *asfd, struct cstat *cstat,
     219             :         struct bu *bu, int print_flags,
     220             :         const char *logfile, const char *browse,
     221             :         struct conf **confs)
     222             : {
     223           0 :         long long bno=0;
     224           0 :         long long timestamp=0;
     225           0 :         if(!bu) return 0;
     226           0 :         bno=(long long)bu->bno;
     227           0 :         timestamp=(long long)timestamp_to_long(bu->timestamp);
     228             : 
     229           0 :         if(yajl_map_open_w()
     230           0 :           || yajl_gen_int_pair_w("number", bno)
     231           0 :           || yajl_gen_int_pair_w("timestamp", timestamp)
     232           0 :           || yajl_gen_str_w("flags")
     233           0 :           || yajl_array_open_w()
     234           0 :           || flag_wrap_str(bu, BU_HARDLINKED, "hardlinked")
     235           0 :           || flag_wrap_str(bu, BU_DELETABLE, "deletable")
     236           0 :           || flag_wrap_str(bu, BU_WORKING, "working")
     237           0 :           || flag_wrap_str(bu, BU_FINISHING, "finishing")
     238           0 :           || flag_wrap_str(bu, BU_CURRENT, "current")
     239           0 :           || flag_wrap_str(bu, BU_MANIFEST, "manifest")
     240           0 :           || yajl_array_close_w())
     241           0 :                 return -1;
     242           0 :         if(bu->flags & (BU_WORKING|BU_FINISHING))
     243             :         {
     244           0 :                 if(do_counters(cstat->cntr)) return -1;
     245             :         }
     246           0 :         if(print_flags
     247           0 :           && (bu->flags & (BU_LOG_BACKUP|BU_LOG_RESTORE|BU_LOG_VERIFY
     248             :                 |BU_STATS_BACKUP|BU_STATS_RESTORE|BU_STATS_VERIFY)))
     249             :         {
     250           0 :                 if(yajl_gen_str_w("logs")
     251           0 :                   || yajl_map_open_w()
     252           0 :                   || yajl_gen_str_w("list")
     253           0 :                   || yajl_array_open_w()
     254           0 :                   || flag_wrap_str(bu, BU_LOG_BACKUP, "backup")
     255           0 :                   || flag_wrap_str(bu, BU_LOG_RESTORE, "restore")
     256           0 :                   || flag_wrap_str(bu, BU_LOG_VERIFY, "verify")
     257           0 :                   || flag_wrap_str(bu, BU_STATS_BACKUP, "backup_stats")
     258           0 :                   || flag_wrap_str(bu, BU_STATS_RESTORE, "restore_stats")
     259           0 :                   || flag_wrap_str(bu, BU_STATS_VERIFY, "verify_stats")
     260           0 :                   || yajl_array_close_w())
     261           0 :                         return -1;
     262           0 :                 if(logfile)
     263             :                 {
     264           0 :                         if(flag_wrap_str_zp(bu,
     265           0 :                                 BU_LOG_BACKUP, "backup", logfile)
     266           0 :                           || flag_wrap_str_zp(bu,
     267           0 :                                 BU_LOG_RESTORE, "restore", logfile)
     268           0 :                           || flag_wrap_str_zp(bu,
     269           0 :                                 BU_LOG_VERIFY, "verify", logfile)
     270           0 :                           || flag_wrap_str_zp(bu,
     271           0 :                                 BU_STATS_BACKUP, "backup_stats", logfile)
     272           0 :                           || flag_wrap_str_zp(bu,
     273           0 :                                 BU_STATS_RESTORE, "restore_stats", logfile)
     274           0 :                           || flag_wrap_str_zp(bu,
     275           0 :                                 BU_STATS_VERIFY, "verify_stats", logfile))
     276           0 :                                         return -1;
     277             :                 }
     278           0 :                 if(yajl_map_close_w())
     279           0 :                         return -1;
     280           0 :                 if(browse)
     281             :                 {
     282           0 :                         if(yajl_gen_str_w("browse")) return -1;
     283           0 :                         if(yajl_map_open_w()) return -1;
     284           0 :                         if(yajl_gen_str_pair_w("directory", browse)) return -1;
     285           0 :                         if(yajl_gen_str_w("entries")) return -1;
     286           0 :                         if(yajl_array_open_w()) return -1;
     287           0 :                         if(browse_manifest(asfd, cstat, bu, browse, confs))
     288           0 :                                 return -1;
     289           0 :                         if(yajl_array_close_w()) return -1;
     290           0 :                         if(yajl_map_close_w()) return -1;
     291             : 
     292             :                 }
     293             :         }
     294           0 :         if(yajl_gen_map_close(yajl)!=yajl_gen_status_ok)
     295           0 :                 return -1;
     296             : 
     297           0 :         return 0;
     298             : }
     299             : 
     300           0 : static int json_send_client_start(struct asfd *asfd, struct cstat *cstat)
     301             : {
     302           0 :         const char *run_status=run_status_to_str(cstat);
     303             : 
     304           0 :         if(yajl_map_open_w()
     305           0 :           || yajl_gen_str_pair_w("name", cstat->name)
     306           0 :           || yajl_gen_str_pair_w("run_status", run_status))
     307           0 :                 return -1;
     308           0 :         if(cstat->run_status==RUN_STATUS_RUNNING)
     309             :         {
     310           0 :                 if(yajl_gen_str_pair_w("phase",
     311           0 :                         cntr_status_to_str(cstat->cntr))) return -1;
     312             :         }
     313           0 :         if(yajl_gen_str_w("backups")
     314           0 :           || yajl_array_open_w())
     315           0 :                 return -1;
     316           0 :         return 0;
     317             : }
     318             : 
     319           0 : static int json_send_client_end(struct asfd *asfd)
     320             : {
     321           0 :         if(yajl_array_close_w()
     322           0 :           || yajl_map_close_w())
     323           0 :                 return -1;
     324           0 :         return 0;
     325             : }
     326             : 
     327           0 : static int json_send_client_backup(struct asfd *asfd,
     328             :         struct cstat *cstat, struct bu *bu1, struct bu *bu2,
     329             :         const char *logfile, const char *browse, struct conf **confs)
     330             : {
     331           0 :         int ret=-1;
     332           0 :         if(json_send_client_start(asfd, cstat)) return -1;
     333           0 :         if((ret=json_send_backup(asfd, cstat,
     334             :                 bu1, 1 /* print flags */, logfile, browse, confs)))
     335           0 :                         goto end;
     336           0 :         if((ret=json_send_backup(asfd, cstat,
     337             :                 bu2, 1 /* print flags */, logfile, browse, confs)))
     338           0 :                         goto end;
     339             : end:
     340           0 :         if(json_send_client_end(asfd)) ret=-1;
     341           0 :         return ret;
     342             : }
     343             : 
     344           0 : static int json_send_client_backup_list(struct asfd *asfd, struct cstat *cstat)
     345             : {
     346           0 :         int ret=-1;
     347             :         struct bu *bu;
     348           0 :         if(json_send_client_start(asfd, cstat)) return -1;
     349           0 :         for(bu=cstat->bu; bu; bu=bu->prev)
     350             :         {
     351           0 :                 if(json_send_backup(asfd, cstat,
     352           0 :                         bu, 1 /* print flags */, NULL, NULL, NULL)) goto end;
     353             :         }
     354           0 :         ret=0;
     355             : end:
     356           0 :         if(json_send_client_end(asfd)) ret=-1;
     357           0 :         return ret;
     358             : }
     359             : 
     360           0 : int json_send(struct asfd *asfd, struct cstat *clist, struct cstat *cstat,
     361             :         struct bu *bu, const char *logfile, const char *browse,
     362             :         struct conf **confs)
     363             : {
     364           0 :         int ret=-1;
     365             :         struct cstat *c;
     366             : 
     367           0 :         if(json_start(asfd)
     368           0 :           || json_clients())
     369           0 :                 goto end;
     370             : 
     371           0 :         if(cstat && bu)
     372             :         {
     373           0 :                 if(json_send_client_backup(asfd, cstat, bu, NULL,
     374           0 :                         logfile, browse, confs)) goto end;
     375             :         }
     376           0 :         else if(cstat)
     377             :         {
     378           0 :                 if(json_send_client_backup_list(asfd, cstat)) goto end;
     379             :         }
     380           0 :         else for(c=clist; c; c=c->next)
     381             :         {
     382           0 :                 if(!c->permitted) continue;
     383           0 :                 if(json_send_client_backup(asfd, c,
     384             :                         bu_find_current(c->bu),
     385             :                         bu_find_working_or_finishing(c->bu),
     386           0 :                         NULL, NULL, NULL))
     387           0 :                                 goto end;
     388             :         }
     389             : 
     390           0 :         ret=0;
     391             : end:
     392           0 :         if(json_clients_end()
     393           0 :           || json_end(asfd)) return -1;
     394           0 :         return ret;
     395             : }
     396             : 
     397           0 : int json_cntr_to_file(struct asfd *asfd, struct cntr *cntr)
     398             : {
     399           0 :         int ret=-1;
     400           0 :         if(json_start(asfd)
     401           0 :           || do_counters(cntr))
     402           0 :                 goto end;
     403           0 :         ret=0;
     404             : end:
     405           0 :         if(json_end(asfd)) return -1;
     406           0 :         return ret;
     407             : }
     408             : 
     409           0 : int json_from_statp(const char *path, struct stat *statp)
     410             : {
     411           0 :         return yajl_map_open_w()
     412           0 :           || yajl_gen_str_pair_w("name", path)
     413           0 :           || yajl_gen_int_pair_w("dev", statp->st_dev)
     414           0 :           || yajl_gen_int_pair_w("ino", statp->st_ino)
     415           0 :           || yajl_gen_int_pair_w("mode", statp->st_mode)
     416           0 :           || yajl_gen_int_pair_w("nlink", statp->st_nlink)
     417           0 :           || yajl_gen_int_pair_w("uid", statp->st_uid)
     418           0 :           || yajl_gen_int_pair_w("gid", statp->st_gid)
     419           0 :           || yajl_gen_int_pair_w("rdev", statp->st_rdev)
     420           0 :           || yajl_gen_int_pair_w("size", statp->st_size)
     421           0 :           || yajl_gen_int_pair_w("blksize", statp->st_blksize)
     422           0 :           || yajl_gen_int_pair_w("blocks", statp->st_blocks)
     423           0 :           || yajl_gen_int_pair_w("atime", statp->st_atime)
     424           0 :           || yajl_gen_int_pair_w("ctime", statp->st_ctime)
     425           0 :           || yajl_gen_int_pair_w("mtime", statp->st_mtime)
     426           0 :           || yajl_map_close_w();
     427             : }
     428             : 
     429           0 : int json_send_warn(struct asfd *asfd, const char *msg)
     430             : {
     431           0 :         if(json_start(asfd)
     432           0 :           || yajl_gen_str_pair_w("warning", msg)
     433           0 :           || json_end(asfd)) return -1;
     434           0 :         return 0;
     435             : }

Generated by: LCOV version 1.10