vnstat  2.9
About: vnStat is a console-based network traffic monitor (using the /proc filesystem).
  Fossies Dox: vnstat-2.9.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

dbshow.c
Go to the documentation of this file.
1#include "common.h"
2#include "dbsql.h"
3#include "misc.h"
4#include "dbshow.h"
5
6void showdb(const char *interface, int qmode, const char *databegin, const char *dataend)
7{
8 interfaceinfo info;
9
10 if (!db_getinterfacecountbyname(interface)) {
11 return;
12 }
13
14 if (!db_getinterfaceinfo(interface, &info)) {
15 return;
16 }
17
18 if (info.created == info.updated) {
19 printf(" %s: Not enough data available yet.\n", interface);
20 return;
21 }
22
23 switch (qmode) {
24 case 0:
25 showsummary(&info, 0);
26 break;
27 case 1:
28 showlist(&info, "day", databegin, dataend);
29 break;
30 case 2:
31 showlist(&info, "month", databegin, dataend);
32 break;
33 case 3:
34 showlist(&info, "top", databegin, dataend);
35 break;
36 case 5:
37 showsummary(&info, 1);
38 break;
39 case 6:
40 showlist(&info, "year", databegin, dataend);
41 break;
42 case 7:
43 showhours(&info);
44 break;
45 case 9:
46 showoneline(&info);
47 break;
48 case 11:
49 showlist(&info, "hour", databegin, dataend);
50 break;
51 case 12:
52 showlist(&info, "fiveminute", databegin, dataend);
53 break;
54 default:
55 printf("Error: Not such query mode: %d\n", qmode);
56 break;
57 }
58}
59
60void showsummary(const interfaceinfo *interface, const int shortmode)
61{
62 struct tm *d;
63 char datebuff[DATEBUFFLEN];
64 char todaystr[DATEBUFFLEN], yesterdaystr[DATEBUFFLEN];
65 char fieldseparator[8];
66 uint64_t e_rx, e_tx;
67 time_t current, yesterday;
68 dbdatalist *datalist = NULL, *datalist_i = NULL;
69 dbdatalistinfo datainfo;
70
72
73 current = time(NULL);
74 yesterday = current - 86400;
75
76 if (interface->updated && !shortmode) {
77 strftime(datebuff, DATEBUFFLEN, DATETIMEFORMAT, localtime(&interface->updated));
78 printf("Database updated: %s\n\n", datebuff);
79 } else if (!shortmode) {
80 printf("\n");
81 }
82
83 if (!shortmode) {
84 snprintf(fieldseparator, 8, " | ");
85 indent(3);
86 } else {
87 snprintf(fieldseparator, 8, " / ");
88 indent(1);
89 }
90 if (strcmp(interface->name, interface->alias) == 0 || strlen(interface->alias) == 0) {
91 printf("%s", interface->name);
92 } else {
93 printf("%s (%s)", interface->alias, interface->name);
94 }
95 if (interface->active == 0) {
96 printf(" [disabled]");
97 }
98 if (shortmode) {
99 printf(":\n");
100 } else {
101 /* get formatted date for creation date */
102 d = localtime(&interface->created);
103 strftime(datebuff, DATEBUFFLEN, cfg.tformat, d);
104 printf(" since %s\n\n", datebuff);
105
106 indent(10);
107 printf("rx: %s", getvalue(interface->rxtotal, 1, RT_Normal));
108 indent(3);
109 printf(" tx: %s", getvalue(interface->txtotal, 1, RT_Normal));
110 indent(3);
111 printf(" total: %s\n\n", getvalue(interface->rxtotal + interface->txtotal, 1, RT_Normal));
112
113 indent(3);
114 printf("monthly\n");
115 indent(5);
116
117 if (cfg.ostyle >= 2) {
118 printf(" rx | tx | total | avg. rate\n");
119 indent(5);
120 printf("------------------------+-------------+-------------+---------------\n");
121 } else {
122 printf(" rx | tx | total\n");
123 indent(5);
124 printf("------------------------+-------------+------------\n");
125 }
126 }
127
128 if (!db_getdata(&datalist, &datainfo, interface->name, "month", 2)) {
129 printf("Error: Failed to fetch month data.\n");
130 return;
131 }
132
133 e_rx = e_tx = 0;
134 datalist_i = datalist;
135
136 while (datalist_i != NULL) {
137 indent(5);
138 d = localtime(&datalist_i->timestamp);
139 if (strftime(datebuff, DATEBUFFLEN, cfg.mformat, d) <= 8) {
140 printf("%*s %s", getpadding(9, datebuff), datebuff, getvalue(datalist_i->rx, 11, RT_Normal));
141 } else {
142 printf("%-*s %s", getpadding(11, datebuff), datebuff, getvalue(datalist_i->rx, 11, RT_Normal));
143 }
144 printf("%s%s", fieldseparator, getvalue(datalist_i->tx, 11, RT_Normal));
145 printf("%s%s", fieldseparator, getvalue(datalist_i->rx + datalist_i->tx, 11, RT_Normal));
146 if (cfg.ostyle >= 2) {
147 if (datalist_i->next == NULL && issametimeslot(LT_Month, datalist_i->timestamp, interface->updated)) {
148 if (datalist_i->rx == 0 || datalist_i->tx == 0 || (interface->updated - datalist_i->timestamp) == 0) {
149 e_rx = e_tx = 0;
150 } else {
151 e_rx = (uint64_t)((double)datalist_i->rx / (double)(mosecs(datalist_i->timestamp, interface->updated))) * (uint64_t)(dmonth(d->tm_mon) * 86400);
152 e_tx = (uint64_t)((double)datalist_i->tx / (double)(mosecs(datalist_i->timestamp, interface->updated))) * (uint64_t)(dmonth(d->tm_mon) * 86400);
153 }
154 if (shortmode && cfg.ostyle != 0) {
155 printf("%s%s", fieldseparator, getvalue(e_rx + e_tx, 11, RT_Estimate));
156 } else if (!shortmode) {
157 printf("%s%s", fieldseparator, gettrafficrate(datalist_i->rx + datalist_i->tx, mosecs(datalist_i->timestamp, interface->updated), 14));
158 }
159 } else if (!shortmode) {
160 printf(" | %s", gettrafficrate(datalist_i->rx + datalist_i->tx, dmonth(d->tm_mon) * 86400, 14));
161 }
162 }
163 printf("\n");
164 datalist_i = datalist_i->next;
165 }
166
167 if (!datalist) {
168 indent(5 + 27);
169 printf("no data available\n");
170 }
171
172 if (!shortmode) {
173 indent(5);
174 if (cfg.ostyle >= 2) {
175 printf("------------------------+-------------+-------------+---------------\n");
176 } else {
177 printf("------------------------+-------------+------------\n");
178 }
179 indent(5);
180 printf("estimated %s", getvalue(e_rx, 11, RT_Estimate));
181 printf(" | %s", getvalue(e_tx, 11, RT_Estimate));
182 printf(" | %s", getvalue(e_rx + e_tx, 11, RT_Estimate));
183 if (cfg.ostyle >= 2) {
184 printf(" |\n\n");
185 } else {
186 printf("\n\n");
187 }
188 }
189
190 dbdatalistfree(&datalist);
191
192 if (!shortmode) {
193 indent(3);
194 printf("daily\n");
195 indent(5);
196
197 if (cfg.ostyle >= 2) {
198 printf(" rx | tx | total | avg. rate\n");
199 indent(5);
200 printf("------------------------+-------------+-------------+---------------\n");
201 } else {
202 printf(" rx | tx | total\n");
203 indent(5);
204 printf("------------------------+-------------+------------\n");
205 }
206 }
207
208 /* get formatted date for today and yesterday */
209 d = localtime(&current);
210 strftime(todaystr, DATEBUFFLEN, cfg.dformat, d);
211 d = localtime(&yesterday);
212 strftime(yesterdaystr, DATEBUFFLEN, cfg.dformat, d);
213
214 if (!db_getdata(&datalist, &datainfo, interface->name, "day", 2)) {
215 printf("Error: Failed to fetch day data.\n");
216 return;
217 }
218
219 e_rx = e_tx = 0;
220 datalist_i = datalist;
221
222 while (datalist_i != NULL) {
223 indent(5);
224 d = localtime(&datalist_i->timestamp);
225 strftime(datebuff, DATEBUFFLEN, cfg.dformat, d);
226 if (strcmp(datebuff, todaystr) == 0) {
227 snprintf(datebuff, DATEBUFFLEN, " today");
228 } else if (strcmp(datebuff, yesterdaystr) == 0) {
229 snprintf(datebuff, DATEBUFFLEN, "yesterday");
230 }
231 if (strlen(datebuff) <= 8) {
232 printf("%*s %s", getpadding(9, datebuff), datebuff, getvalue(datalist_i->rx, 11, RT_Normal));
233 } else {
234 printf("%-*s %s", getpadding(11, datebuff), datebuff, getvalue(datalist_i->rx, 11, RT_Normal));
235 }
236 printf("%s%s", fieldseparator, getvalue(datalist_i->tx, 11, RT_Normal));
237 printf("%s%s", fieldseparator, getvalue(datalist_i->rx + datalist_i->tx, 11, RT_Normal));
238 if (cfg.ostyle >= 2) {
239 if (datalist_i->next == NULL && issametimeslot(LT_Day, datalist_i->timestamp, interface->updated)) {
240 d = localtime(&interface->updated);
241 if (datalist_i->rx == 0 || datalist_i->tx == 0 || (d->tm_hour * 60 + d->tm_min) == 0) {
242 e_rx = e_tx = 0;
243 } else {
244 e_rx = (uint64_t)((double)datalist_i->rx / (double)(d->tm_hour * 60 + d->tm_min)) * 1440;
245 e_tx = (uint64_t)((double)datalist_i->tx / (double)(d->tm_hour * 60 + d->tm_min)) * 1440;
246 }
247 if (shortmode && cfg.ostyle != 0) {
248 printf("%s%s", fieldseparator, getvalue(e_rx + e_tx, 11, RT_Estimate));
249 } else if (!shortmode) {
250 printf("%s%s", fieldseparator, gettrafficrate(datalist_i->rx + datalist_i->tx, d->tm_sec + (d->tm_min * 60) + (d->tm_hour * 3600), 14));
251 }
252 } else if (!shortmode) {
253 printf(" | %s", gettrafficrate(datalist_i->rx + datalist_i->tx, 86400, 14));
254 }
255 }
256 printf("\n");
257 datalist_i = datalist_i->next;
258 }
259
260 if (!shortmode) {
261 if (!datalist) {
262 indent(5 + 27);
263 printf("no data available\n");
264 }
265 indent(5);
266 if (cfg.ostyle >= 2) {
267 printf("------------------------+-------------+-------------+---------------\n");
268 } else {
269 printf("------------------------+-------------+------------\n");
270 }
271 indent(5);
272 printf("estimated %s", getvalue(e_rx, 11, RT_Estimate));
273 printf(" | %s", getvalue(e_tx, 11, RT_Estimate));
274 printf(" | %s", getvalue(e_rx + e_tx, 11, RT_Estimate));
275 if (cfg.ostyle >= 2) {
276 printf(" |\n");
277 } else {
278 printf("\n");
279 }
280 } else {
281 printf("\n");
282 }
283
284 dbdatalistfree(&datalist);
286}
287
288void showlist(const interfaceinfo *interface, const char *listname, const char *databegin, const char *dataend)
289{
290 int32_t limit;
291 ListType listtype = LT_None;
292 int offset = 0, i = 1;
293 int estimatevisible = 0;
294 struct tm *d;
295 time_t current;
296 char datebuff[DATEBUFFLEN], daybuff[DATEBUFFLEN];
297 char titlename[16], colname[8], stampformat[64];
298 uint64_t e_rx = 0, e_tx = 0, e_secs = 0;
299 dbdatalist *datalist = NULL, *datalist_i = NULL;
300 dbdatalistinfo datainfo;
301
303
304 if (strcmp(listname, "day") == 0) {
305 listtype = LT_Day;
306 strncpy_nt(colname, listname, 8);
307 snprintf(titlename, 16, "daily");
308 strncpy_nt(stampformat, cfg.dformat, 64);
309 limit = cfg.listdays;
310 } else if (strcmp(listname, "month") == 0) {
311 listtype = LT_Month;
312 strncpy_nt(colname, listname, 8);
313 snprintf(titlename, 16, "monthly");
314 strncpy_nt(stampformat, cfg.mformat, 64);
315 limit = cfg.listmonths;
316 } else if (strcmp(listname, "year") == 0) {
317 listtype = LT_Year;
318 strncpy_nt(colname, listname, 8);
319 snprintf(titlename, 16, "yearly");
320 strncpy_nt(stampformat, "%Y", 64);
321 limit = cfg.listyears;
322 } else if (strcmp(listname, "top") == 0) {
323 listtype = LT_Top;
324 snprintf(colname, 8, "day");
325 snprintf(titlename, 16, "top days");
326 strncpy_nt(stampformat, cfg.tformat, 64);
327 limit = cfg.listtop;
328 offset = 6;
329 } else if (strcmp(listname, "hour") == 0) {
330 listtype = LT_Hour;
331 strncpy_nt(colname, listname, 8);
332 snprintf(titlename, 16, "hourly");
333 strncpy_nt(stampformat, "%H:%M", 64);
334 limit = cfg.listhours;
335 } else if (strcmp(listname, "fiveminute") == 0) {
336 listtype = LT_5min;
337 strncpy_nt(colname, "time", 8);
338 snprintf(titlename, 16, "5 minute");
339 strncpy_nt(stampformat, "%H:%M", 64);
340 limit = cfg.listfivemins;
341 } else {
342 return;
343 }
344
345 if (limit < 0) {
346 limit = 0;
347 }
348
349 daybuff[0] = '\0';
350
351 if (!db_getdata_range(&datalist, &datainfo, interface->name, listname, (uint32_t)limit, databegin, dataend)) {
352 printf("Error: Failed to fetch %s data.\n", titlename);
353 return;
354 }
355
356 if (!datalist) {
357 printf("No %s data available", titlename);
358 if (strlen(databegin) || strlen(dataend)) {
359 printf(" for given date range");
360 }
361 printf(".\n");
362 return;
363 }
364
365 datalist_i = datalist;
366
367 if (strlen(dataend) == 0 && datainfo.count > 0 && (listtype == LT_Day || listtype == LT_Month || listtype == LT_Year)) {
368 estimatevisible = 1;
369 getestimates(&e_rx, &e_tx, listtype, interface->updated, &datalist);
370 if (cfg.estimatebarvisible && e_rx + e_tx > datainfo.max) {
371 datainfo.max = e_rx + e_tx;
372 }
373 }
374
375 if (listtype == LT_Top) {
376 if (limit > 0 && datainfo.count < (uint32_t)limit) {
377 limit = (int32_t)datainfo.count;
378 }
379 if (limit <= 0 || datainfo.count > 999) {
380 snprintf(titlename, 16, "top");
381 } else {
382 snprintf(titlename, 16, "top %d", limit);
383 }
384 current = time(NULL);
385 d = localtime(&current);
386 strftime(daybuff, DATEBUFFLEN, stampformat, d);
387 }
388
389 printf("\n");
390 if (strcmp(interface->name, interface->alias) == 0 || strlen(interface->alias) == 0) {
391 printf(" %s", interface->name);
392 } else {
393 printf(" %s (%s)", interface->alias, interface->name);
394 }
395 if (interface->active == 0) {
396 printf(" [disabled]");
397 }
398 printf(" / %s", titlename);
399
400 if (listtype == LT_Top && (strlen(databegin))) {
401 printf(" (%s -", databegin);
402 if (strlen(dataend)) {
403 printf(" %s)", dataend);
404 } else {
405 printf(">)");
406 }
407 }
408 printf("\n\n");
409
410 if (cfg.ostyle == 3) {
411 if (listtype == LT_Top) {
412 printf(" # %8s ", colname);
413 } else {
414 indent(5);
415 printf("%8s", colname);
416 }
417 printf(" rx | tx | total | avg. rate\n");
418 if (listtype == LT_Top) {
419 printf(" -----");
420 } else {
421 indent(5);
422 }
423 printf("------------------------+-------------+-------------+---------------\n");
424 } else {
425 if (listtype == LT_Top) {
426 printf(" # %8s ", colname);
427 } else {
428 printf(" %8s", colname);
429 }
430 printf(" rx | tx | total\n");
431 if (listtype == LT_Top) {
432 printf("------");
433 }
434 printf("-------------------------+-------------+------------");
435 if (cfg.ostyle != 0) {
436 printf("---------------------");
437 if (listtype != LT_Top) {
438 printf("------");
439 }
440 }
441 printf("\n");
442 }
443
444 while (datalist_i != NULL) {
445 d = localtime(&datalist_i->timestamp);
446
447 if (listtype == LT_Hour || listtype == LT_5min) {
448 strftime(datebuff, DATEBUFFLEN, cfg.dformat, d);
449 if (strcmp(daybuff, datebuff) != 0) {
450 if (cfg.ostyle == 3) {
451 indent(4);
452 }
453 printf(" %s\n", datebuff);
454 strcpy(daybuff, datebuff);
455 }
456 }
457
458 strftime(datebuff, DATEBUFFLEN, stampformat, d);
459 if (cfg.ostyle == 3) {
460 indent(1);
461 if (listtype != LT_Top) {
462 indent(3);
463 }
464 }
465
466 if (listtype == LT_Top) {
467 if (strcmp(daybuff, datebuff) == 0) {
468 printf("> %2d ", i);
469 } else {
470 printf(" %2d ", i);
471 }
472 }
473
474 if (strlen(datebuff) <= 9 && listtype != LT_Top) {
475 printf(" %*s %s", getpadding(9, datebuff), datebuff, getvalue(datalist_i->rx, 11, RT_Normal));
476 } else {
477 printf(" %-*s %s", getpadding(11, datebuff), datebuff, getvalue(datalist_i->rx, 11, RT_Normal));
478 }
479 printf(" | %s", getvalue(datalist_i->tx, 11, RT_Normal));
480 printf(" | %s", getvalue(datalist_i->rx + datalist_i->tx, 11, RT_Normal));
481 if (cfg.ostyle == 3) {
482 if (datalist_i->next == NULL && issametimeslot(listtype, datalist_i->timestamp, interface->updated)) {
483 e_secs = getperiodseconds(listtype, datalist_i->timestamp, interface->updated, 1);
484 } else {
485 e_secs = getperiodseconds(listtype, datalist_i->timestamp, interface->updated, 0);
486 }
487 printf(" | %s", gettrafficrate(datalist_i->rx + datalist_i->tx, (time_t)e_secs, 14));
488 } else if (cfg.ostyle != 0) {
489 showbar(datalist_i->rx, datalist_i->tx, datainfo.max, 24 - offset);
490 }
491 printf("\n");
492 if (datalist_i->next == NULL) {
493 break;
494 }
495 datalist_i = datalist_i->next;
496 i++;
497 }
498 if (datainfo.count == 0) {
499 if (cfg.ostyle != 3) {
500 printf(" no data available\n");
501 } else {
502 printf(" no data available\n");
503 }
504 }
505 if (cfg.ostyle == 3) {
506 if (listtype == LT_Top) {
507 printf(" -----");
508 } else {
509 indent(5);
510 }
511 printf("------------------------+-------------+-------------+---------------\n");
512 } else {
513 if (listtype == LT_Top) {
514 printf("------");
515 }
516 printf("-------------------------+-------------+------------");
517 if (cfg.ostyle != 0) {
518 printf("---------------------");
519 if (listtype != LT_Top) {
520 printf("------");
521 }
522 }
523 printf("\n");
524 }
525
526 /* estimate or sum visible */
527 if ( (estimatevisible) ||
528 (strlen(dataend) > 0 && datainfo.count > 1 && listtype != LT_Top) ) {
529
530 if (cfg.ostyle == 3) {
531 printf(" ");
532 }
533 if (strlen(dataend) == 0) {
534 printf(" estimated %s", getvalue(e_rx, 11, RT_Estimate));
535 printf(" | %s", getvalue(e_tx, 11, RT_Estimate));
536 printf(" | %s", getvalue(e_rx + e_tx, 11, RT_Estimate));
537 } else {
538 if (datainfo.count < 100) {
539 snprintf(datebuff, DATEBUFFLEN, "sum of %" PRIu32 "", datainfo.count);
540 } else {
541 snprintf(datebuff, DATEBUFFLEN, "sum");
542 }
543 printf(" %9s %s", datebuff, getvalue(datainfo.sumrx, 11, RT_Normal));
544 printf(" | %s", getvalue(datainfo.sumtx, 11, RT_Normal));
545 printf(" | %s", getvalue(datainfo.sumrx + datainfo.sumtx, 11, RT_Normal));
546 }
547 if (cfg.ostyle == 3) {
548 printf(" |");
549 } else if (cfg.ostyle != 0 && estimatevisible && cfg.estimatebarvisible) {
550 showbar(e_rx, e_tx, datainfo.max, 24 - offset);
551 }
552 printf("\n");
553 }
554
555 dbdatalistfree(&datalist);
557}
558
559void showoneline(const interfaceinfo *interface)
560{
561 struct tm *d;
562 char daytemp[DATEBUFFLEN];
563 uint64_t div;
564 dbdatalist *datalist = NULL;
565 dbdatalistinfo datainfo;
566
568
569 /* version string */
570 printf("%d;", ONELINEVERSION);
571
572 /* interface name */
573 if (strcmp(interface->name, interface->alias) == 0 || strlen(interface->alias) == 0) {
574 printf("%s", interface->name);
575 } else {
576 printf("%s (%s)", interface->alias, interface->name);
577 }
578 if (interface->active == 0) {
579 printf(" [disabled]");
580 }
581 printf(";");
582
583 if (!db_getdata(&datalist, &datainfo, interface->name, "day", 1)) {
584 printf("\nError: Failed to fetch day data.\n");
585 return;
586 }
587
588 if (datainfo.count > 0) {
589 d = localtime(&datalist->timestamp);
590 strftime(daytemp, DATEBUFFLEN, cfg.dformat, d);
591 printf("%s;", daytemp);
592
593 d = localtime(&interface->updated);
594
595 /* daily */
596 if (cfg.ostyle == 4) {
597 printf("%" PRIu64 ";", datalist->rx);
598 printf("%" PRIu64 ";", datalist->tx);
599 printf("%" PRIu64 ";", datalist->rx + datalist->tx);
600 div = (uint64_t)(d->tm_sec + (d->tm_min * 60) + (d->tm_hour * 3600));
601 if (!div) {
602 div = 1;
603 }
604 printf("%" PRIu64 ";", (datalist->rx + datalist->tx) / div);
605 } else {
606 printf("%s;", getvalue(datalist->rx, 1, RT_Normal));
607 printf("%s;", getvalue(datalist->tx, 1, RT_Normal));
608 printf("%s;", getvalue(datalist->rx + datalist->tx, 1, RT_Normal));
609 printf("%s;", gettrafficrate(datalist->rx + datalist->tx, (time_t)(d->tm_sec + (d->tm_min * 60) + (d->tm_hour * 3600)), 1));
610 }
611 } else {
612 printf(";;;;;");
613 }
614 dbdatalistfree(&datalist);
615
616 if (!db_getdata(&datalist, &datainfo, interface->name, "month", 1)) {
617 printf("\nError: Failed to fetch month data.\n");
618 return;
619 }
620
621 if (datainfo.count > 0) {
622 d = localtime(&datalist->timestamp);
623 strftime(daytemp, DATEBUFFLEN, cfg.mformat, d);
624 printf("%s;", daytemp);
625
626 /* monthly */
627 if (cfg.ostyle == 4) {
628 printf("%" PRIu64 ";", datalist->rx);
629 printf("%" PRIu64 ";", datalist->tx);
630 printf("%" PRIu64 ";", datalist->rx + datalist->tx);
631 div = (uint64_t)(mosecs(datalist->timestamp, interface->updated));
632 if (!div) {
633 div = 1;
634 }
635 printf("%" PRIu64 ";", (datalist->rx + datalist->tx) / div);
636 } else {
637 printf("%s;", getvalue(datalist->rx, 1, RT_Normal));
638 printf("%s;", getvalue(datalist->tx, 1, RT_Normal));
639 printf("%s;", getvalue(datalist->rx + datalist->tx, 1, RT_Normal));
640 printf("%s;", gettrafficrate(datalist->rx + datalist->tx, mosecs(datalist->timestamp, interface->updated), 1));
641 }
642 } else {
643 printf(";;;;;");
644 }
645 dbdatalistfree(&datalist);
646
647 /* all time total */
648 if (cfg.ostyle == 4) {
649 printf("%" PRIu64 ";", interface->rxtotal);
650 printf("%" PRIu64 ";", interface->txtotal);
651 printf("%" PRIu64 "\n", interface->rxtotal + interface->txtotal);
652 } else {
653 printf("%s;", getvalue(interface->rxtotal, 1, RT_Normal));
654 printf("%s;", getvalue(interface->txtotal, 1, RT_Normal));
655 printf("%s\n", getvalue(interface->rxtotal + interface->txtotal, 1, RT_Normal));
656 }
658}
659
660void showhours(const interfaceinfo *interface)
661{
662 int i, s = 0, hour, minute, declen = cfg.hourlydecimals, div = 1;
663 unsigned int j, k, tmax = 0, dots = 0;
664 uint64_t max = 1;
665 char matrix[HGLINES][81]; /* width is one over 80 so that snprintf can write the end char */
666 char unit[4];
667 struct tm *d;
668 dbdatalist *datalist = NULL, *datalist_i = NULL;
669 dbdatalistinfo datainfo;
670 HOURDATA hourdata[24];
671
673
674 for (i = 0; i < 24; i++) {
675 hourdata[i].rx = hourdata[i].tx = 0;
676 hourdata[i].date = 0;
677 }
678
679 if (!db_getdata(&datalist, &datainfo, interface->name, "hour", 24)) {
680 printf("Error: Failed to fetch hour data.\n");
681 return;
682 }
683
684 if (datainfo.count == 0) {
685 return;
686 }
687
688 datalist_i = datalist;
689
690 while (datalist_i != NULL) {
691 d = localtime(&datalist_i->timestamp);
692 if (hourdata[d->tm_hour].date != 0 || interface->updated - datalist_i->timestamp > 86400) {
693 datalist_i = datalist_i->next;
694 continue;
695 }
696 hourdata[d->tm_hour].rx = datalist_i->rx;
697 hourdata[d->tm_hour].tx = datalist_i->tx;
698 hourdata[d->tm_hour].date = datalist_i->timestamp;
699 datalist_i = datalist_i->next;
700 }
701 dbdatalistfree(&datalist);
702
703 /* tmax = time max = current hour */
704 /* max = transfer max */
705
706 d = localtime(&interface->updated);
707 hour = d->tm_hour;
708 minute = d->tm_min;
709
710 for (i = 0; i < 24; i++) {
711 if (hourdata[i].date >= hourdata[tmax].date) {
712 tmax = (unsigned int)i;
713 }
714 if (hourdata[i].rx >= max) {
715 max = hourdata[i].rx;
716 }
717 if (hourdata[i].tx >= max) {
718 max = hourdata[i].tx;
719 }
720 }
721
722 /* mr. proper */
723 for (i = 0; i < HGLINES; i++) {
724 for (j = 0; j < 81; j++) {
725 matrix[i][j] = ' ';
726 }
727 }
728
729 /* unit selection */
730 while ((double)max / (pow(1024, div)) >= 100 && div < UNITPREFIXCOUNT) {
731 div++;
732 }
733 strncpy_nt(unit, getunitprefix(div), 4);
734 div = (int)(pow(1024, div - 1));
735 if (div == 1) {
736 declen = 0;
737 }
738
739 /* structure */
740 snprintf(matrix[11], 81, " -+--------------------------------------------------------------------------->");
741 for (i = 0; i < 3; i++) {
742 snprintf(matrix[14] + (i * 28), 14, " h %*srx (%s)", 1 + cfg.unitmode, " ", unit);
743 snprintf(matrix[14] + (i * 28) + 15 + cfg.unitmode, 10, "tx (%s)", unit);
744 }
745
746 for (i = 10; i > 1; i--)
747 matrix[i][2] = '|';
748
749 matrix[1][2] = '^';
750 matrix[12][2] = '|';
751
752 /* title */
753 if (strcmp(interface->name, interface->alias) == 0 || strlen(interface->alias) == 0) {
754 i = snprintf(matrix[0], 81, " %s", interface->name);
755 } else {
756 i = snprintf(matrix[0], 81, " %s (%s)", interface->alias, interface->name);
757 }
758 if (interface->active == 0) {
759 snprintf(matrix[0] + i + 1, 81, " [disabled]");
760 }
761
762 /* time to the corner */
763 snprintf(matrix[0] + 74, 7, "%02d:%02d", hour, minute);
764
765 /* numbers under x-axis and graphics :) */
766 k = 5;
767 for (i = 23; i >= 0; i--) {
768 s = (int)tmax - i;
769 if (s < 0)
770 s += 24;
771
772 snprintf(matrix[12] + k, 81 - k, "%02d ", s);
773
774 dots = (unsigned int)(10 * ((double)hourdata[s].rx / (double)max));
775 for (j = 0; j < dots; j++)
776 matrix[10 - j][k] = cfg.rxhourchar[0];
777
778 dots = (unsigned int)(10 * ((double)hourdata[s].tx / (double)max));
779 for (j = 0; j < dots; j++)
780 matrix[10 - j][k + 1] = cfg.txhourchar[0];
781
782 k = k + 3;
783 }
784
785 /* section separators */
786 if (cfg.hourlystyle == 1) {
787 matrix[14][26] = '|';
788 matrix[14][54] = '|';
789 } else if (cfg.hourlystyle == 2) {
790 matrix[14][25] = ']';
791 matrix[14][26] = '[';
792 matrix[14][53] = ']';
793 matrix[14][54] = '[';
794 } else if (cfg.hourlystyle == 3) {
795 matrix[14][26] = '[';
796 matrix[14][53] = ']';
797 }
798
799 /* clean \0 */
800 for (i = 0; i < HGLINES; i++) {
801 for (j = 0; j < 80; j++) {
802 if (matrix[i][j] == '\0') {
803 matrix[i][j] = ' ';
804 }
805 }
806 }
807
808 /* show matrix */
809 for (i = 0; i < HGLINES; i++) {
810 for (j = 0; j < 80; j++) {
811 printf("%c", matrix[i][j]);
812 }
813 printf("\n");
814 }
815
816 /* hours and traffic */
817 for (i = 0; i <= 7; i++) {
818 s = (int)tmax + i + 1;
819 for (j = 0; j < 3; j++) {
820 printf("%02d %" DECCONV "10.*f %" DECCONV "10.*f", ((unsigned int)s + (j * 8)) % 24,
821 declen, (double)hourdata[((unsigned int)s + (j * 8)) % 24].rx / (double)div,
822 declen, (double)hourdata[((unsigned int)s + (j * 8)) % 24].tx / (double)div);
823
824 if (j < 2) {
825 if (cfg.hourlystyle == 1) {
826 printf(" | ");
827 } else if (cfg.hourlystyle == 2) {
828 printf(" ][ ");
829 } else if (cfg.hourlystyle == 3) {
830 if (j == 0) {
831 printf(" [ ");
832 } else {
833 printf(" ] ");
834 }
835 } else {
836 printf(" ");
837 }
838 }
839 }
840 printf("\n");
841 }
842
844}
845
846int showbar(const uint64_t rx, const uint64_t tx, const uint64_t max, const int len)
847{
848 int i, l, width = len;
849
850 if ((rx + tx) < max) {
851 width = (int)(((double)(rx + tx) / (double)max) * len);
852 } else if ((rx + tx) > max || max == 0) {
853 return 0;
854 }
855
856 if (width <= 0) {
857 return 0;
858 }
859
860 printf(" ");
861
862 if (tx > rx) {
863 l = (int)lrint(((double)rx / (double)(rx + tx) * width));
864
865 for (i = 0; i < l; i++) {
866 printf("%c", cfg.rxchar[0]);
867 }
868 for (i = 0; i < (width - l); i++) {
869 printf("%c", cfg.txchar[0]);
870 }
871 } else {
872 l = (int)lrint(((double)tx / (double)(rx + tx) * width));
873
874 for (i = 0; i < (width - l); i++) {
875 printf("%c", cfg.rxchar[0]);
876 }
877 for (i = 0; i < l; i++) {
878 printf("%c", cfg.txchar[0]);
879 }
880 }
881 return width;
882}
883
884void indent(int i)
885{
886 if ((cfg.ostyle > 0) && (i > 0)) {
887 printf("%*s", i, " ");
888 }
889}
890
891int showalert(const char *interface, const AlertOutput output, const AlertExit exit, const AlertType type, const AlertCondition condition, const uint64_t limit)
892{
893 interfaceinfo ifaceinfo;
894 int i, l, ret = 0, limitexceeded = 0, estimateexceeded = 0;
895 short ongoing = 1;
896 double percentage = 0.0;
897 char tablename[6], typeoutput[8], conditionname[16];
898 char datebuff[DATEBUFFLEN];
899 ListType listtype = LT_None;
900 uint64_t bytes = 0, e_rx = 0, e_tx = 0, e_bytes = 0, periodseconds = 0;
901 dbdatalist *datalist = NULL;
902 dbdatalistinfo datainfo;
903
905
906 if (!db_getinterfaceinfo(interface, &ifaceinfo)) {
907 return 1;
908 }
909
910 switch (type) {
911 case AT_None:
912 return 0;
913 case AT_Hour:
914 listtype = LT_Hour;
915 snprintf(tablename, 6, "hour");
916 snprintf(typeoutput, 8, "hourly");
917 break;
918 case AT_Day:
919 listtype = LT_Day;
920 snprintf(tablename, 6, "day");
921 snprintf(typeoutput, 8, "daily");
922 break;
923 case AT_Month:
924 listtype = LT_Month;
925 snprintf(tablename, 6, "month");
926 snprintf(typeoutput, 8, "monthly");
927 break;
928 case AT_Year:
929 listtype = LT_Year;
930 snprintf(tablename, 6, "year");
931 snprintf(typeoutput, 8, "yearly");
932 break;
933 }
934
935 if (!db_getdata(&datalist, &datainfo, interface, tablename, 1)) {
936 printf("Error: Failed to fetch %s data for interface %s.\n", tablename, interface);
937 return 1;
938 }
939
940 if (!datalist) {
941 printf("Error: No %s data available for interface %s.\n", tablename, interface);
942 return 1;
943 }
944
945 switch (condition) {
946 case AC_None:
947 break;
948 case AC_RX:
949 bytes = datalist->rx;
950 snprintf(conditionname, 16, "rx");
951 getestimates(&e_rx, &e_tx, listtype, ifaceinfo.updated, &datalist);
952 e_bytes = e_rx;
953 break;
954 case AC_TX:
955 bytes = datalist->tx;
956 snprintf(conditionname, 16, "tx");
957 getestimates(&e_rx, &e_tx, listtype, ifaceinfo.updated, &datalist);
958 e_bytes = e_tx;
959 break;
960 case AC_Total:
961 bytes = datalist->rx + datalist->tx;
962 snprintf(conditionname, 16, "total");
963 getestimates(&e_rx, &e_tx, listtype, ifaceinfo.updated, &datalist);
964 e_bytes = e_rx + e_tx;
965 break;
966 case AC_RX_Estimate:
967 ongoing = 0;
968 getestimates(&e_rx, &e_tx, listtype, ifaceinfo.updated, &datalist);
969 bytes = e_rx;
970 snprintf(conditionname, 16, "rx estimate");
971 break;
972 case AC_TX_Estimate:
973 ongoing = 0;
974 getestimates(&e_rx, &e_tx, listtype, ifaceinfo.updated, &datalist);
975 bytes = e_tx;
976 snprintf(conditionname, 16, "tx estimate");
977 break;
979 ongoing = 0;
980 getestimates(&e_rx, &e_tx, listtype, ifaceinfo.updated, &datalist);
981 bytes = e_rx + e_tx;
982 snprintf(conditionname, 16, "total estimate");
983 break;
984 }
985
986 if (bytes > limit) {
987 limitexceeded = 1;
988 }
989
990 if (ongoing == 1 && e_bytes > limit) {
991 estimateexceeded = 1;
992 }
993
994 if (limitexceeded && exit == AE_Exit_1_On_Limit) {
995 ret = 1;
996 } else if (estimateexceeded && exit == AE_Exit_1_On_Estimate) {
997 ret = 1;
998 }
999
1000 if (output != AO_No_Output) {
1001 if (output == AO_Always_Output || (output == AO_Output_On_Estimate && estimateexceeded) || ((output == AO_Output_On_Limit || output == AO_Output_On_Estimate) && limitexceeded)) {
1002 if (strlen(ifaceinfo.alias)) {
1003 printf("\n %s (%s)", ifaceinfo.alias, ifaceinfo.name);
1004 } else {
1005 printf("\n %s", interface);
1006 }
1007 if (ifaceinfo.updated) {
1008 strftime(datebuff, DATEBUFFLEN, DATETIMEFORMAT, localtime(&ifaceinfo.updated));
1009 printf(" at %s", datebuff);
1010 }
1011 if (datalist->timestamp) {
1012 printf(" for %s ", tablename);
1013 switch (type) {
1014 case AT_None:
1015 break;
1016 case AT_Hour:
1017 strftime(datebuff, DATEBUFFLEN, "%H", localtime(&datalist->timestamp));
1018 printf("%s of ", datebuff);
1019 strftime(datebuff, DATEBUFFLEN, cfg.dformat, localtime(&datalist->timestamp));
1020 printf("%s", datebuff);
1021 break;
1022 case AT_Day:
1023 strftime(datebuff, DATEBUFFLEN, cfg.dformat, localtime(&datalist->timestamp));
1024 printf("%s", datebuff);
1025 break;
1026 case AT_Month:
1027 strftime(datebuff, DATEBUFFLEN, cfg.mformat, localtime(&datalist->timestamp));
1028 printf("%s", datebuff);
1029 break;
1030 case AT_Year:
1031 strftime(datebuff, DATEBUFFLEN, "%Y", localtime(&datalist->timestamp));
1032 printf("%s", datebuff);
1033 break;
1034 }
1035 }
1036 printf("\n\n");
1037 }
1038
1039 if ((output == AO_Always_Output || output == AO_Output_On_Limit || output == AO_Output_On_Estimate) && limitexceeded) {
1040 printf(" Alert limit exceeded!\n\n");
1041 } else if (output == AO_Always_Output || (output == AO_Output_On_Estimate && estimateexceeded)) {
1042 if (estimateexceeded) {
1043 printf(" Warning: Limit will be exceeded at current rate\n\n");
1044 }
1045 printf(" [");
1046 l = (int)lrint((double)(bytes) / (double)limit * ALERTUSAGELEN);
1047 if (l > ALERTUSAGELEN) {
1048 l = ALERTUSAGELEN;
1049 }
1050 for (i = 0; i < l; i++) {
1051 printf("=");
1052 }
1053 if (ongoing) {
1054 if (!estimateexceeded) {
1055 l = (int)lrint((double)(e_bytes) / (double)limit * ALERTUSAGELEN);
1056 for (; i < l; i++) {
1057 printf("-");
1058 }
1059 } else {
1060 for (; i < ALERTUSAGELEN; i++) {
1061 printf("-");
1062 }
1063 }
1064 }
1065 for (; i < ALERTUSAGELEN; i++) {
1066 printf(".");
1067 }
1068 printf("]\n\n");
1069 }
1070
1071 if (output == AO_Always_Output || (output == AO_Output_On_Estimate && estimateexceeded) || ((output == AO_Output_On_Limit || output == AO_Output_On_Estimate) && limitexceeded)) {
1072 printf(" %8s |", typeoutput);
1073 if (ongoing) {
1074 printf(" %9s |", conditionname);
1075 } else {
1076 printf(" %14s |", conditionname);
1077 }
1078 percentage = (double)(bytes) / (double)limit * 100.0;
1079 printf(" percentage | avg. rate\n");
1080 printf(" ----------+------------------+----------------+--------------\n");
1081 printf(" used | %16s |", getvalue(bytes, 16, RT_Normal));
1082 periodseconds = getperiodseconds(listtype, datalist->timestamp, ifaceinfo.updated, ongoing);
1083 if (ongoing && periodseconds == 0) {
1084 periodseconds = getperiodseconds(listtype, datalist->timestamp, ifaceinfo.updated, 0);
1085 }
1086 if (percentage <= 100000.0) {
1087 printf(" %13.1f%% | %13s\n", percentage, gettrafficrate(bytes, (time_t)periodseconds, 13));
1088 } else {
1089 printf(" %14s | %13s\n", ">100000%", gettrafficrate(bytes, (time_t)periodseconds, 13));
1090 }
1091 printf(" limit | %16s |", getvalue(limit, 16, RT_Normal));
1092 printf(" | %13s\n", gettrafficrate(limit, (time_t)getperiodseconds(listtype, datalist->timestamp, ifaceinfo.updated, 0), 13));
1093
1094 if (limitexceeded) {
1095 printf(" excess | %16s | |\n", getvalue(bytes - limit, 16, RT_Normal));
1096 printf(" ----------+------------------+----------------+--------------\n");
1097 } else {
1098 printf(" remaining | %16s | %13.1f%% |\n", getvalue(limit - bytes, 16, RT_Normal), 100.0 - percentage);
1099 printf(" ----------+------------------+----------------+--------------\n");
1100 }
1101 if (ongoing && e_bytes > 0) {
1102 printf(" estimated | %16s |", getvalue(e_bytes, 16, RT_Normal));
1103 percentage = (double)(e_bytes) / (double)limit * 100.0;
1104 if (percentage <= 100000.0) {
1105 printf(" %13.1f%%", percentage);
1106 } else {
1107 printf(" %14s", ">100000%");
1108 }
1109 if (e_bytes > limit) {
1110 printf(", +%s\n", getvalue(e_bytes - limit, 0, RT_Normal));
1111 } else {
1112 /* rate for estimated is always to same as for used so "bytes" intentionally used here instead of "e_bytes" */
1113 printf(" | %13s\n", gettrafficrate(bytes, (time_t)periodseconds, 13));
1114 }
1115 }
1116 }
1117 }
1118
1119 dbdatalistfree(&datalist);
1120
1122
1123 return ret;
1124}
time_t mosecs(time_t month, time_t updated)
Definition: common.c:209
int dmonth(const int month)
Definition: common.c:177
void timeused_debug(const char *func, const int reset)
Definition: common.c:322
CFG cfg
Definition: common.c:4
char * strncpy_nt(char *dest, const char *src, size_t n)
Definition: common.c:253
#define ONELINEVERSION
Definition: common.h:211
#define __func__
Definition: common.h:51
#define DATETIMEFORMAT
Definition: common.h:89
#define DECCONV
Definition: common.h:41
void showoneline(const interfaceinfo *interface)
Definition: dbshow.c:559
void showlist(const interfaceinfo *interface, const char *listname, const char *databegin, const char *dataend)
Definition: dbshow.c:288
void showsummary(const interfaceinfo *interface, const int shortmode)
Definition: dbshow.c:60
int showalert(const char *interface, const AlertOutput output, const AlertExit exit, const AlertType type, const AlertCondition condition, const uint64_t limit)
Definition: dbshow.c:891
int showbar(const uint64_t rx, const uint64_t tx, const uint64_t max, const int len)
Definition: dbshow.c:846
void showhours(const interfaceinfo *interface)
Definition: dbshow.c:660
void indent(int i)
Definition: dbshow.c:884
void showdb(const char *interface, int qmode, const char *databegin, const char *dataend)
Definition: dbshow.c:6
AlertOutput
Definition: dbshow.h:13
@ AO_Always_Output
Definition: dbshow.h:15
@ AO_Output_On_Estimate
Definition: dbshow.h:16
@ AO_Output_On_Limit
Definition: dbshow.h:17
@ AO_No_Output
Definition: dbshow.h:14
#define DATEBUFFLEN
Definition: dbshow.h:4
#define HGLINES
Definition: dbshow.h:5
AlertExit
Definition: dbshow.h:20
@ AE_Exit_1_On_Estimate
Definition: dbshow.h:23
@ AE_Exit_1_On_Limit
Definition: dbshow.h:24
#define ALERTUSAGELEN
Definition: dbshow.h:6
AlertType
Definition: dbshow.h:27
@ AT_None
Definition: dbshow.h:28
@ AT_Hour
Definition: dbshow.h:29
@ AT_Year
Definition: dbshow.h:32
@ AT_Day
Definition: dbshow.h:30
@ AT_Month
Definition: dbshow.h:31
AlertCondition
Definition: dbshow.h:35
@ AC_TX
Definition: dbshow.h:38
@ AC_None
Definition: dbshow.h:36
@ AC_RX
Definition: dbshow.h:37
@ AC_RX_Estimate
Definition: dbshow.h:40
@ AC_Total_Estimate
Definition: dbshow.h:42
@ AC_Total
Definition: dbshow.h:39
@ AC_TX_Estimate
Definition: dbshow.h:41
uint64_t db_getinterfacecountbyname(const char *iface)
Definition: dbsql.c:419
int db_getdata(dbdatalist **dbdata, dbdatalistinfo *listinfo, const char *iface, const char *table, const uint32_t resultlimit)
Definition: dbsql.c:1212
int db_getdata_range(dbdatalist **dbdata, dbdatalistinfo *listinfo, const char *iface, const char *table, const uint32_t resultlimit, const char *databegin, const char *dataend)
Definition: dbsql.c:1217
void dbdatalistfree(dbdatalist **dbdata)
Definition: dbsql.c:1393
int db_getinterfaceinfo(const char *iface, interfaceinfo *info)
Definition: dbsql.c:651
uint64_t getperiodseconds(const ListType listtype, const time_t entry, const time_t updated, const short isongoing)
Definition: misc.c:453
void getestimates(uint64_t *rx, uint64_t *tx, const ListType listtype, const time_t updated, dbdatalist **dbdata)
Definition: misc.c:493
int issametimeslot(const ListType listtype, const time_t entry, const time_t updated)
Definition: misc.c:403
char * getvalue(const uint64_t bytes, const int len, const RequestType type)
Definition: misc.c:148
const char * getunitprefix(const int index)
Definition: misc.c:222
int getpadding(const int len, const char *str)
Definition: misc.c:320
char * gettrafficrate(const uint64_t bytes, const time_t interval, const int len)
Definition: misc.c:203
#define UNITPREFIXCOUNT
Definition: misc.h:4
ListType
Definition: misc.h:14
@ LT_5min
Definition: misc.h:16
@ LT_Hour
Definition: misc.h:17
@ LT_Year
Definition: misc.h:20
@ LT_Day
Definition: misc.h:18
@ LT_None
Definition: misc.h:15
@ LT_Top
Definition: misc.h:21
@ LT_Month
Definition: misc.h:19
@ RT_Estimate
Definition: misc.h:10
@ RT_Normal
Definition: misc.h:9
int32_t listfivemins
Definition: common.h:324
int32_t listtop
Definition: common.h:324
char tformat[64]
Definition: common.h:307
char mformat[64]
Definition: common.h:307
char dformat[64]
Definition: common.h:307
int32_t listmonths
Definition: common.h:324
char rxhourchar[2]
Definition: common.h:311
int32_t hourlydecimals
Definition: common.h:316
char rxchar[2]
Definition: common.h:311
char txchar[2]
Definition: common.h:311
int32_t unitmode
Definition: common.h:314
int32_t ostyle
Definition: common.h:315
int32_t listdays
Definition: common.h:324
int32_t hourlystyle
Definition: common.h:316
int32_t listyears
Definition: common.h:324
char txhourchar[2]
Definition: common.h:311
int32_t estimatebarvisible
Definition: common.h:317
int32_t listhours
Definition: common.h:324
Definition: dbshow.h:8
uint64_t tx
Definition: dbshow.h:10
uint64_t rx
Definition: dbshow.h:10
time_t date
Definition: dbshow.h:9
time_t timestamp
Definition: dbsql.h:8
uint64_t rx
Definition: dbsql.h:10
uint64_t tx
Definition: dbsql.h:10
uint64_t sumrx
Definition: dbsql.h:20
uint64_t sumtx
Definition: dbsql.h:20
uint32_t count
Definition: dbsql.h:15
uint64_t max
Definition: dbsql.h:19
int active
Definition: dbsql.h:25
char alias[32]
Definition: dbsql.h:24
time_t created
Definition: dbsql.h:26
time_t updated
Definition: dbsql.h:26
uint64_t txtotal
Definition: dbsql.h:28
char name[32]
Definition: dbsql.h:24
uint64_t rxtotal
Definition: dbsql.h:28