#include "common.h" #include "ifinfo.h" #include "iflist.h" #include "traffic.h" #include "dbsql.h" #include "dbxml.h" #include "dbjson.h" #include "dbshow.h" #include "misc.h" #include "cfg.h" #include "cfgoutput.h" #include "vnstat_func.h" void initparams(PARAMS *p) { db = NULL; noexit = 0; /* allow functions to exit in case of error */ debug = 0; /* debug disabled by default */ disableprints = 0; /* let prints be visible */ p->addiface = 0; p->query = 1; p->setalias = 0; p->dbifcount = 0; p->force = 0; p->traffic = 0; p->livetraffic = 0; p->defaultiface = 1; p->removeiface = 0; p->renameiface = 0; p->livemode = 0; p->limit = -1; p->ifacelist = NULL; p->interface[0] = '\0'; p->alias[0] = '\0'; p->newifname[0] = '\0'; p->filename[0] = '\0'; p->definterface[0] = '\0'; p->cfgfile[0] = '\0'; p->jsonmode = 'a'; p->xmlmode = 'a'; p->databegin[0] = '\0'; p->dataend[0] = '\0'; } void showhelp(PARAMS *p) { printf("vnStat %s by Teemu Toivola \n\n", getversion()); printf(" -5, --fiveminutes [limit] show 5 minutes\n"); printf(" -h, --hours [limit] show hours\n"); printf(" -hg, --hoursgraph show hours graph\n"); printf(" -d, --days [limit] show days\n"); printf(" -m, --months [limit] show months\n"); printf(" -y, --years [limit] show years\n"); printf(" -t, --top [limit] show top days\n\n"); printf(" -b, --begin set list begin date\n"); printf(" -e, --end set list end date\n\n"); printf(" --oneline [mode] show simple parsable format\n"); printf(" --json [mode] [limit] show database in json format\n"); printf(" --xml [mode] [limit] show database in xml format\n\n"); printf(" -tr, --traffic [time] calculate traffic\n"); printf(" -l, --live [mode] show transfer rate in real time\n"); printf(" -i, --iface select interface"); if (strlen(p->definterface)) { printf(" (default: %s)", p->definterface); } printf("\n\n"); printf("Use \"--longhelp\" or \"man vnstat\" for complete list of options.\n"); } void showlonghelp(PARAMS *p) { printf("vnStat %s by Teemu Toivola \n\n", getversion()); printf("Query:\n"); printf(" -q, --query query database\n"); printf(" -s, --short use short output\n"); printf(" -5, --fiveminutes [limit] show 5 minutes\n"); printf(" -h, --hours [limit] show hours\n"); printf(" -hg, --hoursgraph show hours graph\n"); printf(" -d, --days [limit] show days\n"); printf(" -m, --months [limit] show months\n"); printf(" -y, --years [limit] show years\n"); printf(" -t, --top [limit] show top days\n"); printf(" -b, --begin set list begin date\n"); printf(" -e, --end set list end date\n"); printf(" --oneline [mode] show simple parsable format\n"); printf(" --json [mode] [limit] show database in json format\n"); printf(" --xml [mode] [limit] show database in xml format\n\n"); printf("Modify:\n"); printf(" --add add interface to database\n"); printf(" --remove remove interface from database\n"); printf(" --rename rename interface in database\n"); printf(" --setalias set alias for interface\n\n"); printf("Misc:\n"); printf(" -i, --iface select interface"); if (strlen(p->definterface)) { printf(" (default: %s)", p->definterface); } printf("\n"); printf(" -?, --help show short help\n"); printf(" -D, --debug show some additional debug information\n"); printf(" -v, --version show version\n"); printf(" -tr, --traffic [time] calculate traffic\n"); printf(" -l, --live [mode] show transfer rate in real time\n"); printf(" -ru, --rateunit [mode] swap configured rate unit\n"); printf(" --limit set output entry limit\n"); printf(" --style select output style (0-4)\n"); printf(" --iflist [mode] show list of available interfaces\n"); printf(" --dbiflist [mode] show list of interfaces in database\n"); printf(" --dbdir select database directory\n"); printf(" --locale set locale\n"); printf(" --config select config file\n"); printf(" --showconfig dump config file with current settings\n"); printf(" --longhelp show this help\n\n"); printf("See also \"man vnstat\" for longer descriptions of each option.\n"); } void parseargs(PARAMS *p, int argc, char **argv) { int currentarg; /* parse parameters, maybe not the best way but... */ for (currentarg = 1; currentarg < argc; currentarg++) { if (debug) printf("arg %d: \"%s\"\n", currentarg, argv[currentarg]); if (strcmp(argv[currentarg], "--longhelp") == 0) { showlonghelp(p); exit(EXIT_SUCCESS); } else if ((strcmp(argv[currentarg], "-?") == 0) || (strcmp(argv[currentarg], "--help") == 0)) { showhelp(p); exit(EXIT_SUCCESS); } else if ((strcmp(argv[currentarg], "-i") == 0) || (strcmp(argv[currentarg], "--iface") == 0) || (strcmp(argv[currentarg], "--interface") == 0)) { if (currentarg + 1 < argc) { if (strlen(argv[currentarg + 1]) > 31) { printf("Error: Interface name is limited to 31 characters.\n"); exit(EXIT_FAILURE); } strncpy_nt(p->interface, argv[currentarg + 1], 32); if (strlen(p->interface)) { p->defaultiface = 0; } else { strncpy_nt(p->definterface, p->interface, 32); } if (debug) printf("Used interface: \"%s\"\n", p->interface); currentarg++; } else { printf("Error: Interface for %s missing.\n", argv[currentarg]); exit(EXIT_FAILURE); } } else if (strcmp(argv[currentarg], "--config") == 0) { /* config has already been parsed earlier so nothing to do here */ currentarg++; } else if (strcmp(argv[currentarg], "--setalias") == 0 || strcmp(argv[currentarg], "--nick") == 0) { if (strcmp(argv[currentarg], "--nick") == 0) { printf("Warning: --nick is deprecated and will be removed in a future release. Use --setalias instead.\n"); } if (currentarg + 1 < argc) { strncpy_nt(p->alias, argv[currentarg + 1], 32); if (debug) printf("Used alias: \"%s\"\n", p->alias); p->setalias = 1; currentarg++; } else { printf("Error: Alias for %s missing.\n", argv[currentarg]); exit(EXIT_FAILURE); } } else if ((strcmp(argv[currentarg], "--style")) == 0) { if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) { cfg.ostyle = atoi(argv[currentarg + 1]); if (cfg.ostyle > 4 || cfg.ostyle < 0) { printf("Error: Invalid style parameter \"%d\"\n", cfg.ostyle); showstylehelp(); exit(EXIT_FAILURE); } if (debug) printf("Style changed: %d\n", cfg.ostyle); currentarg++; } else { printf("Error: Style parameter for --style missing.\n"); showstylehelp(); exit(EXIT_FAILURE); } } else if ((strcmp(argv[currentarg], "--dbdir")) == 0) { if (currentarg + 1 < argc) { strncpy_nt(cfg.dbdir, argv[currentarg + 1], 512); if (debug) printf("DatabaseDir: \"%s\"\n", cfg.dbdir); currentarg++; } else { printf("Error: Directory for %s missing.\n", argv[currentarg]); exit(EXIT_FAILURE); } } else if ((strcmp(argv[currentarg], "--locale")) == 0) { if (currentarg + 1 < argc) { setlocale(LC_ALL, argv[currentarg + 1]); if (debug) printf("Locale: \"%s\"\n", argv[currentarg + 1]); currentarg++; } else { printf("Error: Locale for %s missing.\n", argv[currentarg]); exit(EXIT_FAILURE); } } else if (strcmp(argv[currentarg], "--add") == 0) { p->addiface = 1; p->query = 0; } else if ((strcmp(argv[currentarg], "-u") == 0) || (strcmp(argv[currentarg], "--update") == 0)) { printf("Error: The \"%s\" parameter is not supported in this version.\n", argv[currentarg]); exit(EXIT_FAILURE); } else if ((strcmp(argv[currentarg], "-q") == 0) || (strcmp(argv[currentarg], "--query") == 0)) { p->query = 1; } else if ((strcmp(argv[currentarg], "-D") == 0) || (strcmp(argv[currentarg], "--debug") == 0)) { debug = 1; } else if ((strcmp(argv[currentarg], "-d") == 0) || (strcmp(argv[currentarg], "--days") == 0)) { cfg.qmode = 1; if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) { cfg.listdays = atoi(argv[currentarg + 1]); if (cfg.listdays < 0) { printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]); exit(EXIT_FAILURE); } currentarg++; } } else if ((strcmp(argv[currentarg], "-m") == 0) || (strcmp(argv[currentarg], "--months") == 0)) { cfg.qmode = 2; if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) { cfg.listmonths = atoi(argv[currentarg + 1]); if (cfg.listmonths < 0) { printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]); exit(EXIT_FAILURE); } currentarg++; } } else if ((strcmp(argv[currentarg], "-t") == 0) || (strcmp(argv[currentarg], "--top") == 0)) { cfg.qmode = 3; if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) { cfg.listtop = atoi(argv[currentarg + 1]); if (cfg.listtop < 0) { printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]); exit(EXIT_FAILURE); } currentarg++; } } else if ((strcmp(argv[currentarg], "-s") == 0) || (strcmp(argv[currentarg], "--short") == 0)) { cfg.qmode = 5; } else if ((strcmp(argv[currentarg], "-y") == 0) || (strcmp(argv[currentarg], "--years") == 0)) { cfg.qmode = 6; if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) { cfg.listyears = atoi(argv[currentarg + 1]); if (cfg.listyears < 0) { printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]); exit(EXIT_FAILURE); } currentarg++; } } else if ((strcmp(argv[currentarg], "-hg") == 0) || (strcmp(argv[currentarg], "--hoursgraph") == 0)) { cfg.qmode = 7; } else if ((strcmp(argv[currentarg], "-h") == 0) || (strcmp(argv[currentarg], "--hours") == 0)) { cfg.qmode = 11; if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) { cfg.listhours = atoi(argv[currentarg + 1]); if (cfg.listhours < 0) { printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]); exit(EXIT_FAILURE); } currentarg++; } } else if ((strcmp(argv[currentarg], "-5") == 0) || (strcmp(argv[currentarg], "--fiveminutes") == 0)) { cfg.qmode = 12; if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) { cfg.listfivemins = atoi(argv[currentarg + 1]); if (cfg.listfivemins < 0) { printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]); exit(EXIT_FAILURE); } currentarg++; } } else if (strcmp(argv[currentarg], "--oneline") == 0) { cfg.qmode = 9; if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) { if (argv[currentarg + 1][0] == 'b') { cfg.ostyle = 4; currentarg++; } else { if (!ishelprequest(argv[currentarg + 1])) printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]); printf(" Valid parameters for --oneline:\n"); printf(" (none) - automatically scaled units visible\n"); printf(" b - all values in bytes\n"); exit(EXIT_FAILURE); } } } else if (strcmp(argv[currentarg], "--xml") == 0) { cfg.qmode = 8; if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) { p->xmlmode = argv[currentarg + 1][0]; if (strlen(argv[currentarg + 1]) != 1 || strchr("afhdmyt", p->xmlmode) == NULL) { if (!ishelprequest(argv[currentarg + 1])) printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]); printf(" Valid parameters for --xml:\n"); printf(" a - all (default)\n"); printf(" f - only 5 minutes\n"); printf(" h - only hours\n"); printf(" d - only days\n"); printf(" m - only months\n"); printf(" y - only years\n"); printf(" t - only top\n"); exit(EXIT_FAILURE); } currentarg++; } if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) { cfg.listjsonxml = atoi(argv[currentarg + 1]); if (cfg.listjsonxml < 0) { printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]); exit(EXIT_FAILURE); } currentarg++; } } else if (strcmp(argv[currentarg], "--json") == 0) { cfg.qmode = 10; if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) { p->jsonmode = argv[currentarg + 1][0]; if (strlen(argv[currentarg + 1]) != 1 || strchr("afhdmyt", p->jsonmode) == NULL) { if (!ishelprequest(argv[currentarg + 1])) printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]); printf(" Valid parameters for --json:\n"); printf(" a - all (default)\n"); printf(" f - only 5 minutes\n"); printf(" h - only hours\n"); printf(" d - only days\n"); printf(" m - only months\n"); printf(" y - only years\n"); printf(" t - only top\n"); exit(EXIT_FAILURE); } currentarg++; } if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) { cfg.listjsonxml = atoi(argv[currentarg + 1]); if (cfg.listjsonxml < 0) { printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]); exit(EXIT_FAILURE); } currentarg++; } } else if ((strcmp(argv[currentarg], "-ru") == 0) || (strcmp(argv[currentarg], "--rateunit")) == 0) { if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) { if (!isdigit(argv[currentarg + 1][0]) || atoi(argv[currentarg + 1]) > 1 || atoi(argv[currentarg + 1]) < 0) { if (!ishelprequest(argv[currentarg + 1])) printf("Error: Invalid parameter \"%s\".\n", argv[currentarg + 1]); printf(" Valid parameters for %s:\n", argv[currentarg]); printf(" 0 - bytes\n"); printf(" 1 - bits\n"); exit(EXIT_FAILURE); } cfg.rateunit = atoi(argv[currentarg + 1]); if (debug) printf("Rateunit changed: %d\n", cfg.rateunit); currentarg++; } else { cfg.rateunit = !cfg.rateunit; if (debug) printf("Rateunit changed: %d\n", cfg.rateunit); } } else if ((strcmp(argv[currentarg], "-tr") == 0) || (strcmp(argv[currentarg], "--traffic") == 0)) { if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) { cfg.sampletime = atoi(argv[currentarg + 1]); currentarg++; } p->traffic = 1; p->query = 0; } else if ((strcmp(argv[currentarg], "-l") == 0) || (strcmp(argv[currentarg], "--live") == 0)) { if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) { if (!isdigit(argv[currentarg + 1][0]) || atoi(argv[currentarg + 1]) > 1 || atoi(argv[currentarg + 1]) < 0) { if (!ishelprequest(argv[currentarg + 1])) printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]); printf(" Valid parameters for %s:\n", argv[currentarg]); printf(" 0 - show packets per second (default)\n"); printf(" 1 - show transfer counters\n"); exit(EXIT_FAILURE); } p->livemode = atoi(argv[currentarg + 1]); currentarg++; } p->livetraffic = 1; p->query = 0; } else if (strcmp(argv[currentarg], "--force") == 0) { p->force = 1; } else if (strcmp(argv[currentarg], "--showconfig") == 0) { printcfgfile(); exit(EXIT_SUCCESS); } else if (strcmp(argv[currentarg], "--remove") == 0) { p->removeiface = 1; p->query = 0; } else if (strcmp(argv[currentarg], "--rename") == 0) { if (currentarg + 1 < argc) { strncpy_nt(p->newifname, argv[currentarg + 1], 32); if (debug) printf("Given new interface name: \"%s\"\n", p->newifname); p->renameiface = 1; p->query = 0; currentarg++; } else { printf("Error: New interface name for %s missing.\n", argv[currentarg]); exit(EXIT_FAILURE); } } else if ((strcmp(argv[currentarg], "-b") == 0) || (strcmp(argv[currentarg], "--begin") == 0)) { if (currentarg + 1 < argc) { if (!validatedatetime(argv[currentarg + 1])) { printf("Error: Invalid date format, expected YYYY-MM-DD HH:MM or YYYY-MM-DD.\n"); exit(EXIT_FAILURE); } strncpy_nt(p->databegin, argv[currentarg + 1], 18); currentarg++; } else { printf("Error: Date of format YYYY-MM-DD HH:MM or YYYY-MM-DD for %s missing.\n", argv[currentarg]); exit(EXIT_FAILURE); } } else if ((strcmp(argv[currentarg], "-e") == 0) || (strcmp(argv[currentarg], "--end") == 0)) { if (currentarg + 1 < argc) { if (!validatedatetime(argv[currentarg + 1])) { printf("Error: Invalid date format, expected YYYY-MM-DD HH:MM or YYYY-MM-DD.\n"); exit(EXIT_FAILURE); } strncpy_nt(p->dataend, argv[currentarg + 1], 18); currentarg++; } else { printf("Error: Date of format YYYY-MM-DD HH:MM or YYYY-MM-DD for %s missing.\n", argv[currentarg]); exit(EXIT_FAILURE); } } else if (strcmp(argv[currentarg], "--iflist") == 0) { p->query = 0; if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) { if (!isdigit(argv[currentarg + 1][0]) || atoi(argv[currentarg + 1]) > 1 || atoi(argv[currentarg + 1]) < 0) { if (!ishelprequest(argv[currentarg + 1])) printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]); printf(" Valid parameters for --iflist:\n"); printf(" 0 - show verbose (default)\n"); printf(" 1 - show one interface per line\n"); exit(EXIT_FAILURE); } p->query = atoi(argv[currentarg + 1]); currentarg++; } showiflist(p->query); exit(EXIT_SUCCESS); } else if (strcmp(argv[currentarg], "--dbiflist") == 0) { p->query = 0; if (currentarg + 1 < argc && (strlen(argv[currentarg + 1]) == 1 || ishelprequest(argv[currentarg + 1]))) { if (!isdigit(argv[currentarg + 1][0]) || atoi(argv[currentarg + 1]) > 1 || atoi(argv[currentarg + 1]) < 0) { if (!ishelprequest(argv[currentarg + 1])) printf("Error: Invalid mode parameter \"%s\".\n", argv[currentarg + 1]); printf(" Valid parameters for --dbiflist:\n"); printf(" 0 - show verbose (default)\n"); printf(" 1 - show one interface per line\n"); exit(EXIT_FAILURE); } p->query = atoi(argv[currentarg + 1]); currentarg++; } showdbiflist(p->query); exit(EXIT_SUCCESS); } else if (strcmp(argv[currentarg], "--limit") == 0) { if (currentarg + 1 < argc && isdigit(argv[currentarg + 1][0])) { p->limit = atoi(argv[currentarg + 1]); if (p->limit < 0) { printf("Error: Invalid limit parameter \"%s\" for %s. Only a zero and positive numbers are allowed.\n", argv[currentarg + 1], argv[currentarg]); exit(EXIT_FAILURE); } currentarg++; } else { printf("Error: Invalid or missing parameter for %s.\n", argv[currentarg]); exit(EXIT_FAILURE); } } else if ((strcmp(argv[currentarg], "-v") == 0) || (strcmp(argv[currentarg], "--version") == 0)) { printf("vnStat %s by Teemu Toivola \n", getversion()); exit(EXIT_SUCCESS); } else { if (argv[currentarg][0] == '-' || strlen(argv[currentarg]) == 1) { printf("Unknown parameter \"%s\". Use --help for help.\n", argv[currentarg]); exit(EXIT_FAILURE); } else { if (strlen(argv[currentarg]) > 31) { printf("Error: Interface name is limited to 31 characters.\n"); exit(EXIT_FAILURE); } strncpy_nt(p->interface, argv[currentarg], 32); if (strlen(p->interface)) { p->defaultiface = 0; } else { strncpy_nt(p->definterface, p->interface, 32); } if (debug) printf("Used interface: \"%s\"\n", p->interface); } } } if (p->limit != -1) { cfg.listfivemins = cfg.listhours = cfg.listdays = cfg.listmonths = cfg.listyears = cfg.listtop = cfg.listjsonxml = p->limit; } } void showstylehelp(void) { printf(" Valid parameters for --style.:\n"); printf(" 0 - a more narrow output\n"); printf(" 1 - enable bar column if available\n"); printf(" 2 - average traffic rate in summary output\n"); printf(" 3 - average traffic rate in all outputs if available\n"); printf(" 4 - disable terminal control characters in -l / --live\n"); printf(" and show raw values in --oneline\n"); } void handleremoveinterface(PARAMS *p) { if (!p->removeiface) { return; } if (p->defaultiface) { printf("Error: Use -i parameter to specify an interface.\n"); exit(EXIT_FAILURE); } if (!db_getinterfacecountbyname(p->interface)) { printf("Error: Interface \"%s\" not found in database.\n", p->interface); exit(EXIT_FAILURE); } if (!p->force) { printf("Warning:\nThe current option would remove all data about interface \"%s\" from the database. ", p->interface); printf("Add --force in order to really do that.\n"); exit(EXIT_FAILURE); } #ifndef CHECK_VNSTAT if (!db_close() || !db_open_rw(0)) { printf("Error: Handling database \"%s/%s\" failing: %s\n", cfg.dbdir, DATABASEFILE, strerror(errno)); exit(EXIT_FAILURE); } #endif if (db_removeinterface(p->interface)) { printf("Interface \"%s\" removed from database.\n", p->interface); printf("The interface will no longer be monitored. Use --add if monitoring the interface is again needed.\n"); #ifndef CHECK_VNSTAT db_close(); exit(EXIT_SUCCESS); #endif } else { printf("Error: Removing interface \"%s\" from database failed.\n", p->interface); exit(EXIT_FAILURE); } } void handlerenameinterface(PARAMS *p) { if (!p->renameiface) { return; } if (p->defaultiface) { printf("Error: Use -i parameter to specify an interface.\n"); exit(EXIT_FAILURE); } if (!strlen(p->newifname)) { printf("Error: New interface name must be at least one character long.\n"); exit(EXIT_FAILURE); } if (!db_getinterfacecountbyname(p->interface)) { printf("Error: Interface \"%s\" not found in database.\n", p->interface); exit(EXIT_FAILURE); } if (db_getinterfacecountbyname(p->newifname)) { printf("Error: Interface \"%s\" already exists in database.\n", p->newifname); exit(EXIT_FAILURE); } if (!p->force) { printf("Warning:\nThe current option would rename interface \"%s\" -> \"%s\" in the database. ", p->interface, p->newifname); printf("Add --force in order to really do that.\n"); exit(EXIT_FAILURE); } #ifndef CHECK_VNSTAT if (!db_close() || !db_open_rw(0)) { printf("Error: Handling database \"%s/%s\" failing: %s\n", cfg.dbdir, DATABASEFILE, strerror(errno)); exit(EXIT_FAILURE); } #endif if (db_renameinterface(p->interface, p->newifname)) { printf("Interface \"%s\" has been renamed \"%s\".\n", p->interface, p->newifname); #ifndef CHECK_VNSTAT db_close(); exit(EXIT_SUCCESS); #endif } else { printf("Error: Renaming interface \"%s\" -> \"%s\" failed.\n", p->interface, p->newifname); exit(EXIT_FAILURE); } } void handleaddinterface(PARAMS *p) { if (!p->addiface) { return; } if (p->defaultiface) { printf("Error: Use -i parameter to specify an interface.\n"); exit(EXIT_FAILURE); } db_errcode = 0; if (db_getinterfacecountbyname(p->interface)) { printf("Error: Interface \"%s\" already exists in the database.\n", p->interface); exit(EXIT_FAILURE); } if (db_errcode) { exit(EXIT_FAILURE); } if (!p->force && !getifinfo(p->interface)) { getifliststring(&p->ifacelist, 1); printf("Only available interfaces can be added for monitoring.\n\n"); printf("The following interfaces are currently available:\n %s\n", p->ifacelist); free(p->ifacelist); exit(EXIT_FAILURE); } if (!p->force && !spacecheck(cfg.dbdir)) { printf("Error: Not enough free diskspace available.\n"); exit(EXIT_FAILURE); } #ifndef CHECK_VNSTAT if (!db_close() || !db_open_rw(0)) { printf("Error: Handling database \"%s/%s\" failing: %s\n", cfg.dbdir, DATABASEFILE, strerror(errno)); exit(EXIT_FAILURE); } #endif printf("Adding interface \"%s\" to database for monitoring.\n", p->interface); if (db_addinterface(p->interface)) { if (cfg.rescanonsave) { printf("vnStat daemon will automatically start monitoring \"%s\" within %d minutes if the daemon process is currently running.\n", p->interface, cfg.saveinterval); } else { printf("Restart vnStat daemon if it is currently running in order to start monitoring \"%s\".\n", p->interface); } handlesetalias(p); #ifndef CHECK_VNSTAT db_close(); exit(EXIT_SUCCESS); #endif } else { printf("Error: Adding interface \"%s\" to database failed.\n", p->interface); exit(EXIT_FAILURE); } } void handlesetalias(PARAMS *p) { if (!p->setalias) { return; } if (p->defaultiface) { printf("Error: Use -i parameter to specify an interface.\n"); exit(EXIT_FAILURE); } if (!db_getinterfacecountbyname(p->interface)) { printf("Error: Interface \"%s\" not found in database.\n", p->interface); exit(EXIT_FAILURE); } #ifndef CHECK_VNSTAT if (!db_close() || !db_open_rw(0)) { printf("Error: Handling database \"%s/%s\" failing: %s\n", cfg.dbdir, DATABASEFILE, strerror(errno)); exit(EXIT_FAILURE); } #endif if (db_setalias(p->interface, p->alias)) { printf("Alias of interface \"%s\" set to \"%s\".\n", p->interface, p->alias); #ifndef CHECK_VNSTAT db_close(); exit(EXIT_SUCCESS); #endif } else { printf("Error: Setting interface \"%s\" alias failed.\n", p->interface); exit(EXIT_FAILURE); } } void handleshowdata(PARAMS *p) { int ifcount = 0; iflist *dbifl = NULL, *dbifl_i = NULL; if (!p->query) { return; } /* show only specified file */ if (!p->defaultiface) { showoneinterface(p); return; } /* show all interfaces if -i isn't specified */ if (p->dbifcount == 0) { p->query = 0; } else if ((cfg.qmode == 0 || cfg.qmode == 8 || cfg.qmode == 10) && (p->dbifcount > 1)) { if (cfg.qmode == 0) { if (cfg.ostyle != 0) { printf("\n rx / tx / total / estimated\n"); } else { printf("\n rx / tx / total\n"); } } else if (cfg.qmode == 8) { xmlheader(); } else if (cfg.qmode == 10) { jsonheader(); } if (db_getiflist(&dbifl) <= 0) { return; } dbifl_i = dbifl; while (dbifl_i != NULL) { strncpy_nt(p->interface, dbifl_i->interface, 32); if (debug) printf("\nProcessing interface \"%s\"...\n", p->interface); if (cfg.qmode == 0) { showdb(p->interface, 5, "", ""); } else if (cfg.qmode == 8) { showxml(p->interface, p->xmlmode, p->databegin, p->dataend); } else if (cfg.qmode == 10) { showjson(p->interface, ifcount, p->jsonmode, p->databegin, p->dataend); } ifcount++; dbifl_i = dbifl_i->next; } iflistfree(&dbifl); if (cfg.qmode == 8) { xmlfooter(); } else if (cfg.qmode == 10) { jsonfooter(); } /* show in qmode if there's only one interface or qmode!=0 */ } else { showoneinterface(p); } } void showoneinterface(PARAMS *p) { if (!db_getinterfacecountbyname(p->interface)) { if (strchr(p->interface, '+') == NULL) { printf("Error: Interface \"%s\" not found in database.\n", p->interface); } else { printf("Error: Not all requested interfaces found in database or given interfaces aren't unique.\n"); } exit(EXIT_FAILURE); } if (cfg.qmode == 5) { if (cfg.ostyle != 0) { printf("\n rx / tx / total / estimated\n"); } else { printf("\n rx / tx / total\n"); } } if (cfg.qmode != 8 && cfg.qmode != 10) { showdb(p->interface, cfg.qmode, p->databegin, p->dataend); } else if (cfg.qmode == 8) { xmlheader(); showxml(p->interface, p->xmlmode, p->databegin, p->dataend); xmlfooter(); } else if (cfg.qmode == 10) { jsonheader(); showjson(p->interface, 0, p->jsonmode, p->databegin, p->dataend); jsonfooter(); } } void handletrafficmeters(PARAMS *p) { int i; if (!p->traffic && !p->livetraffic) { return; } if (strchr(p->interface, '+') != NULL) { printf("This feature doesn't support interface merges (\"%s\"), ", p->interface); for (i = 0; i < (int)strlen(p->interface); i++) { if (p->interface[i] == '+') { p->interface[i] = '\0'; break; } } p->defaultiface = 0; printf("using \"%s\" instead.\n", p->interface); } if (!isifavailable(p->interface)) { getifliststring(&p->ifacelist, 0); if (p->defaultiface) { printf("Error: Configured default interface \"%s\" isn't available.\n\n", p->interface); if (strlen(cfg.cfgfile)) { printf("Update \"Interface\" keyword value in configuration file \"%s\" to change ", cfg.cfgfile); printf("the default interface or give an alternative interface using the -i parameter.\n\n"); } else { printf("An alternative interface can be given using the -i parameter.\n\n"); } printf("The following interfaces are currently available:\n %s\n", p->ifacelist); } else { printf("Error: Unable to get interface \"%s\" statistics.\n\n", p->interface); printf("The following interfaces are currently available:\n %s\n", p->ifacelist); } free(p->ifacelist); exit(EXIT_FAILURE); } /* calculate traffic */ if (p->traffic) { trafficmeter(p->interface, (unsigned int)cfg.sampletime); } /* live traffic */ if (p->livetraffic) { livetrafficmeter(p->interface, p->livemode); } } void handleifselection(PARAMS *p) { int ifcount, dbifcount = 0, iffound = 0, dbopened = 0; iflist *ifl = NULL; iflist *dbifl = NULL, *dbifl_iterator = NULL; if (!p->defaultiface) { return; } if (strlen(p->definterface)) { strncpy_nt(p->interface, p->definterface, 32); return; } if (p->traffic || p->livetraffic) { ifcount = getiflist(&ifl, 0, 1); /* try to open database for extra information */ if (db == NULL) { if (!db_open_ro()) { db = NULL; } else { dbopened = 1; } } if (db != NULL) { dbifcount = db_getiflist_sorted(&dbifl, 1); if (dbopened) { db_close(); } } if (dbifcount > 0 && ifcount > 0) { dbifl_iterator = dbifl; while (dbifl_iterator != NULL) { if (iflistsearch(&ifl, dbifl_iterator->interface)) { strncpy_nt(p->interface, dbifl_iterator->interface, 32); iffound = 1; if (debug) printf("Automatically selected interface with db: \"%s\"\n", p->interface); break; } dbifl_iterator = dbifl_iterator->next; } } if (!iffound) { if (ifcount > 0) { strncpy_nt(p->interface, ifl->interface, 32); if (debug) printf("Automatically selected interface without db: \"%s\"\n", p->interface); } else { printf("Error: Unable to find any suitable interface.\n"); iflistfree(&ifl); iflistfree(&dbifl); exit(EXIT_FAILURE); } } iflistfree(&ifl); } else if (p->query) { if (db_getiflist_sorted(&dbifl, 1) <= 0) { printf("Error: Unable to discover suitable interface from database.\n"); iflistfree(&dbifl); exit(EXIT_FAILURE); } strncpy_nt(p->interface, dbifl->interface, 32); if (debug) printf("Automatically selected interface from db: \"%s\"\n", p->interface); } iflistfree(&dbifl); } void showiflist(const int parseable) { char *ifacelist = NULL; iflist *ifl = NULL, *ifl_iterator = NULL; if (!parseable) { if (!getifliststring(&ifacelist, 1)) { exit(EXIT_FAILURE); } if (strlen(ifacelist)) { printf("Available interfaces: %s\n", ifacelist); } else { printf("No usable interfaces found.\n"); } free(ifacelist); } else { if (!getiflist(&ifl, 0, 1)) { exit(EXIT_FAILURE); } ifl_iterator = ifl; while (ifl_iterator != NULL) { printf("%s\n", ifl_iterator->interface); ifl_iterator = ifl_iterator->next; } iflistfree(&ifl); } } void showdbiflist(const int parseable) { int dbifcount; iflist *dbifl = NULL, *dbifl_i = NULL; if (db == NULL && !db_open_ro()) { printf("Error: Failed to open database \"%s/%s\" in read-only mode.\n", cfg.dbdir, DATABASEFILE); exit(EXIT_FAILURE); } dbifcount = db_getiflist(&dbifl); if (dbifcount < 0) { printf("Error: Failed to get interface list from database \"%s/%s\".\n", cfg.dbdir, DATABASEFILE); exit(EXIT_FAILURE); } if (dbifcount == 0 && !parseable) { printf("Database is empty."); } else { dbifl_i = dbifl; if (!parseable) { printf("Interfaces in database:"); while (dbifl_i != NULL) { printf(" %s", dbifl_i->interface); dbifl_i = dbifl_i->next; } printf("\n"); } else { while (dbifl_i != NULL) { printf("%s\n", dbifl_i->interface); dbifl_i = dbifl_i->next; } } } iflistfree(&dbifl); db_close(); }