"Fossies" - the Fresh Open Source Software Archive

Member "vnstat-2.9/src/vnstat_func.c" (23 Jan 2022, 41518 Bytes) of package /linux/misc/vnstat-2.9.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "vnstat_func.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.8_vs_2.9.

    1 #include "common.h"
    2 #include "ifinfo.h"
    3 #include "iflist.h"
    4 #include "traffic.h"
    5 #include "dbsql.h"
    6 #include "dbxml.h"
    7 #include "dbjson.h"
    8 #include "dbshow.h"
    9 #include "misc.h"
   10 #include "cfg.h"
   11 #include "cfgoutput.h"
   12 #include "vnstat_func.h"
   13 
   14 void initparams(PARAMS *p)
   15 {
   16     db = NULL;
   17     noexit = 0;        /* allow functions to exit in case of error */
   18     debug = 0;         /* debug disabled by default */
   19     disableprints = 0; /* let prints be visible */
   20 
   21     p->addiface = 0;
   22     p->query = 1;
   23     p->setalias = 0;
   24     p->dbifcount = 0;
   25     p->force = 0;
   26     p->traffic = 0;
   27     p->livetraffic = 0;
   28     p->defaultiface = 1;
   29     p->removeiface = 0;
   30     p->renameiface = 0;
   31     p->livemode = 0;
   32     p->limit = -1;
   33     p->ifacelist = NULL;
   34     p->interface[0] = '\0';
   35     p->alias[0] = '\0';
   36     p->newifname[0] = '\0';
   37     p->filename[0] = '\0';
   38     p->definterface[0] = '\0';
   39     p->cfgfile[0] = '\0';
   40     p->jsonmode = 'a';
   41     p->xmlmode = 'a';
   42     p->databegin[0] = '\0';
   43     p->dataend[0] = '\0';
   44 
   45     p->alert = 0;
   46     p->alertoutput = 0;
   47     p->alertexit = 0;
   48     p->alerttype = 0;
   49     p->alertcondition = 0;
   50     p->alertlimit = 0;
   51 }
   52 
   53 void showhelp(PARAMS *p)
   54 {
   55     printf("vnStat %s by Teemu Toivola <tst at iki dot fi>\n\n", getversion());
   56 
   57     printf("      -5,  --fiveminutes [limit]   show 5 minutes\n");
   58     printf("      -h,  --hours [limit]         show hours\n");
   59     printf("      -hg, --hoursgraph            show hours graph\n");
   60     printf("      -d,  --days [limit]          show days\n");
   61     printf("      -m,  --months [limit]        show months\n");
   62     printf("      -y,  --years [limit]         show years\n");
   63     printf("      -t,  --top [limit]           show top days\n\n");
   64 
   65     printf("      -b, --begin <date>           set list begin date\n");
   66     printf("      -e, --end <date>             set list end date\n\n");
   67 
   68     printf("      --oneline [mode]             show simple parsable format\n");
   69     printf("      --json [mode] [limit]        show database in json format\n");
   70     printf("      --xml [mode] [limit]         show database in xml format\n");
   71     printf("      --alert <output> <exit> <type> <condition> <limit> <unit>\n");
   72     printf("                                   alert if limit is exceeded\n\n");
   73 
   74     printf("      -tr, --traffic [time]        calculate traffic\n");
   75     printf("      -l,  --live [mode]           show transfer rate in real time\n");
   76     printf("      -i,  --iface <interface>     select interface");
   77     if (strlen(p->definterface)) {
   78         printf(" (default: %s)", p->definterface);
   79     }
   80     printf("\n\n");
   81 
   82     printf("Use \"--longhelp\" or \"man vnstat\" for complete list of options.\n");
   83 }
   84 
   85 void showlonghelp(PARAMS *p)
   86 {
   87     printf("vnStat %s by Teemu Toivola <tst at iki dot fi>\n\n", getversion());
   88 
   89     printf("Query:\n");
   90 
   91     printf("      -q,  --query                 query database\n");
   92     printf("      -s,  --short                 use short output\n");
   93     printf("      -5,  --fiveminutes [limit]   show 5 minutes\n");
   94     printf("      -h,  --hours [limit]         show hours\n");
   95     printf("      -hg, --hoursgraph            show hours graph\n");
   96     printf("      -d,  --days [limit]          show days\n");
   97     printf("      -m,  --months [limit]        show months\n");
   98     printf("      -y,  --years [limit]         show years\n");
   99     printf("      -t,  --top [limit]           show top days\n");
  100     printf("      -b,  --begin <date>          set list begin date\n");
  101     printf("      -e,  --end <date>            set list end date\n");
  102     printf("      --oneline [mode]             show simple parsable format\n");
  103     printf("      --json [mode] [limit]        show database in json format\n");
  104     printf("      --xml [mode] [limit]         show database in xml format\n");
  105     printf("      --alert <output> <exit> <type> <condition> <limit> <unit>\n");
  106     printf("                                   alert if limit is exceeded\n\n");
  107 
  108     printf("Modify:\n");
  109 
  110     printf("      --add                        add interface to database\n");
  111     printf("      --remove                     remove interface from database\n");
  112     printf("      --rename <name>              rename interface in database\n");
  113     printf("      --setalias <alias>           set alias for interface\n\n");
  114 
  115     printf("Misc:\n");
  116 
  117     printf("      -i,  --iface <interface>     select interface");
  118     if (strlen(p->definterface)) {
  119         printf(" (default: %s)", p->definterface);
  120     }
  121     printf("\n");
  122     printf("      -?,  --help                  show short help\n");
  123     printf("      -D,  --debug                 show some additional debug information\n");
  124     printf("      -v,  --version               show version\n");
  125     printf("      -tr, --traffic [time]        calculate traffic\n");
  126     printf("      -l,  --live [mode]           show transfer rate in real time\n");
  127     printf("      -ru, --rateunit [mode]       swap configured rate unit\n");
  128     printf("      --limit <limit>              set output entry limit\n");
  129     printf("      --style <mode>               select output style (0-4)\n");
  130     printf("      --iflist [mode]              show list of available interfaces\n");
  131     printf("      --dbiflist [mode]            show list of interfaces in database\n");
  132     printf("      --dbdir <directory>          select database directory\n");
  133     printf("      --locale <locale>            set locale\n");
  134     printf("      --config <config file>       select config file\n");
  135     printf("      --showconfig                 dump config file with current settings\n");
  136     printf("      --longhelp                   show this help\n\n");
  137 
  138     printf("See also \"man vnstat\" for longer descriptions of each option.\n");
  139 }
  140 
  141 void parseargs(PARAMS *p, const int argc, char **argv)
  142 {
  143     int currentarg;
  144 
  145     /* parse parameters, maybe not the best way but... */
  146     for (currentarg = 1; currentarg < argc; currentarg++) {
  147         if (debug)
  148             printf("arg %d: \"%s\"\n", currentarg, argv[currentarg]);
  149         if (strcmp(argv[currentarg], "--longhelp") == 0) {
  150             showlonghelp(p);
  151             exit(EXIT_SUCCESS);
  152         } else if ((strcmp(argv[currentarg], "-?") == 0) || (strcmp(argv[currentarg], "--help") == 0)) {
  153             showhelp(p);
  154             exit(EXIT_SUCCESS);
  155         } else if ((strcmp(argv[currentarg], "-i") == 0) || (strcmp(argv[currentarg], "--iface") == 0) || (strcmp(argv[currentarg], "--interface") == 0)) {
  156             if (currentarg + 1 < argc) {
  157                 if (strlen(argv[currentarg + 1]) > 31) {
  158                     printf("Error: Interface name is limited to 31 characters.\n");
  159                     exit(EXIT_FAILURE);
  160                 }
  161                 strncpy_nt(p->interface, argv[currentarg + 1], 32);
  162                 if (strlen(p->interface)) {
  163                     p->defaultiface = 0;
  164                 } else {
  165                     strncpy_nt(p->definterface, p->interface, 32);
  166                 }
  167                 if (debug)
  168                     printf("Used interface: \"%s\"\n", p->interface);
  169                 currentarg++;
  170             } else {
  171                 printf("Error: Interface for %s missing.\n", argv[currentarg]);
  172                 exit(EXIT_FAILURE);
  173             }
  174         } else if (strcmp(argv[currentarg], "--config") == 0) {
  175             /* config has already been parsed earlier so nothing to do here */
  176             currentarg++;
  177         } else if (strcmp(argv[currentarg], "--setalias") == 0 || strcmp(argv[currentarg], "--nick") == 0) {
  178             if (strcmp(argv[currentarg], "--nick") == 0) {
  179                 printf("Warning: --nick is deprecated and will be removed in a future release. Use --setalias instead.\n");
  180             }
  181             if (currentarg + 1 < argc) {
  182                 strncpy_nt(p->alias, argv[currentarg + 1], 32);
  183                 if (debug)
  184                     printf("Used alias: \"%s\"\n", p->alias);
  185                 p->setalias = 1;
  186                 currentarg++;
  187             } else {
  188                 printf("Error: Alias for %s missing.\n", argv[currentarg]);
  189                 exit(EXIT_FAILURE);
  190             }
  191         } else if ((strcmp(argv[currentarg], "--style")) == 0) {
  192             if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) {
  193                 cfg.ostyle = atoi(argv[currentarg + 1]);
  194                 if (cfg.ostyle > 4 || cfg.ostyle < 0) {
  195                     printf("Error: Invalid style parameter \"%d\"\n", cfg.ostyle);
  196                     showstylehelp();
  197                     exit(EXIT_FAILURE);
  198                 }
  199                 if (debug)
  200                     printf("Style changed: %d\n", cfg.ostyle);
  201                 currentarg++;
  202             } else {
  203                 printf("Error: Style parameter for --style missing.\n");
  204                 showstylehelp();
  205                 exit(EXIT_FAILURE);
  206             }
  207         } else if ((strcmp(argv[currentarg], "--dbdir")) == 0) {
  208             if (currentarg + 1 < argc) {
  209                 strncpy_nt(cfg.dbdir, argv[currentarg + 1], 512);
  210                 if (debug)
  211                     printf("DatabaseDir: \"%s\"\n", cfg.dbdir);
  212                 currentarg++;
  213             } else {
  214                 printf("Error: Directory for %s missing.\n", argv[currentarg]);
  215                 exit(EXIT_FAILURE);
  216             }
  217         } else if ((strcmp(argv[currentarg], "--locale")) == 0) {
  218             if (currentarg + 1 < argc) {
  219                 setlocale(LC_ALL, argv[currentarg + 1]);
  220                 if (debug)
  221                     printf("Locale: \"%s\"\n", argv[currentarg + 1]);
  222                 currentarg++;
  223             } else {
  224                 printf("Error: Locale for %s missing.\n", argv[currentarg]);
  225                 exit(EXIT_FAILURE);
  226             }
  227         } else if (strcmp(argv[currentarg], "--add") == 0) {
  228             p->addiface = 1;
  229             p->query = 0;
  230         } else if ((strcmp(argv[currentarg], "-u") == 0) || (strcmp(argv[currentarg], "--update") == 0)) {
  231             printf("Error: The \"%s\" parameter is not supported in this version.\n", argv[currentarg]);
  232             exit(EXIT_FAILURE);
  233         } else if ((strcmp(argv[currentarg], "-q") == 0) || (strcmp(argv[currentarg], "--query") == 0)) {
  234             p->query = 1;
  235         } else if ((strcmp(argv[currentarg], "-D") == 0) || (strcmp(argv[currentarg], "--debug") == 0)) {
  236             debug = 1;
  237         } else if ((strcmp(argv[currentarg], "-d") == 0) || (strcmp(argv[currentarg], "--days") == 0)) {
  238             cfg.qmode = 1;
  239             if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) {
  240                 cfg.listdays = atoi(argv[currentarg + 1]);
  241                 if (cfg.listdays < 0) {
  242                     printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]);
  243                     exit(EXIT_FAILURE);
  244                 }
  245                 currentarg++;
  246             }
  247         } else if ((strcmp(argv[currentarg], "-m") == 0) || (strcmp(argv[currentarg], "--months") == 0)) {
  248             cfg.qmode = 2;
  249             if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) {
  250                 cfg.listmonths = atoi(argv[currentarg + 1]);
  251                 if (cfg.listmonths < 0) {
  252                     printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]);
  253                     exit(EXIT_FAILURE);
  254                 }
  255                 currentarg++;
  256             }
  257         } else if ((strcmp(argv[currentarg], "-t") == 0) || (strcmp(argv[currentarg], "--top") == 0)) {
  258             cfg.qmode = 3;
  259             if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) {
  260                 cfg.listtop = atoi(argv[currentarg + 1]);
  261                 if (cfg.listtop < 0) {
  262                     printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]);
  263                     exit(EXIT_FAILURE);
  264                 }
  265                 currentarg++;
  266             }
  267         } else if ((strcmp(argv[currentarg], "-s") == 0) || (strcmp(argv[currentarg], "--short") == 0)) {
  268             cfg.qmode = 5;
  269         } else if ((strcmp(argv[currentarg], "-y") == 0) || (strcmp(argv[currentarg], "--years") == 0)) {
  270             cfg.qmode = 6;
  271             if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) {
  272                 cfg.listyears = atoi(argv[currentarg + 1]);
  273                 if (cfg.listyears < 0) {
  274                     printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]);
  275                     exit(EXIT_FAILURE);
  276                 }
  277                 currentarg++;
  278             }
  279         } else if ((strcmp(argv[currentarg], "-hg") == 0) || (strcmp(argv[currentarg], "--hoursgraph") == 0)) {
  280             cfg.qmode = 7;
  281         } else if ((strcmp(argv[currentarg], "-h") == 0) || (strcmp(argv[currentarg], "--hours") == 0)) {
  282             cfg.qmode = 11;
  283             if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) {
  284                 cfg.listhours = atoi(argv[currentarg + 1]);
  285                 if (cfg.listhours < 0) {
  286                     printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]);
  287                     exit(EXIT_FAILURE);
  288                 }
  289                 currentarg++;
  290             }
  291         } else if ((strcmp(argv[currentarg], "-5") == 0) || (strcmp(argv[currentarg], "--fiveminutes") == 0)) {
  292             cfg.qmode = 12;
  293             if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) {
  294                 cfg.listfivemins = atoi(argv[currentarg + 1]);
  295                 if (cfg.listfivemins < 0) {
  296                     printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]);
  297                     exit(EXIT_FAILURE);
  298                 }
  299                 currentarg++;
  300             }
  301         } else if (strcmp(argv[currentarg], "--oneline") == 0) {
  302             cfg.qmode = 9;
  303             if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) {
  304                 if (argv[currentarg + 1][0] == 'b') {
  305                     cfg.ostyle = 4;
  306                     currentarg++;
  307                 } else {
  308                     if (!ishelprequest(argv[currentarg + 1]))
  309                         printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]);
  310                     printf(" Valid parameters for --oneline:\n");
  311                     printf("    (none) - automatically scaled units visible\n");
  312                     printf("    b      - all values in bytes\n");
  313                     exit(EXIT_FAILURE);
  314                 }
  315             }
  316         } else if (strcmp(argv[currentarg], "--xml") == 0) {
  317             cfg.qmode = 8;
  318             if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) {
  319                 p->xmlmode = argv[currentarg + 1][0];
  320                 if (strlen(argv[currentarg + 1]) != 1 || strchr("afhdmyt", p->xmlmode) == NULL) {
  321                     if (!ishelprequest(argv[currentarg + 1]))
  322                         printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]);
  323                     printf(" Valid parameters for --xml:\n");
  324                     printf("    a - all (default)\n");
  325                     printf("    f - only 5 minutes\n");
  326                     printf("    h - only hours\n");
  327                     printf("    d - only days\n");
  328                     printf("    m - only months\n");
  329                     printf("    y - only years\n");
  330                     printf("    t - only top\n");
  331                     exit(EXIT_FAILURE);
  332                 }
  333                 currentarg++;
  334             }
  335             if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) {
  336                 cfg.listjsonxml = atoi(argv[currentarg + 1]);
  337                 if (cfg.listjsonxml < 0) {
  338                     printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]);
  339                     exit(EXIT_FAILURE);
  340                 }
  341                 currentarg++;
  342             }
  343         } else if (strcmp(argv[currentarg], "--json") == 0) {
  344             cfg.qmode = 10;
  345             if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) {
  346                 p->jsonmode = argv[currentarg + 1][0];
  347                 if (strlen(argv[currentarg + 1]) != 1 || strchr("afhdmyt", p->jsonmode) == NULL) {
  348                     if (!ishelprequest(argv[currentarg + 1]))
  349                         printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]);
  350                     printf(" Valid parameters for --json:\n");
  351                     printf("    a - all (default)\n");
  352                     printf("    f - only 5 minutes\n");
  353                     printf("    h - only hours\n");
  354                     printf("    d - only days\n");
  355                     printf("    m - only months\n");
  356                     printf("    y - only years\n");
  357                     printf("    t - only top\n");
  358                     exit(EXIT_FAILURE);
  359                 }
  360                 currentarg++;
  361             }
  362             if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) {
  363                 cfg.listjsonxml = atoi(argv[currentarg + 1]);
  364                 if (cfg.listjsonxml < 0) {
  365                     printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]);
  366                     exit(EXIT_FAILURE);
  367                 }
  368                 currentarg++;
  369             }
  370         } else if ((strcmp(argv[currentarg], "-ru") == 0) || (strcmp(argv[currentarg], "--rateunit")) == 0) {
  371             if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) {
  372                 if (!isdigit(argv[currentarg + 1][0]) || atoi(argv[currentarg + 1]) > 1 || atoi(argv[currentarg + 1]) < 0) {
  373                     if (!ishelprequest(argv[currentarg + 1]))
  374                         printf("Error: Invalid parameter \"%s\".\n", argv[currentarg + 1]);
  375                     printf(" Valid parameters for %s:\n", argv[currentarg]);
  376                     printf("    0 - bytes\n");
  377                     printf("    1 - bits\n");
  378                     exit(EXIT_FAILURE);
  379                 }
  380                 cfg.rateunit = atoi(argv[currentarg + 1]);
  381                 if (debug)
  382                     printf("Rateunit changed: %d\n", cfg.rateunit);
  383                 currentarg++;
  384             } else {
  385                 cfg.rateunit = !cfg.rateunit;
  386                 if (debug)
  387                     printf("Rateunit changed: %d\n", cfg.rateunit);
  388             }
  389         } else if ((strcmp(argv[currentarg], "-tr") == 0) || (strcmp(argv[currentarg], "--traffic") == 0)) {
  390             if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) {
  391                 cfg.sampletime = atoi(argv[currentarg + 1]);
  392                 currentarg++;
  393             }
  394             p->traffic = 1;
  395             p->query = 0;
  396         } else if ((strcmp(argv[currentarg], "-l") == 0) || (strcmp(argv[currentarg], "--live") == 0)) {
  397             if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) {
  398                 if (!isdigit(argv[currentarg + 1][0]) || atoi(argv[currentarg + 1]) > 1 || atoi(argv[currentarg + 1]) < 0) {
  399                     if (!ishelprequest(argv[currentarg + 1]))
  400                         printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]);
  401                     printf(" Valid parameters for %s:\n", argv[currentarg]);
  402                     printf("    0 - show packets per second (default)\n");
  403                     printf("    1 - show transfer counters\n");
  404                     exit(EXIT_FAILURE);
  405                 }
  406                 p->livemode = atoi(argv[currentarg + 1]);
  407                 currentarg++;
  408             }
  409             p->livetraffic = 1;
  410             p->query = 0;
  411         } else if (strcmp(argv[currentarg], "--force") == 0) {
  412             p->force = 1;
  413         } else if (strcmp(argv[currentarg], "--showconfig") == 0) {
  414             printcfgfile();
  415             exit(EXIT_SUCCESS);
  416         } else if (strcmp(argv[currentarg], "--remove") == 0) {
  417             p->removeiface = 1;
  418             p->query = 0;
  419         } else if (strcmp(argv[currentarg], "--rename") == 0) {
  420             if (currentarg + 1 < argc) {
  421                 strncpy_nt(p->newifname, argv[currentarg + 1], 32);
  422                 if (debug)
  423                     printf("Given new interface name: \"%s\"\n", p->newifname);
  424                 p->renameiface = 1;
  425                 p->query = 0;
  426                 currentarg++;
  427             } else {
  428                 printf("Error: New interface name for %s missing.\n", argv[currentarg]);
  429                 exit(EXIT_FAILURE);
  430             }
  431         } else if ((strcmp(argv[currentarg], "-b") == 0) || (strcmp(argv[currentarg], "--begin") == 0)) {
  432             if (currentarg + 1 < argc) {
  433                 if (!validatedatetime(argv[currentarg + 1])) {
  434                     printf("Error: Invalid date format, expected YYYY-MM-DD HH:MM, YYYY-MM-DD or \"today\".\n");
  435                     exit(EXIT_FAILURE);
  436                 }
  437                 strncpy_nt(p->databegin, argv[currentarg + 1], 18);
  438                 currentarg++;
  439             } else {
  440                 printf("Error: Date of format YYYY-MM-DD HH:MM, YYYY-MM-DD or \"today\" for %s missing.\n", argv[currentarg]);
  441                 exit(EXIT_FAILURE);
  442             }
  443         } else if ((strcmp(argv[currentarg], "-e") == 0) || (strcmp(argv[currentarg], "--end") == 0)) {
  444             if (currentarg + 1 < argc) {
  445                 if (!validatedatetime(argv[currentarg + 1])) {
  446                     printf("Error: Invalid date format, expected YYYY-MM-DD HH:MM or YYYY-MM-DD.\n");
  447                     exit(EXIT_FAILURE);
  448                 }
  449                 strncpy_nt(p->dataend, argv[currentarg + 1], 18);
  450                 currentarg++;
  451             } else {
  452                 printf("Error: Date of format YYYY-MM-DD HH:MM or YYYY-MM-DD for %s missing.\n", argv[currentarg]);
  453                 exit(EXIT_FAILURE);
  454             }
  455         } else if (strcmp(argv[currentarg], "--iflist") == 0) {
  456             p->query = 0;
  457             if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) {
  458                 if (!isdigit(argv[currentarg + 1][0]) || atoi(argv[currentarg + 1]) > 1 || atoi(argv[currentarg + 1]) < 0) {
  459                     if (!ishelprequest(argv[currentarg + 1]))
  460                         printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]);
  461                     printf(" Valid parameters for --iflist:\n");
  462                     printf("    0 - show verbose (default)\n");
  463                     printf("    1 - show one interface per line\n");
  464                     exit(EXIT_FAILURE);
  465                 }
  466                 p->query = atoi(argv[currentarg + 1]);
  467                 currentarg++;
  468             }
  469             showiflist(p->query);
  470             exit(EXIT_SUCCESS);
  471         } else if (strcmp(argv[currentarg], "--dbiflist") == 0) {
  472             p->query = 0;
  473             if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) {
  474                 if (!isdigit(argv[currentarg + 1][0]) || atoi(argv[currentarg + 1]) > 1 || atoi(argv[currentarg + 1]) < 0) {
  475                     if (!ishelprequest(argv[currentarg + 1]))
  476                         printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]);
  477                     printf(" Valid parameters for --dbiflist:\n");
  478                     printf("    0 - show verbose (default)\n");
  479                     printf("    1 - show one interface per line\n");
  480                     exit(EXIT_FAILURE);
  481                 }
  482                 p->query = atoi(argv[currentarg + 1]);
  483                 currentarg++;
  484             }
  485             showdbiflist(p->query);
  486             exit(EXIT_SUCCESS);
  487         } else if (strcmp(argv[currentarg], "--limit") == 0) {
  488             if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) {
  489                 p->limit = atoi(argv[currentarg + 1]);
  490                 if (p->limit < 0) {
  491                     printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]);
  492                     exit(EXIT_FAILURE);
  493                 }
  494                 currentarg++;
  495             } else {
  496                 printf("Error: Invalid or missing parameter for %s.\n", argv[currentarg]);
  497                 exit(EXIT_FAILURE);
  498             }
  499         } else if (strcmp(argv[currentarg], "--alert") == 0) {
  500             if (currentarg + 6 >= argc) {
  501                 printf("Error: Invalid parameter count for %s.\n", argv[currentarg]);
  502                 showalerthelp();
  503                 exit(EXIT_FAILURE);
  504             }
  505             if (!parsealertargs(p, argv + currentarg)) {
  506                 exit(EXIT_FAILURE);
  507             } else {
  508                 currentarg += 6;
  509                 p->alert = 1;
  510             }
  511         } else if ((strcmp(argv[currentarg], "-v") == 0) || (strcmp(argv[currentarg], "--version") == 0)) {
  512             printf("vnStat %s by Teemu Toivola <tst at iki dot fi>\n", getversion());
  513             exit(EXIT_SUCCESS);
  514         } else {
  515             if (argv[currentarg][0] == '-' || strlen(argv[currentarg]) == 1) {
  516                 printf("Unknown parameter \"%s\". Use --help for help.\n", argv[currentarg]);
  517                 exit(EXIT_FAILURE);
  518             } else {
  519                 if (strlen(argv[currentarg]) > 31) {
  520                     printf("Error: Interface name is limited to 31 characters.\n");
  521                     exit(EXIT_FAILURE);
  522                 }
  523                 strncpy_nt(p->interface, argv[currentarg], 32);
  524                 if (strlen(p->interface)) {
  525                     p->defaultiface = 0;
  526                 } else {
  527                     strncpy_nt(p->definterface, p->interface, 32);
  528                 }
  529                 if (debug)
  530                     printf("Used interface: \"%s\"\n", p->interface);
  531             }
  532         }
  533     }
  534 
  535     if (p->limit != -1) {
  536         cfg.listfivemins = cfg.listhours = cfg.listdays = cfg.listmonths = cfg.listyears = cfg.listtop = cfg.listjsonxml = p->limit;
  537     }
  538 }
  539 
  540 int parsealertargs(PARAMS *p, char **argv)
  541 {
  542     int i, u, found, currentarg = 0;
  543     uint64_t alertlimit = 0, unitmultiplier = 1;
  544     int32_t unitmode = cfg.unitmode;
  545     const char *alerttypes[] = {"h", "hour", "hourly", "d", "day", "daily", "m", "month", "monthly", "y", "year", "yearly"};
  546     const char *alertconditions[] = {"rx", "tx", "total", "rx_estimate", "tx_estimate", "total_estimate"}; // order must match that of AlertCondition in dbshow.h
  547 
  548     for (i = 1; i <= 6; i++) {
  549         if (argv[currentarg + i][0] == '-' || ishelprequest(argv[currentarg + i])) {
  550             showalerthelp();
  551             return 0;
  552         }
  553     }
  554     currentarg++;
  555 
  556     // output
  557     if (!isnumeric(argv[currentarg])) {
  558         printf("Error: Non-numeric output parameter \"%s\" for %s.\n", argv[currentarg], argv[0]);
  559         showalerthelp();
  560         return 0;
  561     }
  562     p->alertoutput = (unsigned int)atoi(argv[currentarg]);
  563     if (p->alertoutput > 3) {
  564         printf("Error: Output parameter out of range for %s.\n", argv[0]);
  565         showalerthelp();
  566         return 0;
  567     }
  568     if (debug) {
  569         printf("Alert output: %u\n", p->alertoutput);
  570     }
  571     currentarg++;
  572 
  573     // exit
  574     if (!isnumeric(argv[currentarg])) {
  575         printf("Error: Non-numeric exit parameter \"%s\" for %s.\n", argv[currentarg], argv[0]);
  576         showalerthelp();
  577         return 0;
  578     }
  579     p->alertexit = (unsigned int)atoi(argv[currentarg]);
  580     if (p->alertexit > 3) {
  581         printf("Error: Exit parameter out of range for %s.\n", argv[0]);
  582         showalerthelp();
  583         return 0;
  584     }
  585     if (debug) {
  586         printf("Alert exit: %u\n", p->alertexit);
  587     }
  588 
  589     if (p->alertoutput == AO_No_Output && (p->alertexit == AE_Always_Exit_0 || p->alertexit == AE_Always_Exit_1)) {
  590         printf("Error: Configuring %s for no output and always same exit status provides no real usability.\n", argv[0]);
  591         showalerthelp();
  592         return 0;
  593     }
  594     currentarg++;
  595 
  596     // type
  597     found = 0;
  598     for (i = 0; i < 12; i++) {
  599         if (strcmp(argv[currentarg], alerttypes[i]) == 0) {
  600             found = 1;
  601             break;
  602         }
  603     }
  604     if (!found) {
  605         printf("Error: Invalid type parameter \"%s\" for %s.\n", argv[currentarg], argv[0]);
  606         showalerthelp();
  607         return 0;
  608     }
  609 
  610     switch (argv[currentarg][0]) {
  611         case 'h':
  612             p->alerttype = AT_Hour;
  613             break;
  614         case 'd':
  615             p->alerttype = AT_Day;
  616             break;
  617         case 'm':
  618             p->alerttype = AT_Month;
  619             break;
  620         case 'y':
  621             p->alerttype = AT_Year;
  622             break;
  623         default:
  624             return 0;
  625     }
  626     if (debug) {
  627         printf("Alert type: %u\n", p->alerttype);
  628     }
  629     currentarg++;
  630 
  631     // condition
  632     found = 0;
  633     for (i = 0; i < 6; i++) {
  634         if (strcmp(argv[currentarg], alertconditions[i]) == 0) {
  635             found = 1;
  636             p->alertcondition = (unsigned int)i + 1;
  637             break;
  638         }
  639     }
  640     if (!found) {
  641         printf("Error: Invalid condition parameter \"%s\" for %s.\n", argv[currentarg], argv[0]);
  642         showalerthelp();
  643         return 0;
  644     }
  645     if (debug) {
  646         printf("Alert condition: %u\n", p->alertcondition);
  647     }
  648     currentarg++;
  649 
  650     if ((p->alertcondition == AC_RX_Estimate || p->alertcondition == AC_TX_Estimate || p->alertcondition == AC_Total_Estimate) &&
  651         (p->alertoutput == AO_Output_On_Estimate || p->alertexit == AE_Exit_1_On_Estimate)) {
  652         if (p->alertoutput == AO_Output_On_Estimate) {
  653             printf("Error: Estimate conditions cannot be used in combination with output parameter \"2\".\n");
  654         }
  655         if (p->alertexit == AE_Exit_1_On_Estimate) {
  656             printf("Error: Estimate conditions cannot be used in combination with exit parameter \"2\".\n");
  657         }
  658         showalerthelp();
  659         return 0;
  660     }
  661 
  662     // limit
  663     if (!isnumeric(argv[currentarg])) {
  664         printf("Error: Limit parameter for %s must be a greater than zero integer without decimals.\n", argv[0]);
  665         showalerthelp();
  666         return 0;
  667     }
  668     alertlimit = strtoull(argv[currentarg], (char **)NULL, 0);
  669     if (alertlimit == 0) {
  670         printf("Error: Invalid limit parameter \"%s\" for %s.\n", argv[currentarg], argv[0]);
  671         showalerthelp();
  672         return 0;
  673     }
  674     if (debug) {
  675         printf("Alert limit: %" PRIu64 "\n", alertlimit);
  676     }
  677     currentarg++;
  678 
  679     // limit unit
  680     found = 0;
  681     for (u = 0; u < 3; u++) {
  682         cfg.unitmode = u;
  683         for (i = 1; i <= UNITPREFIXCOUNT; i++) {
  684             if (strcmp(argv[currentarg], getunitprefix(i)) == 0) {
  685                 found = 1;
  686                 break;
  687             }
  688         }
  689         if (found) {
  690             break;
  691         }
  692     }
  693     cfg.unitmode = unitmode;
  694     if (!found) {
  695         printf("Error: Invalid limit unit parameter \"%s\" for %s.\n", argv[currentarg], argv[0]);
  696         showalerthelp();
  697         return 0;
  698     }
  699 
  700     unitmultiplier = getunitdivisor(u, i);
  701 
  702     if (alertlimit > (uint64_t)(MAX64 / unitmultiplier)) {
  703         printf("Error: %" PRIu64 " %s exceeds maximum supported limit of %" PRIu64 " %s.\n", alertlimit, argv[currentarg], (uint64_t)(MAX64 / unitmultiplier), argv[currentarg]);
  704         return 0;
  705     }
  706 
  707     p->alertlimit = alertlimit * unitmultiplier;
  708 
  709     if (debug) {
  710         printf("Alert unit %s is %d %d = %" PRIu64 "\n", argv[currentarg], u, i, unitmultiplier);
  711         printf("Alert real limit is %" PRIu64 " * %" PRIu64 " = %" PRIu64 "\n", alertlimit, unitmultiplier, p->alertlimit);
  712     }
  713 
  714     return 1;
  715 }
  716 
  717 void showalerthelp(void)
  718 {
  719     printf("\n");
  720     printf("Valid parameters for\n--alert <output> <exit> <type> <condition> <limit> <unit>\n\n");
  721 
  722     printf(" <output>\n");
  723     printf("    0 - no output\n");
  724     printf("    1 - always show output\n");
  725     printf("    2 - show output only if usage estimate exceeds limit\n");
  726     printf("    3 - show output only if limit is exceeded\n\n");
  727 
  728     printf(" <exit>\n");
  729     printf("    0 - always use exit status 0\n");
  730     printf("    1 - always use exit status 1\n");
  731     printf("    2 - use exit status 1 if usage estimate exceeds limit\n");
  732     printf("    3 - use exit status 1 if limit is exceeded\n\n");
  733 
  734     printf(" <type>\n");
  735     printf("    h, hour, hourly        d, day, daily\n");
  736     printf("    m, month, monthly      y, year, yearly\n\n");
  737 
  738     printf(" <condition>\n");
  739     printf("    rx, tx, total, rx_estimate, tx_estimate, total_estimate\n\n");
  740 
  741     printf(" <limit>\n");
  742     printf("    greater than zero integer without decimals\n\n");
  743 
  744     printf(" <unit> for <limit>\n");
  745     printf("    B, KiB, MiB, GiB, TiB, PiB, EiB\n");
  746     printf("    B, KB, MB, GB, TB, PB, EB\n");
  747 }
  748 
  749 void showstylehelp(void)
  750 {
  751     printf(" Valid parameters for --style:\n");
  752     printf("    0 - a more narrow output\n");
  753     printf("    1 - enable bar column if available\n");
  754     printf("    2 - average traffic rate in summary output\n");
  755     printf("    3 - average traffic rate in all outputs if available\n");
  756     printf("    4 - disable terminal control characters in -l / --live\n");
  757     printf("        and show raw values in --oneline\n");
  758 }
  759 
  760 void handleshowalert(PARAMS *p)
  761 {
  762     int alert = 0;
  763 
  764     if (!p->alert) {
  765         return;
  766     }
  767 
  768     if (p->defaultiface) {
  769         printf("Error: An interface needs to be explicitly specified for --alert.\n");
  770         exit(EXIT_FAILURE);
  771     }
  772 
  773     validateinterface(p);
  774 
  775     alert = showalert(p->interface, p->alertoutput, p->alertexit, p->alerttype, p->alertcondition, p->alertlimit);
  776 
  777     if ((alert || p->alertexit == AE_Always_Exit_1) && p->alertexit != AE_Always_Exit_0) {
  778         exit(EXIT_FAILURE);
  779     }
  780 
  781     exit(EXIT_SUCCESS);
  782 }
  783 
  784 void handleremoveinterface(PARAMS *p)
  785 {
  786     if (!p->removeiface) {
  787         return;
  788     }
  789 
  790     if (p->defaultiface) {
  791         printf("Error: An interface needs to be explicitly specified for --remove.\n");
  792         exit(EXIT_FAILURE);
  793     }
  794 
  795     if (!db_getinterfacecountbyname(p->interface)) {
  796         printf("Error: Interface \"%s\" not found in database.\n", p->interface);
  797         exit(EXIT_FAILURE);
  798     }
  799 
  800     if (!p->force) {
  801         printf("Warning:\nThe current option would remove all data about interface \"%s\" from the database. ", p->interface);
  802         printf("Add --force in order to really do that.\n");
  803         exit(EXIT_FAILURE);
  804     }
  805 
  806 #ifndef CHECK_VNSTAT
  807     if (!db_close() || !db_open_rw(0)) {
  808         printf("Error: Handling database \"%s/%s\" failing: %s\n", cfg.dbdir, DATABASEFILE, strerror(errno));
  809         exit(EXIT_FAILURE);
  810     }
  811 #endif
  812 
  813     if (db_removeinterface(p->interface)) {
  814         printf("Interface \"%s\" removed from database.\n", p->interface);
  815         printf("The interface will no longer be monitored. Use --add if monitoring the interface is again needed.\n");
  816 #ifndef CHECK_VNSTAT
  817         db_close();
  818         exit(EXIT_SUCCESS);
  819 #endif
  820     } else {
  821         printf("Error: Removing interface \"%s\" from database failed.\n", p->interface);
  822         exit(EXIT_FAILURE);
  823     }
  824 }
  825 
  826 void handlerenameinterface(PARAMS *p)
  827 {
  828     if (!p->renameiface) {
  829         return;
  830     }
  831 
  832     if (p->defaultiface) {
  833         printf("Error: An interface needs to be explicitly specified for --rename.\n");
  834         exit(EXIT_FAILURE);
  835     }
  836 
  837     if (!strlen(p->newifname)) {
  838         printf("Error: New interface name must be at least one character long.\n");
  839         exit(EXIT_FAILURE);
  840     }
  841 
  842     if (!db_getinterfacecountbyname(p->interface)) {
  843         printf("Error: Interface \"%s\" not found in database.\n", p->interface);
  844         exit(EXIT_FAILURE);
  845     }
  846 
  847     if (db_getinterfacecountbyname(p->newifname)) {
  848         printf("Error: Interface \"%s\" already exists in database.\n", p->newifname);
  849         exit(EXIT_FAILURE);
  850     }
  851 
  852     if (!p->force) {
  853         printf("Warning:\nThe current option would rename interface \"%s\" -> \"%s\" in the database. ", p->interface, p->newifname);
  854         printf("Add --force in order to really do that.\n");
  855         exit(EXIT_FAILURE);
  856     }
  857 
  858 #ifndef CHECK_VNSTAT
  859     if (!db_close() || !db_open_rw(0)) {
  860         printf("Error: Handling database \"%s/%s\" failing: %s\n", cfg.dbdir, DATABASEFILE, strerror(errno));
  861         exit(EXIT_FAILURE);
  862     }
  863 #endif
  864 
  865     if (db_renameinterface(p->interface, p->newifname)) {
  866         printf("Interface \"%s\" has been renamed \"%s\".\n", p->interface, p->newifname);
  867 #ifndef CHECK_VNSTAT
  868         db_close();
  869         exit(EXIT_SUCCESS);
  870 #endif
  871     } else {
  872         printf("Error: Renaming interface \"%s\" -> \"%s\" failed.\n", p->interface, p->newifname);
  873         exit(EXIT_FAILURE);
  874     }
  875 }
  876 
  877 void handleaddinterface(PARAMS *p)
  878 {
  879     if (!p->addiface) {
  880         return;
  881     }
  882 
  883     if (p->defaultiface) {
  884         printf("Error: An interface needs to be explicitly specified for --add.\n");
  885         exit(EXIT_FAILURE);
  886     }
  887 
  888     db_errcode = 0;
  889     if (db_getinterfacecountbyname(p->interface)) {
  890         printf("Error: Interface \"%s\" already exists in the database.\n", p->interface);
  891         exit(EXIT_FAILURE);
  892     }
  893     if (db_errcode) {
  894         exit(EXIT_FAILURE);
  895     }
  896 
  897     if (!p->force && !getifinfo(p->interface)) {
  898         getifliststring(&p->ifacelist, 1);
  899         printf("Only available interfaces can be added for monitoring.\n\n");
  900         printf("The following interfaces are currently available:\n    %s\n", p->ifacelist);
  901         free(p->ifacelist);
  902         exit(EXIT_FAILURE);
  903     }
  904 
  905     if (!p->force && !spacecheck(cfg.dbdir)) {
  906         printf("Error: Not enough free diskspace available.\n");
  907         exit(EXIT_FAILURE);
  908     }
  909 
  910 #ifndef CHECK_VNSTAT
  911     if (!db_close() || !db_open_rw(0)) {
  912         printf("Error: Handling database \"%s/%s\" failing: %s\n", cfg.dbdir, DATABASEFILE, strerror(errno));
  913         exit(EXIT_FAILURE);
  914     }
  915 #endif
  916 
  917     printf("Adding interface \"%s\" to database for monitoring.\n", p->interface);
  918     if (db_addinterface(p->interface)) {
  919         if (cfg.rescanonsave) {
  920             printf("vnStat daemon will automatically start monitoring \"%s\" within %d minutes if the daemon process is currently running.\n", p->interface, cfg.saveinterval);
  921         } else {
  922             printf("Restart vnStat daemon if it is currently running in order to start monitoring \"%s\".\n", p->interface);
  923         }
  924         handlesetalias(p);
  925 #ifndef CHECK_VNSTAT
  926         db_close();
  927         exit(EXIT_SUCCESS);
  928 #endif
  929     } else {
  930         printf("Error: Adding interface \"%s\" to database failed.\n", p->interface);
  931         exit(EXIT_FAILURE);
  932     }
  933 }
  934 
  935 void handlesetalias(PARAMS *p)
  936 {
  937     if (!p->setalias) {
  938         return;
  939     }
  940 
  941     if (p->defaultiface) {
  942         printf("Error: An interface needs to be explicitly specified for --setalias.\n");
  943         exit(EXIT_FAILURE);
  944     }
  945 
  946     if (!db_getinterfacecountbyname(p->interface)) {
  947         printf("Error: Interface \"%s\" not found in database.\n", p->interface);
  948         exit(EXIT_FAILURE);
  949     }
  950 
  951 #ifndef CHECK_VNSTAT
  952     if (!db_close() || !db_open_rw(0)) {
  953         printf("Error: Handling database \"%s/%s\" failing: %s\n", cfg.dbdir, DATABASEFILE, strerror(errno));
  954         exit(EXIT_FAILURE);
  955     }
  956 #endif
  957 
  958     if (db_setalias(p->interface, p->alias)) {
  959         printf("Alias of interface \"%s\" set to \"%s\".\n", p->interface, p->alias);
  960 #ifndef CHECK_VNSTAT
  961         db_close();
  962         exit(EXIT_SUCCESS);
  963 #endif
  964     } else {
  965         printf("Error: Setting interface \"%s\" alias failed.\n", p->interface);
  966         exit(EXIT_FAILURE);
  967     }
  968 }
  969 
  970 void handleshowdata(PARAMS *p)
  971 {
  972     int ifcount = 0;
  973     iflist *dbifl = NULL, *dbifl_i = NULL;
  974 
  975     if (!p->query) {
  976         return;
  977     }
  978 
  979     /* show only specified file */
  980     if (!p->defaultiface) {
  981         showoneinterface(p);
  982         return;
  983     }
  984 
  985     /* show all interfaces if none is explicitly specified */
  986     if (p->dbifcount == 0) {
  987         p->query = 0;
  988     } else if ((cfg.qmode == 0 || cfg.qmode == 8 || cfg.qmode == 10) && (p->dbifcount > 1)) {
  989 
  990         if (cfg.qmode == 0) {
  991             if (cfg.ostyle != 0) {
  992                 printf("\n                      rx      /      tx      /     total    /   estimated\n");
  993             } else {
  994                 printf("\n                      rx      /      tx      /     total\n");
  995             }
  996         } else if (cfg.qmode == 8) {
  997             xmlheader();
  998         } else if (cfg.qmode == 10) {
  999             jsonheader();
 1000         }
 1001 
 1002         if (db_getiflist(&dbifl) <= 0) {
 1003             return;
 1004         }
 1005 
 1006         dbifl_i = dbifl;
 1007 
 1008         while (dbifl_i != NULL) {
 1009             strncpy_nt(p->interface, dbifl_i->interface, 32);
 1010             if (debug)
 1011                 printf("\nProcessing interface \"%s\"...\n", p->interface);
 1012             if (cfg.qmode == 0) {
 1013                 showdb(p->interface, 5, "", "");
 1014             } else if (cfg.qmode == 8) {
 1015                 showxml(p->interface, p->xmlmode, p->databegin, p->dataend);
 1016             } else if (cfg.qmode == 10) {
 1017                 showjson(p->interface, ifcount, p->jsonmode, p->databegin, p->dataend);
 1018             }
 1019             ifcount++;
 1020             dbifl_i = dbifl_i->next;
 1021         }
 1022         iflistfree(&dbifl);
 1023 
 1024         if (cfg.qmode == 8) {
 1025             xmlfooter();
 1026         } else if (cfg.qmode == 10) {
 1027             jsonfooter();
 1028         }
 1029 
 1030         /* show in qmode if there's only one interface or qmode!=0 */
 1031     } else {
 1032         showoneinterface(p);
 1033     }
 1034 }
 1035 
 1036 void showoneinterface(PARAMS *p)
 1037 {
 1038     validateinterface(p);
 1039 
 1040     if (cfg.qmode == 5) {
 1041         if (cfg.ostyle != 0) {
 1042             printf("\n                      rx      /      tx      /     total    /   estimated\n");
 1043         } else {
 1044             printf("\n                      rx      /      tx      /     total\n");
 1045         }
 1046     }
 1047     if (cfg.qmode != 8 && cfg.qmode != 10) {
 1048         showdb(p->interface, cfg.qmode, p->databegin, p->dataend);
 1049     } else if (cfg.qmode == 8) {
 1050         xmlheader();
 1051         showxml(p->interface, p->xmlmode, p->databegin, p->dataend);
 1052         xmlfooter();
 1053     } else if (cfg.qmode == 10) {
 1054         jsonheader();
 1055         showjson(p->interface, 0, p->jsonmode, p->databegin, p->dataend);
 1056         jsonfooter();
 1057     }
 1058 }
 1059 
 1060 void handletrafficmeters(PARAMS *p)
 1061 {
 1062     int i;
 1063 
 1064     if (!p->traffic && !p->livetraffic) {
 1065         return;
 1066     }
 1067 
 1068     if (strchr(p->interface, '+') != NULL) {
 1069         printf("This feature doesn't support interface merges (\"%s\"), ", p->interface);
 1070         for (i = 0; i < (int)strlen(p->interface); i++) {
 1071             if (p->interface[i] == '+') {
 1072                 p->interface[i] = '\0';
 1073                 break;
 1074             }
 1075         }
 1076         p->defaultiface = 0;
 1077         printf("using \"%s\" instead.\n", p->interface);
 1078     }
 1079 
 1080     if (!isifavailable(p->interface)) {
 1081         getifliststring(&p->ifacelist, 0);
 1082         if (p->defaultiface) {
 1083             printf("Error: Configured default interface \"%s\" isn't available.\n\n", p->interface);
 1084             if (strlen(cfg.cfgfile)) {
 1085                 printf("Update \"Interface\" keyword value in configuration file \"%s\" to change ", cfg.cfgfile);
 1086                 printf("the default interface or give an alternative interface with or without the -i parameter.\n\n");
 1087             } else {
 1088                 printf("An alternative interface can be given with or without the -i parameter.\n\n");
 1089             }
 1090             printf("The following interfaces are currently available:\n    %s\n", p->ifacelist);
 1091 
 1092         } else {
 1093             printf("Error: Unable to get interface \"%s\" statistics.\n\n", p->interface);
 1094             printf("The following interfaces are currently available:\n    %s\n", p->ifacelist);
 1095         }
 1096         free(p->ifacelist);
 1097         exit(EXIT_FAILURE);
 1098     }
 1099 
 1100     /* calculate traffic */
 1101     if (p->traffic) {
 1102         trafficmeter(p->interface, (unsigned int)cfg.sampletime);
 1103     }
 1104 
 1105     /* live traffic */
 1106     if (p->livetraffic) {
 1107         livetrafficmeter(p->interface, p->livemode);
 1108     }
 1109 }
 1110 
 1111 void handleifselection(PARAMS *p)
 1112 {
 1113     int ifcount, dbifcount = 0, iffound = 0, dbopened = 0;
 1114     iflist *ifl = NULL;
 1115     iflist *dbifl = NULL, *dbifl_iterator = NULL;
 1116 
 1117     if (!p->defaultiface) {
 1118         return;
 1119     }
 1120 
 1121     if (strlen(p->definterface)) {
 1122         strncpy_nt(p->interface, p->definterface, 32);
 1123         return;
 1124     }
 1125 
 1126     if (p->traffic || p->livetraffic) {
 1127         ifcount = getiflist(&ifl, 0, 1);
 1128 
 1129         /* try to open database for extra information */
 1130         if (db == NULL) {
 1131             if (!db_open_ro()) {
 1132                 db = NULL;
 1133             } else {
 1134                 dbopened = 1;
 1135             }
 1136         }
 1137 
 1138         if (db != NULL) {
 1139             dbifcount = db_getiflist_sorted(&dbifl, 1);
 1140             if (dbopened) {
 1141                 db_close();
 1142             }
 1143         }
 1144 
 1145         if (dbifcount > 0 && ifcount > 0) {
 1146             dbifl_iterator = dbifl;
 1147             while (dbifl_iterator != NULL) {
 1148                 if (iflistsearch(&ifl, dbifl_iterator->interface)) {
 1149                     strncpy_nt(p->interface, dbifl_iterator->interface, 32);
 1150                     iffound = 1;
 1151                     if (debug)
 1152                         printf("Automatically selected interface with db: \"%s\"\n", p->interface);
 1153                     break;
 1154                 }
 1155                 dbifl_iterator = dbifl_iterator->next;
 1156             }
 1157         }
 1158 
 1159         if (!iffound) {
 1160             if (ifcount > 0) {
 1161                 strncpy_nt(p->interface, ifl->interface, 32);
 1162                 if (debug)
 1163                     printf("Automatically selected interface without db: \"%s\"\n", p->interface);
 1164             } else {
 1165                 printf("Error: Unable to find any suitable interface.\n");
 1166                 iflistfree(&ifl);
 1167                 iflistfree(&dbifl);
 1168                 exit(EXIT_FAILURE);
 1169             }
 1170         }
 1171 
 1172         iflistfree(&ifl);
 1173     } else if (p->query) {
 1174         if (db_getiflist_sorted(&dbifl, 1) <= 0) {
 1175             printf("Error: Unable to discover suitable interface from database.\n");
 1176             iflistfree(&dbifl);
 1177             exit(EXIT_FAILURE);
 1178         }
 1179         strncpy_nt(p->interface, dbifl->interface, 32);
 1180         if (debug)
 1181             printf("Automatically selected interface from db: \"%s\"\n", p->interface);
 1182     }
 1183 
 1184     iflistfree(&dbifl);
 1185 }
 1186 
 1187 void showiflist(const int parseable)
 1188 {
 1189     char *ifacelist = NULL;
 1190     iflist *ifl = NULL, *ifl_iterator = NULL;
 1191 
 1192     if (!parseable) {
 1193         if (!getifliststring(&ifacelist, 1)) {
 1194             exit(EXIT_FAILURE);
 1195         }
 1196         if (strlen(ifacelist)) {
 1197             printf("Available interfaces: %s\n", ifacelist);
 1198         } else {
 1199             printf("No usable interfaces found.\n");
 1200         }
 1201         free(ifacelist);
 1202     } else {
 1203         if (!getiflist(&ifl, 0, 1)) {
 1204             exit(EXIT_FAILURE);
 1205         }
 1206         ifl_iterator = ifl;
 1207         while (ifl_iterator != NULL) {
 1208             printf("%s\n", ifl_iterator->interface);
 1209             ifl_iterator = ifl_iterator->next;
 1210         }
 1211         iflistfree(&ifl);
 1212     }
 1213 }
 1214 
 1215 void showdbiflist(const int parseable)
 1216 {
 1217     int dbifcount;
 1218     iflist *dbifl = NULL, *dbifl_i = NULL;
 1219 
 1220     if (db == NULL && !db_open_ro()) {
 1221         printf("Error: Failed to open database \"%s/%s\" in read-only mode.\n", cfg.dbdir, DATABASEFILE);
 1222         exit(EXIT_FAILURE);
 1223     }
 1224 
 1225     dbifcount = db_getiflist(&dbifl);
 1226     if (dbifcount < 0) {
 1227         printf("Error: Failed to get interface list from database \"%s/%s\".\n", cfg.dbdir, DATABASEFILE);
 1228         exit(EXIT_FAILURE);
 1229     }
 1230 
 1231     if (dbifcount == 0 && !parseable) {
 1232         printf("Database is empty.");
 1233     } else {
 1234         dbifl_i = dbifl;
 1235 
 1236         if (!parseable) {
 1237             printf("Interfaces in database:");
 1238             while (dbifl_i != NULL) {
 1239                 printf(" %s", dbifl_i->interface);
 1240                 dbifl_i = dbifl_i->next;
 1241             }
 1242             printf("\n");
 1243         } else {
 1244             while (dbifl_i != NULL) {
 1245                 printf("%s\n", dbifl_i->interface);
 1246                 dbifl_i = dbifl_i->next;
 1247             }
 1248         }
 1249     }
 1250 
 1251     iflistfree(&dbifl);
 1252     db_close();
 1253 }
 1254 
 1255 void validateinterface(PARAMS *p)
 1256 {
 1257     int i, found = 0;
 1258 
 1259     timeused_debug(__func__, 1);
 1260 
 1261     if (!db_getinterfacecountbyname(p->interface)) {
 1262         if (strchr(p->interface, '+') == NULL) {
 1263             for (i = 1; i <= cfg.ifacematchmethod; i++) {
 1264                 found = db_setinterfacebyalias(p->interface, p->interface, i);
 1265                 if (found) {
 1266                     if (debug) {
 1267                         printf("Found \"%s\" with method %d\n", p->interface, i);
 1268                     }
 1269                     break;
 1270                 }
 1271             }
 1272             if (!found) {
 1273                 printf("Error: No interface matching \"%s\" found in database.\n", p->interface);
 1274                 exit(EXIT_FAILURE);
 1275             }
 1276         } else {
 1277             printf("Error: Not all requested interfaces found in database or given interfaces aren't unique.\n");
 1278             exit(EXIT_FAILURE);
 1279         }
 1280     }
 1281 
 1282     timeused_debug(__func__, 0);
 1283 }