int opencfgfile(const char *cfgfile, FILE **fd) { char buffer[512]; int i, tryhome; /* clear buffer */ for (i=0; i<512; i++) { buffer[i] = '\0'; } cfg.cfgfile[0] = '\0'; /* possible config files: 1) --config 2) $HOME/.vnstatrc 3) /etc/vnstat.conf 4) none */ if (cfgfile[0]!='\0') { /* try to open given file */ if ((*fd=fopen(cfgfile, "r"))!=NULL) { strncpy_nt(cfg.cfgfile, cfgfile, 512); if (debug) printf("Config file: --config\n"); } else { snprintf(errorstring, 512, "Unable to open given config file \"%s\": %s\n", cfgfile, strerror(errno)); printe(PT_Error); return 0; } } else { if (getenv("HOME")) { strncpy_nt(buffer, getenv("HOME"), 500); strcat(buffer, "/.vnstatrc"); tryhome = 1; } else { tryhome = 0; } /* try to open first available config file */ if (tryhome && (*fd=fopen(buffer, "r"))!=NULL) { strncpy_nt(cfg.cfgfile, buffer, 512); } else if ((*fd=fopen("/etc/vnstat.conf", "r"))!=NULL) { snprintf(cfg.cfgfile, 512, "/etc/vnstat.conf"); } else if ((*fd=fopen("/usr/local/etc/vnstat.conf", "r"))!=NULL) { snprintf(cfg.cfgfile, 512, "/usr/local/etc/vnstat.conf"); } else { if (debug) printf("Config file: none\n"); return 1; } if (debug) printf("Config file: %s\n", cfg.cfgfile); } return 2; }
int readproc(const char *iface) { FILE *fp; char temp[4][64], procline[512], *proclineptr, ifaceid[33]; int check; if ((fp=fopen(PROCNETDEV, "r"))==NULL) { if (debug) printf("Error: Unable to read %s: %s\n", PROCNETDEV, strerror(errno)); return 0; } strncpy_nt(ifaceid, iface, 32); strcat(ifaceid, ":"); check = 0; while (fgets(procline, 512, fp)!=NULL) { sscanf(procline, "%63s", temp[0]); if (strncmp(ifaceid, temp[0], strlen(ifaceid))==0) { /* if (debug) printf("\n%s\n", procline); */ check = 1; break; } } fclose(fp); if (check==0) { if (debug) printf("Requested interface \"%s\" not found.\n", iface); return 0; } else { strncpy_nt(ifinfo.name, iface, 32); /* get rx and tx from procline */ proclineptr = strchr(procline, ':'); sscanf(proclineptr+1, "%63s %63s %*s %*s %*s %*s %*s %*s %63s %63s", temp[0], temp[1], temp[2], temp[3]); ifinfo.rx = strtoull(temp[0], (char **)NULL, 0); ifinfo.tx = strtoull(temp[2], (char **)NULL, 0); /* daemon doesn't need packet data */ if (!noexit) { ifinfo.rxp = strtoull(temp[1], (char **)NULL, 0); ifinfo.txp = strtoull(temp[3], (char **)NULL, 0); } ifinfo.filled = 1; } return 1; }
END_TEST START_TEST(strncpy_nt_with_over_maximum_length_string) { char dst[6]; strncpy_nt(dst, "123456", 6); ck_assert_str_eq(dst, "12345"); strncpy_nt(dst, "1234567890", 6); ck_assert_str_eq(dst, "12345"); }
void cachestatus(void) { char buffer[512]; int b = 13, count = 0; datanode *p = dataptr; snprintf(buffer, b, "Monitoring: "); if (p != NULL) { while (p != NULL) { if ((b+strlen(p->data.iface.interface)+1) < 508) { strncat(buffer, p->data.iface.interface, strlen(p->data.iface.interface)); strcat(buffer, " "); b = b+strlen(p->data.iface.interface)+1; } else { strcat(buffer, "..."); break; } count++; p = p->next; } } if (count) { strncpy_nt(errorstring, buffer, 512); errorstring[511] = '\0'; } else { snprintf(errorstring, 512, "Nothing to monitor"); } printe(PT_Info); }
int mergedb(char iface[], char dirname[]) { DATA mergedata; char *ifaceptr; if (!strstr(iface, "+")) { return 0; } /* create empty database */ emptydb(&mergedata); strncpy_nt(mergedata.iface.interface, iface, 32); strncpy_nt(mergedata.iface.nick, mergedata.iface.interface, 32); if (debug) printf("iface merge: %s\n", iface); ifaceptr = strtok(iface, "+"); /* merge all databases in given string */ while (ifaceptr != NULL) { if (debug) printf("merging %s:\n", ifaceptr); if (readdb(ifaceptr, dirname)!=0) { printf("Merge \"%s\" failed.\n", mergedata.iface.interface); return 0; } if (!mergewith(&mergedata)) { printf("Merge \"%s\" failed for interface \"%s\".\n", mergedata.iface.interface, ifaceptr); return 0; } ifaceptr = strtok(NULL, "+"); } /* clean possible glitches */ cleanmerged(&mergedata); /* replace active data with merged */ if (memcpy(&data, &mergedata, sizeof(data)) != NULL) { return 1; } else { return 0; } }
END_TEST START_TEST(strncpy_nt_with_below_maximum_length_string) { char dst[6]; strncpy_nt(dst, "123", 6); ck_assert_str_eq(dst, "123"); }
int ibwadd(const char *iface, int limit) { ibwnode *n, *p = ifacebw; /* add new node if list is empty */ if (p == NULL) { n = malloc(sizeof(ibwnode)); if (n == NULL) { return 0; } n->next = ifacebw; ifacebw = n; strncpy_nt(n->interface, iface, 32); n->limit = limit; } else { /* update previous value if already in list */ while (p != NULL) { if (strcmp(p->interface, iface)==0) { p->limit = limit; return 1; } p = p->next; } /* add new node if not found */ n = malloc(sizeof(ibwnode)); if (n == NULL) { return 0; } n->next = ifacebw; ifacebw = n; strncpy_nt(n->interface, iface, 32); n->limit = limit; } return 1; }
char *getversion(void) { int i; static char versionbuffer[16]; strncpy_nt(versionbuffer, VERSION, 16); for (i=0; i<(int)strlen(versionbuffer); i++) { if (versionbuffer[i] == '_') { versionbuffer[i] = ' '; } } return versionbuffer; }
int getifinfo(const char *iface) { char inface[32]; ifinfo.filled = 0; if (strcmp(iface, "default")==0) { strncpy_nt(inface, cfg.iface, 32); } else { strncpy_nt(inface, iface, 32); } #if defined(__linux__) /* try getting interface info from /proc */ if (readproc(inface)!=1) { if (debug) printf("Failed to use %s as source.\n", PROCNETDEV); /* try getting interface info from /sys */ if (readsysclassnet(inface)!=1) { snprintf(errorstring, 512, "Unable to get interface \"%s\" statistics.", inface); printe(PT_Error); return 0; } } #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) if (readifaddrs(inface)!=1) { snprintf(errorstring, 512, "Unable to get interface \"%s\" statistics.", inface); printe(PT_Error); return 0; } #else return 0; #endif return 1; }
int setcfgvalue(struct cfgsetting *cset, const char *value, const char *cfgline) { if (cset->namelen>0) { strncpy_nt(cset->locc, value, cset->namelen); cset->locc[cset->namelen-1]='\0'; if (debug) printf(" c: %s -> \"%s\": \"%s\"\n", cfgline, cset->name, cset->locc); } else if (isdigit(value[0])) { *cset->loci = strtol(value, (char **)NULL, 0); if (debug) printf(" i: %s -> \"%s\": %d\n", cfgline, cset->name, *cset->loci); } else { return 0; } return 1; }
int readifaddrs(const char *iface) { struct if_data ifd; if (!getifdata(iface, &ifd)) { if (debug) printf("Requested interface \"%s\" not found.\n", iface); return 0; } else { strncpy_nt(ifinfo.name, iface, 32); ifinfo.rx = ifd.ifi_ibytes; ifinfo.tx = ifd.ifi_obytes; ifinfo.rxp = ifd.ifi_ipackets; ifinfo.txp = ifd.ifi_opackets; ifinfo.filled = 1; } return 1; }
void handleintsignals(DSTATE *s) { switch (intsignal) { case SIGHUP: snprintf(errorstring, 512, "SIGHUP received, flushing data to disk and reloading config."); printe(PT_Info); cacheflush(s->dirname); s->dbcount = 0; ibwflush(); if (loadcfg(s->cfgfile)) { strncpy_nt(s->dirname, cfg.dbdir, 512); } ibwloadcfg(s->cfgfile); break; case SIGINT: snprintf(errorstring, 512, "SIGINT received, exiting."); printe(PT_Info); s->running = 0; break; case SIGTERM: snprintf(errorstring, 512, "SIGTERM received, exiting."); printe(PT_Info); s->running = 0; break; case 42: break; case 0: break; default: snprintf(errorstring, 512, "Unkown signal %d received, ignoring.", intsignal); printe(PT_Info); break; } intsignal = 0; }
int datacache_add(datacache **dc, const char *interface, const short sync) { datacache *newdc; newdc = malloc(sizeof(datacache)); if (newdc == NULL) { return 0; } newdc->next = *dc; *dc = newdc; strncpy_nt((*dc)->interface, interface, 32); (*dc)->active = 1; (*dc)->filled = 0; (*dc)->syncneeded = sync; (*dc)->currx = 0; (*dc)->curtx = 0; (*dc)->updated = time(NULL); (*dc)->log = NULL; return 1; }
int cacheadd(const char *iface, int sync) { datanode *p, *n; p = dataptr; /* skip if already in list */ while (p != NULL) { if (strcmp(p->data.iface.interface, iface)==0) { if (debug) { printf("cache: %s already cached\n", iface); } return 1; } p = p->next; } /* add new node if not in list */ n = malloc(sizeof(datanode)); if (n == NULL) { return 0; } n->next = dataptr; dataptr = n; strncpy_nt(n->data.iface.interface, iface, 32); n->data.iface.interface[31] = '\0'; n->data.iface.active = 1; n->filled = 0; n->sync = sync; if (debug) { printf("cache: %s added\n", iface); } return 1; }
int iflistadd(iflist **ifl, const char *iface, const uint32_t bandwidth) { iflist *newif; newif = malloc(sizeof(iflist)); if (newif == NULL) { return 0; } newif->next = *ifl; newif->prev = NULL; if (*ifl != NULL) { (*ifl)->prev = newif; } *ifl = newif; strncpy_nt(newif->interface, iface, 32); newif->bandwidth = bandwidth; return 1; }
int addinterfaces(const char *dirname) { char *ifacelist, interface[32]; int index = 0, count = 0, bwlimit = 0; /* get list of currently visible interfaces */ if (getiflist(&ifacelist)==0) { free(ifacelist); return 0; } if (strlen(ifacelist)<2) { free(ifacelist); return 0; } if (debug) printf("Interface list: \"%s\"\n", ifacelist); while (sscanf(ifacelist+index, "%31s", interface)!=EOF) { if (debug) printf("Processing: \"%s\"\n", interface); index += strlen(interface)+1; /* skip local interfaces */ if ((strcmp(interface,"lo")==0) || (strcmp(interface,"lo0")==0) || (strcmp(interface,"sit0")==0)) { if (debug) printf("skip\n"); continue; } /* create database for interface */ initdb(); strncpy_nt(data.interface, interface, 32); strncpy_nt(data.nick, data.interface, 32); if (!getifinfo(interface)) { if (debug) printf("getifinfo failed, skip\n"); continue; } parseifinfo(1); if (!writedb(interface, dirname, 1)) { continue; } count++; bwlimit = ibwget(interface); if (bwlimit > 0) { printf("\"%s\" added with %d Mbit bandwidth limit.\n", interface, bwlimit); } else { printf("\"%s\" added. Warning: no bandwidth limit has been set.\n", interface); } } if (count==1) { printf("-> %d interface added.", count); } else { printf("-> %d interfaces added.", count); } if (count) { printf("\nLimits can be modified using the configuration file. See \"man vnstat.conf\".\n"); printf("Unwanted interfaces can be removed from monitoring with \"vnstat --delete\"."); } printf("\n"); free(ifacelist); return count; }
int readdb(const char *iface, const char *dirname) { FILE *db; char file[512], backup[512]; snprintf(file, 512, "%s/%s", dirname, iface); snprintf(backup, 512, "%s/.%s", dirname, iface); if ((db=fopen(file,"r"))==NULL) { snprintf(errorstring, 512, "Unable to read database \"%s\": %s", file, strerror(errno)); printe(PT_Error); /* create new database template */ initdb(); strncpy_nt(data.interface, iface, 32); strncpy_nt(data.nick, data.interface, 32); return 1; } /* lock file */ if (!lockdb(fileno(db), 0)) { fclose(db); return -1; } if (fread(&data,sizeof(DATA),1,db)==0) { data.version=-1; if (debug) { printf("db: Database read failed for file \"%s\".\n", file); } } else { if (debug) { printf("db: Database loaded for interface \"%s\"...\n", data.interface); } } /* convert old database to new format if necessary */ if (data.version<DBVERSION) { if (data.version!=-1) { snprintf(errorstring, 512, "Trying to convert database \"%s\" (v%d) to current db format", file, data.version); printe(PT_Info); } if ((data.version==-1) || (!convertdb())) { /* close current db and try using backup if database conversion failed */ fclose(db); if ((db=fopen(backup,"r"))==NULL) { snprintf(errorstring, 512, "Unable to open backup database \"%s\": %s", backup, strerror(errno)); printe(PT_Error); if (noexit) { return -1; } else { exit(EXIT_FAILURE); } } /* lock file */ if (!lockdb(fileno(db), 0)) { fclose(db); return -1; } if (fread(&data,sizeof(DATA),1,db)==0) { snprintf(errorstring, 512, "Database load failed even when using backup (%s). Aborting.", strerror(errno)); printe(PT_Error); fclose(db); if (noexit) { return -1; } else { exit(EXIT_FAILURE); } } else { if (debug) { printf("db: Database loaded for interface \"%s\"...\n", data.interface); } } if (data.version!=DBVERSION) { if (!convertdb()) { snprintf(errorstring, 512, "Unable to use backup database."); printe(PT_Error); fclose(db); if (noexit) { return -1; } else { exit(EXIT_FAILURE); } } } snprintf(errorstring, 512, "Database possibly corrupted, using backup instead."); printe(PT_Info); } } else if (data.version>DBVERSION) { snprintf(errorstring, 512, "Downgrading database \"%s\" (v%d) is not supported.", file, data.version); printe(PT_Error); fclose(db); if (noexit) { return -1; } else { exit(EXIT_FAILURE); } } fclose(db); if (strcmp(data.interface,iface)) { snprintf(errorstring, 512, "Warning:\nThe previous interface for this file was \"%s\".",data.interface); printe(PT_Multiline); snprintf(errorstring, 512, "It has now been replaced with \"%s\".",iface); printe(PT_Multiline); snprintf(errorstring, 512, "You can ignore this message if you renamed the filename."); printe(PT_Multiline); snprintf(errorstring, 512, "Interface name mismatch, renamed \"%s\" -> \"%s\"", data.interface, iface); printe(PT_ShortMultiline); if (strcmp(data.interface, data.nick)==0) { strncpy_nt(data.nick, iface, 32); } strncpy_nt(data.interface, iface, 32); } return 0; }
int readsysclassnet(const char *iface) { FILE *fp; char path[64], file[76], buffer[64]; strncpy_nt(ifinfo.name, iface, 32); snprintf(path, 64, "%s/%s/statistics", SYSCLASSNET, iface); if (debug) printf("path: %s\n", path); /* rx bytes */ snprintf(file, 76, "%s/rx_bytes", path); if ((fp=fopen(file, "r"))==NULL) { if (debug) printf("Unable to read: %s - %s\n", file, strerror(errno)); return 0; } else { if (fgets(buffer, 64, fp)!=NULL) { ifinfo.rx = strtoull(buffer, (char **)NULL, 0); } else { fclose(fp); return 0; } } fclose(fp); /* tx bytes */ snprintf(file, 76, "%s/tx_bytes", path); if ((fp=fopen(file, "r"))==NULL) { if (debug) printf("Unable to read: %s - %s\n", file, strerror(errno)); return 0; } else { if (fgets(buffer, 64, fp)!=NULL) { ifinfo.tx = strtoull(buffer, (char **)NULL, 0); } else { fclose(fp); return 0; } } fclose(fp); /* daemon doesn't need packet data */ if (!noexit) { /* rx packets */ snprintf(file, 76, "%s/rx_packets", path); if ((fp=fopen(file, "r"))==NULL) { if (debug) printf("Unable to read: %s - %s\n", file, strerror(errno)); return 0; } else { if (fgets(buffer, 64, fp)!=NULL) { ifinfo.rxp = strtoull(buffer, (char **)NULL, 0); } else { fclose(fp); return 0; } } fclose(fp); /* tx packets */ snprintf(file, 76, "%s/tx_packets", path); if ((fp=fopen(file, "r"))==NULL) { if (debug) printf("Unable to read: %s - %s\n", file, strerror(errno)); return 0; } else { if (fgets(buffer, 64, fp)!=NULL) { ifinfo.txp = strtoull(buffer, (char **)NULL, 0); } else { fclose(fp); return 0; } } fclose(fp); } ifinfo.filled = 1; return 1; }
int readdb(DATA *data, const char *iface, const char *dirname, const int force) { FILE *legacydb; char file[512], backup[512]; snprintf(file, 512, "%s/%s", dirname, iface); snprintf(backup, 512, "%s/.%s", dirname, iface); if ((legacydb = fopen(file, "r")) == NULL) { snprintf(errorstring, 1024, "Unable to read database \"%s\": %s", file, strerror(errno)); printe(PT_Error); /* create new database template */ initdb(data); strncpy_nt(data->interface, iface, 32); strncpy_nt(data->nick, data->interface, 32); return 1; } if (fread(data, sizeof(DATA), 1, legacydb) != 1 || ferror(legacydb)) { data->version = -1; if (debug) { printf("db: Database read failed for file \"%s\".\n", file); } } else { if (debug) { data->interface[sizeof(data->interface) - 1] = '\0'; printf("db: Database loaded for interface \"%s\"...\n", data->interface); } } data->interface[sizeof(data->interface) - 1] = '\0'; data->nick[sizeof(data->nick) - 1] = '\0'; if (data->version == LEGACYDBVERSION) { if (!validatedb(data) && !force) { data->version = -1; if (debug) { printf("db: Database for interface \"%s\" fails to validate, trying with backup\n", data->interface); } } } /* convert old database to new format if necessary */ if (data->version < LEGACYDBVERSION) { if (data->version == -1) { /* close current db and try using backup if database conversion failed */ fclose(legacydb); if ((legacydb = fopen(backup, "r")) == NULL) { snprintf(errorstring, 1024, "Unable to open backup database \"%s\": %s", backup, strerror(errno)); printe(PT_Error); if (noexit) { return -1; } else { exit(EXIT_FAILURE); } } if (fread(data, sizeof(DATA), 1, legacydb) != 1 || ferror(legacydb)) { snprintf(errorstring, 1024, "Database load failed even when using backup (%s). Aborting.", strerror(errno)); printe(PT_Error); fclose(legacydb); if (noexit) { return -1; } else { exit(EXIT_FAILURE); } } else { if (debug) { data->interface[sizeof(data->interface) - 1] = '\0'; printf("db: Backup database loaded for interface \"%s\"...\n", data->interface); } } data->interface[sizeof(data->interface) - 1] = '\0'; data->nick[sizeof(data->nick) - 1] = '\0'; if (data->version == LEGACYDBVERSION) { if (!validatedb(data)) { data->version = -1; if (debug) { printf("db: Backup database for interface \"%s\" fails to validate\n", data->interface); } } } if (data->version != LEGACYDBVERSION) { if (data->version == -1) { snprintf(errorstring, 1024, "Unable to use database \"%s\" or its backup.", file); printe(PT_Error); fclose(legacydb); if (noexit) { return -1; } else { exit(EXIT_FAILURE); } } } snprintf(errorstring, 1024, "Database possibly corrupted, using backup instead."); printe(PT_Info); } } else if (data->version > LEGACYDBVERSION) { snprintf(errorstring, 1024, "Downgrading database \"%s\" (v%d) is not supported.", file, data->version); printe(PT_Error); fclose(legacydb); if (noexit) { return -1; } else { exit(EXIT_FAILURE); } } fclose(legacydb); if (strcmp(data->interface, iface)) { snprintf(errorstring, 1024, "Warning:\nThe previous interface for this file was \"%s\".", data->interface); printe(PT_Multiline); snprintf(errorstring, 1024, "It has now been replaced with \"%s\".", iface); printe(PT_Multiline); snprintf(errorstring, 1024, "You can ignore this message if you renamed the filename."); printe(PT_Multiline); snprintf(errorstring, 1024, "Interface name mismatch, renamed \"%s\" -> \"%s\"", data->interface, iface); printe(PT_ShortMultiline); if (strcmp(data->interface, data->nick) == 0) { strncpy_nt(data->nick, iface, 32); } strncpy_nt(data->interface, iface, 32); } return 0; }
int main(int argc, char *argv[]) { int i, currentarg; DIR *dir = NULL; struct dirent *di = NULL; PARAMS p; initparams(&p); /* early check for debug and config parameter */ if (argc > 1) { for (currentarg=1; currentarg<argc; currentarg++) { if ((strcmp(argv[currentarg],"-D")==0) || (strcmp(argv[currentarg],"--debug")==0)) { debug = 1; } else if (strcmp(argv[currentarg],"--config")==0) { if (currentarg+1<argc) { strncpy_nt(p.cfgfile, argv[currentarg+1], 512); if (debug) printf("Used config file: %s\n", p.cfgfile); currentarg++; continue; } else { printf("Error: File for --config missing.\n"); return 1; } } } } /* load config if available */ if (!loadcfg(p.cfgfile)) { return 1; } if (!ibwloadcfg(p.cfgfile)) { return 1; } configlocale(); strncpy_nt(p.interface, "default", 32); strncpy_nt(p.definterface, cfg.iface, 32); strncpy_nt(p.nick, "none", 32); /* init dirname */ strncpy_nt(p.dirname, cfg.dbdir, 512); /* 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); return 0; } else if ((strcmp(argv[currentarg],"-?")==0) || (strcmp(argv[currentarg],"--help")==0)) { showhelp(&p); return 0; } else if ((strcmp(argv[currentarg],"-i")==0) || (strcmp(argv[currentarg],"--iface")==0)) { if (currentarg+1<argc) { strncpy_nt(p.interface, argv[currentarg+1], 32); p.defaultiface = 0; if (debug) printf("Used interface: %s\n", p.interface); currentarg++; continue; } else { printf("Error: Interface for -i missing.\n"); return 1; } } else if (strcmp(argv[currentarg],"--config")==0) { /* config has already been parsed earlier so nothing to do here */ currentarg++; continue; } else if ((strcmp(argv[currentarg],"--nick"))==0) { if (currentarg+1<argc) { strncpy_nt(p.nick, argv[currentarg+1], 32); if (debug) printf("Used nick: %s\n", p.nick); currentarg++; continue; } else { printf("Error: Nick for --nick missing.\n"); return 1; } } else if ((strcmp(argv[currentarg],"--style"))==0) { if (currentarg+1<argc && isdigit(argv[currentarg+1][0])) { if (cfg.ostyle > 4 || cfg.ostyle < 0) { printf("Error: Invalid style parameter \"%d\" for --style.\n", cfg.ostyle); printf(" Valid parameters:\n"); printf(" 0 - a more narrow output\n"); printf(" 1 - enable bar column if available\n"); printf(" 2 - average traffic rate in summary and weekly outputs\n"); printf(" 3 - average traffic rate in all outputs if available\n"); printf(" 4 - disable terminal control characters in -l / --live\n"); return 1; } cfg.ostyle = atoi(argv[currentarg+1]); if (debug) printf("Style changed: %d\n", cfg.ostyle); currentarg++; continue; } else { printf("Error: Style parameter for --style missing.\n"); printf(" Valid parameters:\n"); printf(" 0 - a more narrow output\n"); printf(" 1 - enable bar column if available\n"); printf(" 2 - average traffic rate in summary and weekly outputs\n"); printf(" 3 - average traffic rate in all outputs if available\n"); printf(" 4 - disable terminal control characters in -l / --live\n"); return 1; } } else if ((strcmp(argv[currentarg],"--dbdir"))==0) { if (currentarg+1<argc) { strncpy_nt(p.dirname, argv[currentarg+1], 512); if (debug) printf("DatabaseDir: \"%s\"\n", p.dirname); currentarg++; continue; } else { printf("Error: Directory for --dbdir missing.\n"); return 1; } } 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++; continue; } else { printf("Error: Locale for --locale missing.\n"); return 1; } } else if (strcmp(argv[currentarg],"--create")==0) { p.create=1; p.query=0; if (debug) printf("Creating database...\n"); } else if ((strcmp(argv[currentarg],"-u")==0) || (strcmp(argv[currentarg],"--update")==0)) { p.update=1; p.query=0; if (debug) printf("Updating database...\n"); } else if (strcmp(argv[currentarg],"--importdb")==0) { if (currentarg+1<argc) { p.import=1; strncpy_nt(p.filename, argv[currentarg+1], 512); if (debug) printf("Used import file: %s\n", p.filename); currentarg++; continue; } else { printf("Error: File parameter for --importdb missing.\n"); return 1; } } 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; } else if ((strcmp(argv[currentarg],"-m")==0) || (strcmp(argv[currentarg],"--months")==0)) { cfg.qmode=2; } else if ((strcmp(argv[currentarg],"-t")==0) || (strcmp(argv[currentarg],"--top10")==0)) { cfg.qmode=3; } else if ((strcmp(argv[currentarg],"-s")==0) || (strcmp(argv[currentarg],"--short")==0)) { cfg.qmode=5; } else if ((strcmp(argv[currentarg],"-w")==0) || (strcmp(argv[currentarg],"--weeks")==0)) { cfg.qmode=6; } else if ((strcmp(argv[currentarg],"-h")==0) || (strcmp(argv[currentarg],"--hours")==0)) { cfg.qmode=7; } else if ((strcmp(argv[currentarg],"--exportdb")==0) || (strcmp(argv[currentarg],"--dumpdb")==0)) { cfg.qmode=4; } else if (strcmp(argv[currentarg],"--oneline")==0) { cfg.qmode=9; } else if (strcmp(argv[currentarg],"--xml")==0) { if (currentarg+1<argc && argv[currentarg+1][0]!='-') { p.xmlmode = argv[currentarg+1][0]; if (strlen(argv[currentarg+1])!=1 || strchr("ahdmt", p.xmlmode)==NULL) { printf("Error: Invalid mode parameter \"%s\" for --xml.\n", argv[currentarg+1]); printf(" Valid parameters:\n"); printf(" a - all (default)\n"); printf(" h - only hours\n"); printf(" d - only days\n"); printf(" m - only months\n"); printf(" t - only top 10\n"); return 1; } currentarg++; } cfg.qmode=8; } else if (strcmp(argv[currentarg],"--json")==0) { if (currentarg+1<argc && argv[currentarg+1][0]!='-') { p.jsonmode = argv[currentarg+1][0]; if (strlen(argv[currentarg+1])!=1 || strchr("ahdmt", p.jsonmode)==NULL) { printf("Error: Invalid mode parameter \"%s\" for --json.\n", argv[currentarg+1]); printf(" Valid parameters:\n"); printf(" a - all (default)\n"); printf(" h - only hours\n"); printf(" d - only days\n"); printf(" m - only months\n"); printf(" t - only top 10\n"); return 1; } currentarg++; } cfg.qmode=10; } else if (strcmp(argv[currentarg],"--savemerged")==0) { p.savemerged=1; } else if ((strcmp(argv[currentarg],"-ru")==0) || (strcmp(argv[currentarg],"--rateunit"))==0) { if (currentarg+1<argc && isdigit(argv[currentarg+1][0])) { if (cfg.rateunit > 1 || cfg.rateunit < 0) { printf("Error: Invalid parameter \"%d\" for --rateunit.\n", cfg.rateunit); printf(" Valid parameters:\n"); printf(" 0 - bytes\n"); printf(" 1 - bits\n"); return 1; } cfg.rateunit = atoi(argv[currentarg+1]); if (debug) printf("Rateunit changed: %d\n", cfg.rateunit); currentarg++; continue; } else { cfg.rateunit = !cfg.rateunit; if (debug) printf("Rateunit changed: %d\n", cfg.rateunit); } } else if (strcmp(argv[currentarg],"--enable")==0) { p.active=1; p.query=0; } 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; continue; } p.traffic=1; p.query=0; } else if ((strcmp(argv[currentarg],"-l")==0) || (strcmp(argv[currentarg],"--live")==0)) { if (currentarg+1<argc && argv[currentarg+1][0]!='-') { if (!isdigit(argv[currentarg+1][0]) || p.livemode > 1 || p.livemode < 0) { printf("Error: Invalid mode parameter \"%s\" for -l / --live.\n", argv[currentarg+1]); printf(" Valid parameters:\n"); printf(" 0 - show packets per second (default)\n"); printf(" 1 - show transfer counters\n"); return 1; } 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],"--cleartop")==0) { p.cleartop=1; } else if (strcmp(argv[currentarg],"--rebuildtotal")==0) { p.rebuildtotal=1; } else if (strcmp(argv[currentarg],"--disable")==0) { p.active=0; p.query=0; } else if (strcmp(argv[currentarg],"--testkernel")==0) { i=kerneltest(); return i; } else if (strcmp(argv[currentarg],"--showconfig")==0) { printcfgfile(); return 0; } else if (strcmp(argv[currentarg],"--delete")==0) { p.delete=1; p.query=0; } else if (strcmp(argv[currentarg],"--iflist")==0) {
int loadcfg(const char *cfgfile) { FILE *fd; char buffer[512]; int i, j, k, linelen, cfglen, tryhome; char value[512], cfgline[512]; struct cfgsetting cset[] = { /* cfg string, char var name, int var name, char len, fill status */ { "Interface", cfg.iface, 0, 32, 0 }, { "DatabaseDir", cfg.dbdir, 0, 512, 0 }, { "Locale", cfg.locale, 0, 32, 0 }, { "MonthRotate", 0, &cfg.monthrotate, 0, 0 }, { "DayFormat", cfg.dformat, 0, 64, 0 }, { "MonthFormat", cfg.mformat, 0, 64, 0 }, { "TopFormat", cfg.tformat, 0, 64, 0 }, { "RXCharacter", cfg.rxchar, 0, 2, 0 }, { "TXCharacter", cfg.txchar, 0, 2, 0 }, { "RXHourCharacter", cfg.rxhourchar, 0, 2, 0 }, { "TXHourCharacter", cfg.txhourchar, 0, 2, 0 }, { "UnitMode", 0, &cfg.unit, 0, 0 }, { "OutputStyle", 0, &cfg.ostyle, 0, 0 }, { "RateUnit", 0, &cfg.rateunit, 0, 0 }, { "MaxBandwidth", 0, &cfg.maxbw, 0, 0 }, { "Sampletime", 0, &cfg.sampletime, 0, 0 }, { "QueryMode", 0, &cfg.qmode, 0, 0 }, { "CheckDiskSpace", 0, &cfg.spacecheck, 0, 0 }, { "UseFileLocking", 0, &cfg.flock, 0, 0 }, { "BootVariation", 0, &cfg.bvar, 0, 0 }, { "TrafficlessDays", 0, &cfg.traflessday, 0, 0 }, { "DaemonUser", cfg.daemonuser, 0, 33, 0 }, { "DaemonGroup", cfg.daemongroup, 0, 33, 0 }, { "UpdateInterval", 0, &cfg.updateinterval, 0, 0 }, { "PollInterval", 0, &cfg.pollinterval, 0, 0 }, { "SaveInterval", 0, &cfg.saveinterval, 0, 0 }, { "OfflineSaveInterval", 0, &cfg.offsaveinterval, 0, 0 }, { "SaveOnStatusChange", 0, &cfg.savestatus, 0, 0 }, { "UseLogging", 0, &cfg.uselogging, 0, 0 }, { "CreateDirs", 0, &cfg.createdirs, 0, 0 }, { "UpdateFileOwner", 0, &cfg.updatefileowner, 0, 0 }, { "LogFile", cfg.logfile, 0, 512, 0 }, { "PidFile", cfg.pidfile, 0, 512, 0 }, { "HeaderFormat", cfg.hformat, 0, 64, 0 }, { "HourlyRate", 0, &cfg.hourlyrate, 0, 0 }, { "SummaryRate", 0, &cfg.summaryrate, 0, 0 }, { "SummaryLayout", 0, &cfg.slayout, 0, 0 }, { "TransparentBg", 0, &cfg.transbg, 0, 0 }, { "CBackground", cfg.cbg, 0, 8, 0 }, { "CEdge", cfg.cedge, 0, 8, 0 }, { "CHeader", cfg.cheader, 0, 8, 0 }, { "CHeaderTitle", cfg.cheadertitle, 0, 8, 0 }, { "CHeaderDate", cfg.cheaderdate, 0, 8, 0 }, { "CText", cfg.ctext, 0, 8, 0 }, { "CLine", cfg.cline, 0, 8, 0 }, { "CLineL", cfg.clinel, 0, 8, 0 }, { "CRx", cfg.crx, 0, 8, 0 }, { "CRxD", cfg.crxd, 0, 8, 0 }, { "CTx", cfg.ctx, 0, 8, 0 }, { "CTxD", cfg.ctxd, 0, 8, 0 }, { 0, 0, 0, 0, 0 } }; ifacebw = NULL; /* clear buffer */ for (i=0; i<512; i++) { buffer[i] = '\0'; } /* load default config */ defaultcfg(); /* possible config files: 1) --config 2) $HOME/.vnstatrc 3) /etc/vnstat.conf 4) none */ if (cfgfile[0]!='\0') { /* try to open given file */ if ((fd=fopen(cfgfile, "r"))!=NULL) { if (debug) printf("Config file: --config\n"); } else { snprintf(errorstring, 512, "Unable to open given config file \"%s\": %s\n", cfgfile, strerror(errno)); printe(PT_Error); return 0; } } else { if (getenv("HOME")) { strncpy_nt(buffer, getenv("HOME"), 500); strcat(buffer, "/.vnstatrc"); tryhome = 1; } else { tryhome = 0; } /* try to open first available config file */ if (tryhome && (fd=fopen(buffer, "r"))!=NULL) { if (debug) printf("Config file: $HOME/.vnstatrc\n"); } else if ((fd=fopen("/etc/vnstat.conf", "r"))!=NULL) { if (debug) printf("Config file: /etc/vnstat.conf\n"); } else { if (debug) printf("Config file: none\n"); return 1; } } rewind(fd); /* parse every config file line */ while (!feof(fd)) { cfgline[0] = '\0'; /* get current line */ if (fgets(cfgline, 512, fd)==NULL) { break; } linelen = (int)strlen(cfgline); if (linelen>2 && cfgline[0]!='#') { for (i=0; cset[i].name!=0; i++) { if (cset[i].found) { continue; } cfglen = (int)strlen(cset[i].name); if ( (linelen>=(cfglen+2)) && (strncasecmp(cfgline, cset[i].name, cfglen)==0) ) { /* clear value buffer */ for (j=0; j<512; j++) { value[j]='\0'; } /* search value */ j = 0; for (k=cfglen; k<linelen; k++) { if (cfgline[k]=='\n' || cfgline[k]=='\r') { break; } else if (cfgline[k]=='\"') { if (j==0) { continue; } else { break; } } else { if (j==0 && (cfgline[k]==' ' || cfgline[k]=='=' || cfgline[k]=='\t')) { continue; } else { value[j] = cfgline[k]; j++; } } } /* set value and get new line if valid value was found */ if (strlen(value)!=0) { if (cset[i].namelen>0) { strncpy_nt(cset[i].locc, value, cset[i].namelen); cset[i].locc[cset[i].namelen-1]='\0'; if (debug) printf(" c: %s -> \"%s\": \"%s\"\n", cfgline, cset[i].name, cset[i].locc); } else if (isdigit(value[0])) { *cset[i].loci = atoi(value); if (debug) printf(" i: %s -> \"%s\": %d\n", cfgline, cset[i].name, *cset[i].loci); } else { continue; } cset[i].found = 1; break; } else if (strlen(value)==0) { if (debug) printf(" c: %s -> \"%s\" with no value, keeping default.\n", cfgline, cset[i].name); cset[i].found = 1; break; } } /* if */ } /* for */ if ((debug) && (!cset[i].found) && (strncasecmp(cfgline, "MaxBW", 5)!=0)) printf("Unknown configuration line: %s", cfgline); } /* if */ } /* while */ /* search for interface specific limits */ ibwcfgread(fd); fclose(fd); if (debug) ibwlist(); /* validate config */ validatecfg(); return 1; }
void defaultcfg(void) { ifacebw = NULL; cfg.bvar = BVAR; cfg.qmode = DEFQMODE; cfg.sampletime = DEFSAMPTIME; cfg.monthrotate = MONTHROTATE; cfg.unitmode = UNITMODE; cfg.rateunitmode = RATEUNITMODE; cfg.ostyle = OSTYLE; cfg.rateunit = RATEUNIT; cfg.bwdetection = BWDETECT; cfg.bwdetectioninterval = BWDETECTINTERVAL; cfg.maxbw = DEFMAXBW; cfg.spacecheck = USESPACECHECK; cfg.flock = USEFLOCK; cfg.hourlyrate = HOURLYRATE; cfg.summaryrate = SUMMARYRATE; cfg.slayout = SUMMARYLAYOUT; cfg.traflessday = TRAFLESSDAY; cfg.utflocale = UTFLOCALE; strncpy_nt(cfg.dbdir, DATABASEDIR, 512); strncpy_nt(cfg.iface, DEFIFACE, 32); strncpy_nt(cfg.locale, LOCALE, 32); strncpy_nt(cfg.dformat, DFORMAT, 64); strncpy_nt(cfg.mformat, MFORMAT, 64); strncpy_nt(cfg.tformat, TFORMAT, 64); strncpy_nt(cfg.hformat, HFORMAT, 64); strncpy_nt(cfg.rxchar, RXCHAR, 2); strncpy_nt(cfg.txchar, TXCHAR, 2); strncpy_nt(cfg.rxhourchar, RXHOURCHAR, 2); strncpy_nt(cfg.txhourchar, TXHOURCHAR, 2); cfg.daemonuser[0] = '\0'; cfg.daemongroup[0] = '\0'; cfg.updateinterval = UPDATEINTERVAL; cfg.pollinterval = POLLINTERVAL; cfg.saveinterval = SAVEINTERVAL; cfg.offsaveinterval = OFFSAVEINTERVAL; cfg.savestatus = SAVESTATUS; cfg.uselogging = USELOGGING; cfg.createdirs = CREATEDIRS; cfg.updatefileowner = UPDATEFILEOWNER; strncpy_nt(cfg.logfile, LOGFILE, 512); strncpy_nt(cfg.pidfile, PIDFILE, 512); cfg.transbg = TRANSBG; strncpy_nt(cfg.cbg, CBACKGROUND, 8); strncpy_nt(cfg.cedge, CEDGE, 8); strncpy_nt(cfg.cheader, CHEADER, 8); strncpy_nt(cfg.cheadertitle, CHEADERTITLE, 8); strncpy_nt(cfg.cheaderdate, CHEADERDATE, 8); strncpy_nt(cfg.ctext, CTEXT, 8); strncpy_nt(cfg.cline, CLINE, 8); strncpy_nt(cfg.clinel, CLINEL, 8); strncpy_nt(cfg.crx, CRX, 8); strncpy_nt(cfg.crxd, CRXD, 8); strncpy_nt(cfg.ctx, CTX, 8); strncpy_nt(cfg.ctxd, CTXD, 8); }
void validatecfg(void) { if (cfg.unitmode<0 || cfg.unitmode>1) { cfg.unitmode = UNITMODE; snprintf(errorstring, 512, "Invalid value for UnitMode, resetting to \"%d\".", cfg.unitmode); printe(PT_Config); } if (cfg.rateunitmode<0 || cfg.rateunitmode>1) { cfg.rateunitmode = RATEUNITMODE; snprintf(errorstring, 512, "Invalid value for RateUnitMode, resetting to \"%d\".", cfg.rateunitmode); printe(PT_Config); } if (cfg.ostyle<0 || cfg.ostyle>3) { cfg.ostyle = OSTYLE; snprintf(errorstring, 512, "Invalid value for OutputStyle, resetting to \"%d\".", cfg.ostyle); printe(PT_Config); } if (cfg.bvar<0 || cfg.bvar>300) { cfg.bvar = BVAR; snprintf(errorstring, 512, "Invalid value for BootVariation, resetting to \"%d\".", cfg.bvar); printe(PT_Config); } if (cfg.sampletime<2 || cfg.sampletime>600) { cfg.sampletime = DEFSAMPTIME; snprintf(errorstring, 512, "Invalid value for Sampletime, resetting to \"%d\".", cfg.sampletime); printe(PT_Config); } if (cfg.monthrotate<1 || cfg.monthrotate>28) { cfg.monthrotate = MONTHROTATE; snprintf(errorstring, 512, "Invalid value for MonthRotate, resetting to \"%d\".", cfg.monthrotate); printe(PT_Config); } if (cfg.maxbw<0 || cfg.maxbw>BWMAX) { cfg.maxbw = DEFMAXBW; snprintf(errorstring, 512, "Invalid value for MaxBandwidth, resetting to \"%d\".", cfg.maxbw); printe(PT_Config); } if (cfg.spacecheck<0 || cfg.spacecheck>1) { cfg.spacecheck = USESPACECHECK; snprintf(errorstring, 512, "Invalid value for CheckDiskSpace, resetting to \"%d\".", cfg.spacecheck); printe(PT_Config); } if (cfg.flock<0 || cfg.flock>1) { cfg.flock = USEFLOCK; snprintf(errorstring, 512, "Invalid value for UseFileLocking, resetting to \"%d\".", cfg.flock); printe(PT_Config); } if (cfg.dbdir[0] != '/') { strncpy_nt(cfg.dbdir, DATABASEDIR, 512); snprintf(errorstring, 512, "DatabaseDir doesn't start with \"/\", resetting to default."); printe(PT_Config); } if (cfg.pollinterval<2 || cfg.pollinterval>60) { cfg.pollinterval = POLLINTERVAL; snprintf(errorstring, 512, "Invalid value for PollInterval, resetting to \"%d\".", cfg.pollinterval); printe(PT_Config); } if (cfg.updateinterval<cfg.pollinterval || cfg.updateinterval>300) { if (cfg.pollinterval>UPDATEINTERVAL) { cfg.updateinterval = cfg.pollinterval; } else { cfg.updateinterval = UPDATEINTERVAL; } snprintf(errorstring, 512, "Invalid value for UpdateInterval, resetting to \"%d\".", cfg.updateinterval); printe(PT_Config); } if ((cfg.saveinterval*60)<cfg.updateinterval || cfg.saveinterval>60) { if (cfg.updateinterval>(SAVEINTERVAL*60)) { cfg.saveinterval = cfg.updateinterval; } else { cfg.saveinterval = SAVEINTERVAL; } snprintf(errorstring, 512, "Invalid value for SaveInterval, resetting to \"%d\".", cfg.saveinterval); printe(PT_Config); } if (cfg.offsaveinterval<cfg.saveinterval || cfg.offsaveinterval>60) { if (cfg.saveinterval>OFFSAVEINTERVAL) { cfg.offsaveinterval = cfg.saveinterval; } else { cfg.offsaveinterval = OFFSAVEINTERVAL; } snprintf(errorstring, 512, "Invalid value for OfflineSaveInterval, resetting to \"%d\".", cfg.offsaveinterval); printe(PT_Config); } if (cfg.savestatus<0 || cfg.savestatus>1) { cfg.savestatus = SAVESTATUS; snprintf(errorstring, 512, "Invalid value for SaveOnStatusChange, resetting to \"%d\".", cfg.savestatus); printe(PT_Config); } if (cfg.uselogging<0 || cfg.uselogging>2) { cfg.uselogging = USELOGGING; snprintf(errorstring, 512, "Invalid value for UseLogging, resetting to \"%d\".", cfg.uselogging); printe(PT_Config); } if (cfg.createdirs<0 || cfg.createdirs>2) { cfg.createdirs = CREATEDIRS; snprintf(errorstring, 512, "Invalid value for CreateDirs, resetting to \"%d\".", cfg.createdirs); printe(PT_Config); } if (cfg.updatefileowner<0 || cfg.updatefileowner>2) { cfg.updatefileowner = UPDATEFILEOWNER; snprintf(errorstring, 512, "Invalid value for UpdateFileOwner, resetting to \"%d\".", cfg.updatefileowner); printe(PT_Config); } if (cfg.logfile[0] != '/') { strncpy_nt(cfg.logfile, LOGFILE, 512); snprintf(errorstring, 512, "LogFile doesn't start with \"/\", resetting to default."); printe(PT_Config); } if (cfg.pidfile[0] != '/') { strncpy_nt(cfg.pidfile, PIDFILE, 512); snprintf(errorstring, 512, "PidFile doesn't start with \"/\", resetting to default."); printe(PT_Config); } if (cfg.transbg<0 || cfg.transbg>1) { cfg.transbg = TRANSBG; snprintf(errorstring, 512, "Invalid value for TransparentBg, resetting to \"%d\".", cfg.transbg); printe(PT_Config); } if (cfg.hourlyrate<0 || cfg.hourlyrate>1) { cfg.hourlyrate = HOURLYRATE; snprintf(errorstring, 512, "Invalid value for HourlyRate, resetting to \"%d\".", cfg.hourlyrate); printe(PT_Config); } if (cfg.summaryrate<0 || cfg.summaryrate>1) { cfg.summaryrate = SUMMARYRATE; snprintf(errorstring, 512, "Invalid value for SummaryRate, resetting to \"%d\".", cfg.summaryrate); printe(PT_Config); } if (cfg.slayout<0 || cfg.slayout>1) { cfg.slayout = SUMMARYLAYOUT; snprintf(errorstring, 512, "Invalid value for SummaryLayout, resetting to \"%d\".", cfg.slayout); printe(PT_Config); } if (cfg.traflessday<0 || cfg.traflessday>1) { cfg.traflessday = TRAFLESSDAY; snprintf(errorstring, 512, "Invalid value for TrafficlessDays, resetting to \"%d\".", cfg.transbg); printe(PT_Config); } if (cfg.bwdetection<0 || cfg.bwdetection>1) { cfg.bwdetection = BWDETECT; snprintf(errorstring, 512, "Invalid value for BandwidthDetection, resetting to \"%d\".", cfg.bwdetection); printe(PT_Config); } if (cfg.bwdetectioninterval<0 || cfg.bwdetectioninterval>30) { cfg.bwdetectioninterval = BWDETECTINTERVAL; snprintf(errorstring, 512, "Invalid value for BandwidthDetectionInterval, resetting to \"%d\".", cfg.bwdetectioninterval); printe(PT_Config); } }