LCOV - code coverage report
Current view: top level - src - cntr.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 9 470 1.9 %
Date: 2015-10-31 Functions: 4 47 8.5 %

          Line data    Source code
       1             : #include "burp.h"
       2             : #include "alloc.h"
       3             : #include "asfd.h"
       4             : #include "async.h"
       5             : #include "cmd.h"
       6             : #include "cntr.h"
       7             : #include "cstat.h"
       8             : #include "fsops.h"
       9             : #include "handy.h"
      10             : #include "log.h"
      11             : 
      12             : #include "server/monitor/json_output.h"
      13             : 
      14             : #include <limits.h>
      15             : 
      16             : #define CNTR_VERSION            3
      17             : #define CNTR_PATH_BUF_LEN       256
      18             : 
      19           0 : static void cntr_ent_free(struct cntr_ent *cntr_ent)
      20             : {
      21           0 :         if(!cntr_ent) return;
      22           0 :         if(cntr_ent->field) free(cntr_ent->field);
      23           0 :         if(cntr_ent->label) free(cntr_ent->label);
      24             : }
      25             : 
      26           0 : struct cntr *cntr_alloc(void)
      27             : {
      28           0 :         return (struct cntr *)calloc_w(1, sizeof(struct cntr), __func__);
      29             : }
      30             : 
      31           0 : static int add_cntr_ent(struct cntr *cntr, int flags,
      32             :         enum cmd cmd, const char *field, const char *label)
      33             : {
      34           0 :         struct cntr_ent *cenew=NULL;
      35           0 :         if(!(cenew=(struct cntr_ent *)
      36             :             calloc_w(1, sizeof(struct cntr_ent), __func__))
      37           0 :           || !(cenew->field=strdup_w(field, __func__))
      38           0 :           || !(cenew->label=strdup_w(label, __func__)))
      39           0 :                 goto error;
      40           0 :         cenew->flags=flags;
      41           0 :         cenew->cmd=cmd;
      42             : 
      43           0 :         if(cntr->list) cenew->next=cntr->list;
      44           0 :         cntr->list=cenew;
      45             : 
      46           0 :         cntr->ent[(uint8_t)cmd]=cenew;
      47           0 :         return 0;
      48             : error:
      49           0 :         cntr_ent_free(cenew);
      50           0 :         return -1;
      51             : }
      52             : 
      53           0 : static size_t calc_max_str_len(struct cntr *cntr, const char *cname)
      54             : {
      55           0 :         size_t slen=0;
      56             :         char ullmax[64];
      57           0 :         struct cntr_ent *e=NULL;
      58             : 
      59             :         // See cntr_to_str().
      60             :         // First section - name/version/status
      61           0 :         slen+=strlen(cname);
      62           0 :         slen+=16; // More than enough space.
      63             : 
      64             :         // Second section.
      65             :         snprintf(ullmax, sizeof(ullmax),
      66           0 :                 " %"PRIu64 "\n", (uint64_t)ULLONG_MAX);
      67           0 :         for(e=cntr->list; e; e=e->next)
      68             :         {
      69           0 :                 if(e->flags & CNTR_SINGLE_FIELD)
      70             :                         // %c%llu\t
      71           0 :                         slen+=strlen(ullmax)+2;
      72             :                 else
      73             :                         // %c%llu/%llu/%llu/%llu/%llu\t
      74           0 :                         slen+=(strlen(ullmax)*5)+6;
      75             :         }
      76             : 
      77             :         // Fourth section - a path. Cannot know how long this might be. Guess.
      78           0 :         slen+=CNTR_PATH_BUF_LEN+3; // %c%s\t\n
      79             : 
      80           0 :         slen+=1; // Terminating character.
      81             : 
      82           0 :         return slen;
      83             : }
      84             : 
      85           0 : int cntr_init(struct cntr *cntr, const char *cname)
      86             : {
      87           0 :         if(!cname)
      88             :         {
      89           0 :                 logp("%s called with no client name\n", __func__);
      90           0 :                 return -1;
      91             :         }
      92             : 
      93             :         // Add in reverse order, so that iterating over from the beginning
      94             :         // comes out in the right order.
      95           0 :         if(
      96             :              add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
      97           0 :                 CMD_TIMESTAMP_END, "time_end", "End time")
      98           0 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
      99           0 :                 CMD_TIMESTAMP, "time_start", "Start time")
     100           0 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     101           0 :                 CMD_BYTES_SENT, "bytes_sent", "Bytes sent")
     102           0 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     103           0 :                 CMD_BYTES_RECV, "bytes_received", "Bytes received")
     104           0 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     105           0 :                 CMD_BYTES, "bytes", "Bytes")
     106           0 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     107           0 :                 CMD_BYTES_ESTIMATED, "bytes_estimated", "Bytes estimated")
     108           0 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     109           0 :                 CMD_MESSAGE, "messages", "Messages")
     110           0 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     111           0 :                 CMD_WARNING, "warnings", "Warnings")
     112           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     113           0 :                 CMD_GRAND_TOTAL, "grand_total", "Grand total")
     114           0 :           || add_cntr_ent(cntr, 0,
     115           0 :                 CMD_TOTAL, "total", "Total")
     116           0 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     117           0 :                 CMD_ERROR, "errors", "Errors")
     118           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     119           0 :                 CMD_DATA, "blocks", "Blocks")
     120           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     121           0 :                 CMD_EFS_FILE, "efs_files", "EFS files")
     122           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     123           0 :                 CMD_ENC_VSS_T, "vss_footers_encrypted", "VSS footers (enc)")
     124           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     125           0 :                 CMD_VSS_T, "vss_footers", "VSS footers")
     126           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     127           0 :                 CMD_ENC_VSS, "vss_headers_encrypted", "VSS headers (enc)")
     128           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     129           0 :                 CMD_VSS, "vss_headers", "VSS headers")
     130           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     131           0 :                 CMD_SPECIAL, "special_files", "Special files")
     132           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     133           0 :                 CMD_SOFT_LINK, "hard_links", "Soft links")
     134           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     135           0 :                 CMD_HARD_LINK, "soft_links", "Hard links")
     136           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     137           0 :                 CMD_DIRECTORY, "directories", "Directories")
     138           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     139           0 :                 CMD_ENC_METADATA, "meta_data_encrypted", "Meta data (enc)")
     140           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     141           0 :                 CMD_METADATA, "meta_data", "Meta data")
     142           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     143           0 :                 CMD_ENC_FILE, "files_encrypted", "Files (encrypted)")
     144           0 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     145           0 :                 CMD_FILE, "files", "Files")
     146             :         )
     147           0 :                 return -1;
     148             : 
     149           0 :         cntr->ent[(uint8_t)CMD_TIMESTAMP]->count=(uint64_t)time(NULL);
     150             : 
     151           0 :         cntr->str_max_len=calc_max_str_len(cntr, cname);
     152           0 :         if(!(cntr->str=(char *)calloc_w(1, cntr->str_max_len, __func__))
     153           0 :           || !(cntr->cname=strdup_w(cname, __func__)))
     154           0 :                 return -1;
     155             : 
     156           0 :         return 0;
     157             : }
     158             : 
     159          40 : void cntr_free(struct cntr **cntr)
     160             : {
     161             :         struct cntr_ent *e;
     162          40 :         struct cntr_ent *l=NULL;
     163          80 :         if(!cntr || !*cntr) return;
     164           0 :         for(e=(*cntr)->list; e; e=l)
     165             :         {
     166           0 :                 l=e->next;
     167           0 :                 cntr_ent_free(e);
     168             :         }
     169           0 :         (*cntr)->list=NULL;
     170           0 :         free_w(&(*cntr)->str);
     171           0 :         free_v((void **)cntr);
     172             : }
     173             : 
     174           0 : const char *bytes_to_human(uint64_t counter)
     175             : {
     176             :         static char ret[32]="";
     177           0 :         float div=(float)counter;
     178           0 :         char units[3]="";
     179             : 
     180           0 :         if(div<1024) return "";
     181             : 
     182           0 :         if((div/=1024)<1024)
     183           0 :                 snprintf(units, sizeof(units), "KB");
     184           0 :         else if((div/=1024)<1024)
     185           0 :                 snprintf(units, sizeof(units), "MB");
     186           0 :         else if((div/=1024)<1024)
     187           0 :                 snprintf(units, sizeof(units), "GB");
     188           0 :         else if((div/=1024)<1024)
     189           0 :                 snprintf(units, sizeof(units), "TB");
     190           0 :         else if((div/=1024)<1024)
     191           0 :                 snprintf(units, sizeof(units), "EB");
     192             :         else
     193             :         {
     194           0 :                 div/=1024;
     195           0 :                 snprintf(units, sizeof(units), "PB");
     196             :         }
     197           0 :         snprintf(ret, sizeof(ret), " (%.2f %s)", div, units);
     198           0 :         return ret;
     199             : }
     200             : 
     201           0 : static void border(void)
     202             : {
     203           0 :         logc("--------------------------------------------------------------------------------\n");
     204           0 : }
     205             : 
     206           0 : static void table_border(enum action act)
     207             : {
     208           0 :         if(act==ACTION_BACKUP
     209           0 :           || act==ACTION_BACKUP_TIMED)
     210             :         {
     211           0 :           logc("% 18s ------------------------------------------------------------\n", "");
     212             :         }
     213           0 :         if(act==ACTION_RESTORE
     214           0 :           || act==ACTION_VERIFY)
     215             :         {
     216           0 :           logc("% 18s ------------------------------\n", "");
     217             :         }
     218           0 : }
     219             : 
     220           0 : static void incr_count_val(struct cntr *cntr, char ch, uint64_t val)
     221             : {
     222           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->count+=val;
     223           0 : }
     224             : 
     225           0 : static void incr_same_val(struct cntr *cntr, char ch, uint64_t val)
     226             : {
     227           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->same+=val;
     228           0 : }
     229             : 
     230           0 : static void incr_changed_val(struct cntr *cntr, char ch, uint64_t val)
     231             : {
     232           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->changed+=val;
     233           0 : }
     234             : 
     235           0 : static void incr_deleted_val(struct cntr *cntr, char ch, uint64_t val)
     236             : {
     237           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->deleted+=val;
     238           0 : }
     239             : 
     240           0 : static void incr_phase1_val(struct cntr *cntr, char ch, uint64_t val)
     241             : {
     242           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->phase1+=val;
     243           0 : }
     244             : 
     245           0 : static void incr_count(struct cntr *cntr, char ch)
     246             : {
     247           0 :         return incr_count_val(cntr, ch, 1);
     248             : }
     249             : 
     250           0 : static void incr_same(struct cntr *cntr, char ch)
     251             : {
     252           0 :         return incr_same_val(cntr, ch, 1);
     253             : }
     254             : 
     255           0 : static void incr_changed(struct cntr *cntr, char ch)
     256             : {
     257           0 :         return incr_changed_val(cntr, ch, 1);
     258             : }
     259             : 
     260           0 : static void incr_deleted(struct cntr *cntr, char ch)
     261             : {
     262           0 :         return incr_deleted_val(cntr, ch, 1);
     263             : }
     264             : 
     265           0 : static void incr_phase1(struct cntr *cntr, char ch)
     266             : {
     267           0 :         return incr_phase1_val(cntr, ch, 1);
     268             : }
     269             : 
     270           0 : static void print_end(uint64_t val)
     271             : {
     272           0 :         if(val) logc(" %"PRIu64 "\n", val);
     273           0 : }
     274             : 
     275           2 : void cntr_add(struct cntr *c, char ch, int print)
     276             : {
     277             :         struct cntr_ent *grand_total_ent;
     278           2 :         if(!c) return;
     279           0 :         if(!(grand_total_ent=c->ent[CMD_GRAND_TOTAL])) return;
     280           0 :         if(print)
     281             :         {
     282           0 :                 if(ch!=CMD_MESSAGE && ch!=CMD_WARNING)
     283           0 :                         logc("%c", ch);
     284             :         }
     285           0 :         if(ch==CMD_FILE_CHANGED)
     286             :         {
     287           0 :                 incr_changed(c, CMD_FILE);
     288           0 :                 incr_changed(c, CMD_TOTAL);
     289           0 :                 incr_changed(c, CMD_GRAND_TOTAL);
     290             :         }
     291             :         else
     292             :         {
     293           0 :                 incr_count(c, ch);
     294           0 :                 if(ch==CMD_WARNING || ch==CMD_MESSAGE) return;
     295           0 :                 incr_count(c, CMD_TOTAL);
     296             :         }
     297             : 
     298           0 :         if(!((++grand_total_ent->count)%64) && print)
     299           0 :                 print_end(grand_total_ent->count);
     300           0 :         fflush(stdout);
     301             : }
     302             : 
     303           0 : void cntr_add_phase1(struct cntr *c, char ch, int print)
     304             : {
     305             :         static struct cntr_ent *total;
     306           0 :         incr_phase1(c, ch);
     307             : 
     308           0 :         total=c->ent[(uint8_t)CMD_GRAND_TOTAL];
     309           0 :         ++total->phase1;
     310           0 :         if(!print) return;
     311           0 :         if(total->phase1==1) logc("\n");
     312           0 :         logc("%c", ch);
     313           0 :         if(!((total->phase1)%64))
     314           0 :                 print_end(total->phase1);
     315           0 :         fflush(stdout);
     316             : }
     317             : 
     318           0 : void cntr_add_val(struct cntr *c, char ch, uint64_t val, int print)
     319             : {
     320           0 :         incr_count_val(c, ch, val);
     321           0 : }
     322             : 
     323           0 : void cntr_add_same(struct cntr *c, char ch)
     324             : {
     325           0 :         incr_same(c, ch);
     326           0 :         incr_same(c, CMD_TOTAL);
     327           0 :         incr_same(c, CMD_GRAND_TOTAL);
     328           0 : }
     329             : 
     330           0 : void cntr_add_same_val(struct cntr *c, char ch, uint64_t val)
     331             : {
     332           0 :         incr_same_val(c, ch, val);
     333           0 :         incr_same_val(c, CMD_TOTAL, val);
     334           0 :         incr_same_val(c, CMD_GRAND_TOTAL, val);
     335           0 : }
     336             : 
     337           0 : void cntr_add_changed(struct cntr *c, char ch)
     338             : {
     339           0 :         incr_changed(c, ch);
     340           0 :         incr_changed(c, CMD_TOTAL);
     341           0 :         incr_changed(c, CMD_GRAND_TOTAL);
     342           0 : }
     343             : 
     344           0 : void cntr_add_changed_val(struct cntr *c, char ch, uint64_t val)
     345             : {
     346           0 :         incr_changed_val(c, ch, val);
     347           0 :         incr_changed_val(c, CMD_TOTAL, val);
     348           0 :         incr_changed_val(c, CMD_GRAND_TOTAL, val);
     349           0 : }
     350             : 
     351           0 : void cntr_add_deleted(struct cntr *c, char ch)
     352             : {
     353           0 :         incr_deleted(c, ch);
     354           0 :         incr_deleted(c, CMD_TOTAL);
     355           0 :         incr_deleted(c, CMD_GRAND_TOTAL);
     356           0 : }
     357             : 
     358           0 : void cntr_add_bytes(struct cntr *c, uint64_t bytes)
     359             : {
     360           0 :         incr_count_val(c, CMD_BYTES, bytes);
     361           0 : }
     362             : 
     363           0 : void cntr_add_sentbytes(struct cntr *c, uint64_t bytes)
     364             : {
     365           0 :         incr_count_val(c, CMD_BYTES_SENT, bytes);
     366           0 : }
     367             : 
     368           0 : void cntr_add_recvbytes(struct cntr *c, uint64_t bytes)
     369             : {
     370           0 :         incr_count_val(c, CMD_BYTES_RECV, bytes);
     371           0 : }
     372             : 
     373           0 : static void quint_print(struct cntr_ent *ent, enum action act)
     374             : {
     375             :         uint64_t a;
     376             :         uint64_t b;
     377             :         uint64_t c;
     378             :         uint64_t d;
     379             :         uint64_t e;
     380           0 :         if(!ent) return;
     381           0 :         a=ent->count;
     382           0 :         b=ent->changed;
     383           0 :         c=ent->same;
     384           0 :         d=ent->deleted;
     385           0 :         e=ent->phase1;
     386             : 
     387           0 :         if(!(ent->flags & CNTR_TABULATE)) return;
     388             : 
     389           0 :         if(!e && !a && !b && !c) return;
     390           0 :         logc("% 18s:", ent->label);
     391           0 :         if(act==ACTION_BACKUP
     392           0 :           || act==ACTION_BACKUP_TIMED)
     393             :         {
     394           0 :                 logc("% 9llu ", a);
     395           0 :                 logc("% 9llu ", b);
     396           0 :                 logc("% 9llu ", c);
     397           0 :                 logc("% 9llu ", d);
     398             :         }
     399           0 :         if(act==ACTION_RESTORE
     400           0 :           || act==ACTION_VERIFY)
     401             :         {
     402           0 :                 logc("% 9s ", "");
     403             :                 //logc("% 9s ", "");
     404             :                 //logc("% 9s ", "");
     405             :                 //logc("% 9s ", "");
     406             :         }
     407           0 :         if(act==ACTION_ESTIMATE)
     408             :         {
     409           0 :                 logc("% 9s ", "");
     410           0 :                 logc("% 9s ", "");
     411           0 :                 logc("% 9llu\n", e);
     412             :         }
     413             :         else
     414             :         {
     415           0 :                 logc("% 9llu |", a+b+c);
     416           0 :                 logc("% 9llu\n", e);
     417             :         }
     418             : }
     419             : 
     420           0 : static uint64_t get_count(struct cntr_ent **ent, enum cmd cmd)
     421             : {
     422           0 :         if(!ent[(uint8_t)cmd]) return 0;
     423           0 :         return ent[(uint8_t)cmd]->count;
     424             : }
     425             : 
     426           0 : static void bottom_part(struct cntr *c, enum action act)
     427             : {
     428             :         uint64_t l;
     429           0 :         struct cntr_ent **e=c->ent;
     430           0 :         logc("\n");
     431           0 :         logc("             Messages:   % 11llu\n", get_count(e, CMD_MESSAGE));
     432           0 :         logc("             Warnings:   % 11llu\n", get_count(e, CMD_WARNING));
     433           0 :         logc("\n");
     434           0 :         logc("      Bytes estimated:   % 11llu", get_count(e, CMD_BYTES_ESTIMATED));
     435           0 :         logc("%s\n", bytes_to_human(get_count(e, CMD_BYTES_ESTIMATED)));
     436             : 
     437           0 :         if(act==ACTION_ESTIMATE) return;
     438             : 
     439           0 :         if(act==ACTION_BACKUP
     440           0 :           || act==ACTION_BACKUP_TIMED)
     441             :         {
     442           0 :                 l=get_count(e, CMD_BYTES);
     443           0 :                 logc("      Bytes in backup:   % 11llu", l);
     444           0 :                 logc("%s\n", bytes_to_human(l));
     445             :         }
     446           0 :         if(act==ACTION_RESTORE)
     447             :         {
     448           0 :                 l=get_count(e, CMD_BYTES);
     449           0 :                 logc("      Bytes attempted:   % 11llu", l);
     450           0 :                 logc("%s\n", bytes_to_human(l));
     451             :         }
     452           0 :         if(act==ACTION_VERIFY)
     453             :         {
     454           0 :                 l=get_count(e, CMD_BYTES);
     455           0 :                 logc("        Bytes checked:   % 11llu", l);
     456           0 :                 logc("%s\n", bytes_to_human(l));
     457             :         }
     458             : 
     459           0 :         if(act==ACTION_BACKUP
     460           0 :           || act==ACTION_BACKUP_TIMED)
     461             :         {
     462           0 :                 l=get_count(e, CMD_BYTES_RECV);
     463           0 :                 logc("       Bytes received:   % 11llu", l);
     464           0 :                 logc("%s\n", bytes_to_human(l));
     465             :         }
     466           0 :         if(act==ACTION_BACKUP 
     467           0 :           || act==ACTION_BACKUP_TIMED
     468           0 :           || act==ACTION_RESTORE)
     469             :         {
     470           0 :                 l=get_count(e, CMD_BYTES_SENT);
     471           0 :                 logc("           Bytes sent:   % 11llu", l);
     472           0 :                 logc("%s\n", bytes_to_human(l));
     473             :         }
     474             : }
     475             : 
     476           2 : void cntr_print(struct cntr *cntr, enum action act)
     477             : {
     478             :         struct cntr_ent *e;
     479             :         time_t now;
     480             :         time_t start;
     481           4 :         if(!cntr) return;
     482           0 :         now=time(NULL);
     483           0 :         start=(time_t)cntr->ent[(uint8_t)CMD_TIMESTAMP]->count;
     484           0 :         cntr->ent[(uint8_t)CMD_TIMESTAMP_END]->count=(uint64_t)now;
     485             : 
     486           0 :         border();
     487           0 :         logc("Start time: %s\n", getdatestr(start));
     488           0 :         logc("  End time: %s\n", getdatestr(now));
     489           0 :         logc("Time taken: %s\n", time_taken(now-start));
     490           0 :         if(act==ACTION_BACKUP
     491           0 :           || act==ACTION_BACKUP_TIMED)
     492             :         {
     493             :           logc("% 18s % 9s % 9s % 9s % 9s % 9s |% 9s\n",
     494           0 :             " ", "New", "Changed", "Unchanged", "Deleted", "Total", "Scanned");
     495             :         }
     496           0 :         if(act==ACTION_RESTORE
     497           0 :           || act==ACTION_VERIFY)
     498             :         {
     499             :           logc("% 18s % 9s % 9s |% 9s\n",
     500           0 :             " ", "", "Attempted", "Expected");
     501             :         }
     502           0 :         if(act==ACTION_ESTIMATE)
     503             :         {
     504             :           logc("% 18s % 9s % 9s %9s\n",
     505           0 :             " ", "", "", "Scanned");
     506             :         }
     507           0 :         table_border(act);
     508             : 
     509           0 :         for(e=cntr->list; e; e=e->next)
     510           0 :                 quint_print(e, act);
     511             : 
     512           0 :         table_border(act);
     513           0 :         bottom_part(cntr, act);
     514             : 
     515           0 :         border();
     516             : }
     517             : 
     518             : #ifndef HAVE_WIN32
     519             : 
     520           0 : int cntr_stats_to_file(struct cntr *cntr,
     521             :         const char *directory, enum action act, struct conf **confs)
     522             : {
     523           0 :         int ret=-1;
     524           0 :         int fd=-1;
     525           0 :         char *path=NULL;
     526           0 :         const char *fname=NULL;
     527           0 :         struct async *as=NULL;
     528           0 :         struct asfd *wfd=NULL;
     529           0 :         cntr->ent[(uint8_t)CMD_TIMESTAMP_END]->count
     530           0 :                 =(uint64_t)time(NULL);
     531             : 
     532           0 :         if(act==ACTION_BACKUP
     533           0 :           ||  act==ACTION_BACKUP_TIMED)
     534           0 :                 fname="backup_stats";
     535           0 :         else if(act==ACTION_RESTORE)
     536           0 :                 fname="restore_stats";
     537           0 :         else if(act==ACTION_VERIFY)
     538           0 :                 fname="verify_stats";
     539             :         else
     540           0 :                 return 0;
     541             : 
     542           0 :         if(!(path=prepend_s(directory, fname)))
     543           0 :                 goto end;
     544           0 :         if((fd=open(path, O_WRONLY|O_CREAT, 0666))<0)
     545             :         {
     546             :                 logp("Could not open %s for writing in %s: %s\n",
     547           0 :                         path, __func__, strerror(errno));
     548           0 :                 goto end;
     549             :         }
     550             :         // FIX THIS:
     551             :         // Pretty heavy duty to set up all this async stuff just so that the
     552             :         // json stuff can write to a simple file.
     553           0 :         if(!(as=async_alloc())
     554           0 :           || as->init(as, 0)
     555           0 :           || !(wfd=asfd_alloc())
     556           0 :           || wfd->init(wfd, "stats file",
     557           0 :                 as, fd, NULL, ASFD_STREAM_LINEBUF, confs))
     558           0 :                         goto end;
     559           0 :         as->asfd_add(as, wfd);
     560           0 :         fd=-1;
     561           0 :         if(json_cntr_to_file(wfd, cntr))
     562           0 :                 goto end;
     563             : 
     564             : // FIX THIS: make this use the json output stuff.
     565             : // Need to add the following few fields to the cntrs somehow.
     566             : /*
     567             :         fprintf(fp, "client_version:%s\n",
     568             :                 conf->peer_version?conf->peer_version:"");
     569             :         fprintf(fp, "server_version:%s\n", VERSION);
     570             :         fprintf(fp, "client_is_windows:%d\n", conf->client_is_windows);
     571             :         for(e=cntr->list; e; e=e->next)
     572             :                 quint_print_to_file(fp, e, act);
     573             : */
     574             : 
     575           0 :         ret=0;
     576             : end:
     577           0 :         close_fd(&fd);
     578           0 :         free_w(&path);
     579           0 :         async_free(&as);
     580           0 :         asfd_free(&wfd);
     581           0 :         return ret;
     582             : }
     583             : 
     584             : #endif
     585             : 
     586           2 : void cntr_print_end(struct cntr *cntr)
     587             : {
     588             :         struct cntr_ent *grand_total_ent;
     589           4 :         if(!cntr) return;
     590           0 :         grand_total_ent=cntr->ent[CMD_GRAND_TOTAL];
     591           0 :         if(grand_total_ent)
     592             :         {
     593           0 :                 print_end(grand_total_ent->count);
     594           0 :                 logc("\n");
     595             :         }
     596             : }
     597             : 
     598           0 : void cntr_print_end_phase1(struct cntr *cntr)
     599             : {
     600             :         struct cntr_ent *grand_total_ent;
     601           0 :         if(!cntr) return;
     602           0 :         grand_total_ent=cntr->ent[CMD_GRAND_TOTAL];
     603           0 :         if(grand_total_ent)
     604             :         {
     605           0 :                 print_end(grand_total_ent->phase1);
     606           0 :                 logc("\n");
     607             :         }
     608             : }
     609             : 
     610             : #ifndef HAVE_WIN32
     611             : // Return string length.
     612           0 : size_t cntr_to_str(struct cntr *cntr, const char *path)
     613             : {
     614             :         static char tmp[CNTR_PATH_BUF_LEN+3]="";
     615           0 :         struct cntr_ent *e=NULL;
     616           0 :         char *str=cntr->str;
     617             : 
     618           0 :         cntr->ent[(uint8_t)CMD_TIMESTAMP_END]->count=time(NULL);
     619             : 
     620             :         snprintf(str, cntr->str_max_len-1, "%s\t%d\t%d\t",
     621           0 :                 cntr->cname, CNTR_VERSION, cntr->cntr_status);
     622             : 
     623           0 :         for(e=cntr->list; e; e=e->next)
     624             :         {
     625           0 :                 if(e->flags & CNTR_SINGLE_FIELD)
     626             :                         snprintf(tmp, sizeof(tmp),
     627           0 :                                 "%c%"PRIu64"\t", e->cmd, e->count);
     628             :                 else
     629             :                         snprintf(tmp, sizeof(tmp),
     630             :                         "%c%"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64"\t",
     631             :                                 e->cmd, e->count, e->same,
     632           0 :                                 e->changed, e->deleted, e->phase1);
     633           0 :                 strcat(str, tmp);
     634             :         }
     635             : 
     636             :         // Abuse CMD_DATAPTH.
     637           0 :         snprintf(tmp, sizeof(tmp), "%c%s\t\n", CMD_DATAPTH, path?path:"");
     638           0 :         strcat(str, tmp);
     639             : 
     640           0 :         return strlen(str);
     641             : }
     642             : #endif
     643             : 
     644           0 : static int extract_ul(const char *value, struct cntr_ent *ent)
     645             : {
     646           0 :         char *as=NULL;
     647           0 :         char *bs=NULL;
     648           0 :         char *cs=NULL;
     649           0 :         char *ds=NULL;
     650           0 :         char *es=NULL;
     651           0 :         char *copy=NULL;
     652           0 :         if(!value || !(copy=strdup_w(value, __func__))) return -1;
     653             : 
     654             :         // Do not want to use strtok, just in case I end up running more
     655             :         // than one at a time.
     656           0 :         as=copy;
     657           0 :         if((bs=strchr(as, '/')))
     658             :         {
     659           0 :                 *bs='\0';
     660           0 :                 ent->count=strtoull(as, NULL, 10);
     661           0 :                 if((cs=strchr(++bs, '/')))
     662             :                 {
     663           0 :                         *cs='\0';
     664           0 :                         ent->changed=strtoull(bs, NULL, 10);
     665           0 :                         if((ds=strchr(++cs, '/')))
     666             :                         {
     667           0 :                                 *ds='\0';
     668           0 :                                 ent->same=strtoull(cs, NULL, 10);
     669           0 :                                 if((es=strchr(++ds, '/')))
     670             :                                 {
     671           0 :                                         ent->deleted=strtoull(ds, NULL, 10);
     672           0 :                                         *es='\0';
     673           0 :                                         es++;
     674           0 :                                         ent->phase1=strtoull(es, NULL, 10);
     675             :                                 }
     676             :                         }
     677             :                 }
     678             :         }
     679             :         else
     680             :         {
     681             :                 // Single field.
     682           0 :                 ent->count=strtoull(as, NULL, 10);
     683             :         }
     684           0 :         free(copy);
     685           0 :         return 0;
     686             : }
     687             : 
     688             : /*
     689             : static char *get_backup_str(const char *s, int *deletable)
     690             : {
     691             :         static char str[32]="";
     692             :         const char *cp=NULL;
     693             :         const char *dp=NULL;
     694             :         if(!s || !*s) return NULL;
     695             :         if(!(cp=strchr(s, ' '))
     696             :           || !(dp=strchr(cp+1, ' ')))
     697             :                 snprintf(str, sizeof(str), "never");
     698             :         else
     699             :         {
     700             :                 uint64_t backupnum=0;
     701             :                 backupnum=strtoul(s, NULL, 10);
     702             :                 snprintf(str, sizeof(str),
     703             :                         "%07lu %s", backupnum, getdatestr(atol(dp+1)));
     704             :                 if(*(cp+1)=='1') *deletable=1;
     705             :         }
     706             :         return str;
     707             : }
     708             : */
     709             : 
     710             : /*
     711             : static int add_to_backup_list(struct strlist **backups, const char *tok)
     712             : {
     713             :         int deletable=0;
     714             :         const char *str=NULL;
     715             :         if(!(str=get_backup_str(tok, &deletable))) return 0;
     716             :         if(strlist_add(backups, (char *)str, deletable)) return -1;
     717             :         return 0;
     718             : }
     719             : */
     720             : 
     721           0 : static int extract_cntrs(struct cstat *cstat, char **path)
     722             : {
     723             :         char *tok;
     724           0 :         struct cntr *cntr=cstat->cntr;
     725           0 :         while((tok=strtok(NULL, "\t\n")))
     726             :         {
     727           0 :                 switch(tok[0])
     728             :                 {
     729             :                         case CMD_DATAPTH:
     730           0 :                                 free_w(path);
     731           0 :                                 if(!(*path=strdup_w(tok+1, __func__)))
     732           0 :                                         return -1;
     733           0 :                                 break;
     734             :                         default:
     735           0 :                                 if(cntr->ent[(uint8_t)tok[0]]
     736           0 :                                   && extract_ul(tok+1,
     737           0 :                                         cntr->ent[(uint8_t)tok[0]]))
     738           0 :                                                 return -1;
     739           0 :                                 break;
     740             :                 }
     741             :         }
     742           0 :         return 0;
     743             : }
     744             : 
     745           0 : int str_to_cntr(const char *str, struct cstat *cstat, char **path)
     746             : {
     747           0 :         int ret=-1;
     748           0 :         char *tok=NULL;
     749           0 :         char *copy=NULL;
     750             : 
     751           0 :         if(!(copy=strdup_w(str, __func__)))
     752           0 :                 return -1;
     753             : 
     754           0 :         if((tok=strtok(copy, "\t\n")))
     755             :         {
     756           0 :                 char *tmp=NULL;
     757             :                 // First token is the client name. Do not need that here.
     758             :                 // Second is the cntr version.
     759           0 :                 if(!(tmp=strtok(NULL, "\t\n")))
     760             :                 {
     761             :                         logp("Parsing problem in %s: null version\n",
     762           0 :                                 __func__);
     763           0 :                         goto end;
     764             :                 }
     765           0 :                 if(atoi(tmp)!=CNTR_VERSION)
     766             :                 {
     767           0 :                         ret=0;
     768           0 :                         goto end;
     769             :                 }
     770             :                 // Third is cstat_status.
     771           0 :                 if(!(tmp=strtok(NULL, "\t\n")))
     772             :                 {
     773             :                         logp("Parsing problem in %s: null cstat_status\n",
     774           0 :                                 __func__);
     775           0 :                         goto end;
     776             :                 }
     777           0 :                 cstat->cntr->cntr_status=(enum cntr_status)atoi(tmp);
     778             : 
     779           0 :                 if(extract_cntrs(cstat, path)) goto end;
     780             :         }
     781             : 
     782           0 :         ret=0;
     783             : end:
     784           0 :         free_w(&copy);
     785           0 :         return ret;
     786             : }
     787             : 
     788             : #ifndef HAVE_WIN32
     789           0 : int cntr_send(struct cntr *cntr)
     790             : {
     791             : /*
     792             :         size_t l;
     793             :         char buf[4096]="";
     794             :         l=cntr_to_str(get_cntr(confs[OPT_CNTR]), STATUS_RUNNING, " ");
     795             :         if(async_write_strn(CMD_GEN, buf, l))
     796             :         {
     797             :                 logp("Error when sending counters to client.\n");
     798             :                 return -1;
     799             :         }
     800             : */
     801           0 :         return 0;
     802             : }
     803             : #endif
     804             : 
     805           0 : static enum asl_ret cntr_recv_func(struct asfd *asfd,
     806             :         struct conf **confs, void *param)
     807             : {
     808             : /*
     809             :         if(str_to_cntr(asfd->rbuf->buf, NULL, NULL, NULL, NULL,
     810             :                 conf->p1cntr, get_cntr(confs[OPT_CNTR]), NULL))
     811             :                         return ASL_END_ERROR;
     812             : */
     813           0 :         return ASL_END_OK;
     814             : }
     815             : 
     816           0 : int cntr_recv(struct asfd *asfd, struct conf **confs)
     817             : {
     818           0 :         return asfd->simple_loop(asfd, confs, NULL, __func__, cntr_recv_func);
     819             : }
     820             : 
     821           0 : const char *cntr_status_to_str(struct cntr *cntr)
     822             : {
     823           0 :         switch(cntr->cntr_status)
     824             :         {
     825           0 :                 case CNTR_STATUS_SCANNING: return CNTR_STATUS_STR_SCANNING;
     826           0 :                 case CNTR_STATUS_BACKUP: return CNTR_STATUS_STR_BACKUP;
     827           0 :                 case CNTR_STATUS_MERGING: return CNTR_STATUS_STR_MERGING;
     828           0 :                 case CNTR_STATUS_SHUFFLING: return CNTR_STATUS_STR_SHUFFLING;
     829           0 :                 case CNTR_STATUS_LISTING: return CNTR_STATUS_STR_LISTING;
     830           0 :                 case CNTR_STATUS_RESTORING: return CNTR_STATUS_STR_RESTORING;
     831           0 :                 case CNTR_STATUS_VERIFYING: return CNTR_STATUS_STR_VERIFYING;
     832           0 :                 case CNTR_STATUS_DELETING: return CNTR_STATUS_STR_DELETING;
     833           0 :                 case CNTR_STATUS_DIFFING: return CNTR_STATUS_STR_DIFFING;
     834           0 :                 default: return "unknown";
     835             :         }
     836             : }
     837             : 
     838           0 : enum cntr_status cntr_str_to_status(const char *str)
     839             : {
     840           0 :         if(!strcmp(str, CNTR_STATUS_STR_SCANNING))
     841           0 :                 return CNTR_STATUS_SCANNING;
     842           0 :         else if(!strcmp(str, CNTR_STATUS_STR_BACKUP))
     843           0 :                 return CNTR_STATUS_BACKUP;
     844           0 :         else if(!strcmp(str, CNTR_STATUS_STR_MERGING))
     845           0 :                 return CNTR_STATUS_MERGING;
     846           0 :         else if(!strcmp(str, CNTR_STATUS_STR_SHUFFLING))
     847           0 :                 return CNTR_STATUS_SHUFFLING;
     848           0 :         else if(!strcmp(str, CNTR_STATUS_STR_LISTING))
     849           0 :                 return CNTR_STATUS_LISTING;
     850           0 :         else if(!strcmp(str, CNTR_STATUS_STR_RESTORING))
     851           0 :                 return CNTR_STATUS_RESTORING;
     852           0 :         else if(!strcmp(str, CNTR_STATUS_STR_VERIFYING))
     853           0 :                 return CNTR_STATUS_VERIFYING;
     854           0 :         else if(!strcmp(str, CNTR_STATUS_STR_DELETING))
     855           0 :                 return CNTR_STATUS_DELETING;
     856           0 :         else if(!strcmp(str, CNTR_STATUS_STR_DIFFING))
     857           0 :                 return CNTR_STATUS_DIFFING;
     858           0 :         return CNTR_STATUS_UNSET;
     859             : }

Generated by: LCOV version 1.10