+1.10 / 2-Jan-10
+
+ - Fix: Buffer overflow was possible in hourly image output when RateUnit=1
+ and HourlyRate=1
+ - Fix: Minor memory leak was possible in the handling of HUP signal in daemon
+ - Fix: Graphical elements weren't correctly aligned in summary image
+ when header wasn't visible (-nh)
+ - Fix: --delete didn't work
+ - Possibility to merge statistics from several databases and save
+ the end result to a new database (--mergesaved)
+ - Added validation of database cache in daemon in order to be more robust
+ in case of system memory corruption
+ - Support for --style to -l (live mode)
+ - Alternative print mode to -l (live mode) with optional parameter
+ - Present options and elements in man pages in alphabetical order
+ - Code cleanup
+
+
1.9 / 12-Sep-09
- Fix: TrafficlessDays configuration option was enabled when set to zero
----
-A snapshot of the FAQ (updated 29.7.2009):
+A snapshot of the FAQ (updated 2.1.2010):
Is there some kind of support forum available?
-(Updated 7.9.2009 for version 1.9)
+(Updated 2.1.2010 for version 1.10)
Compiling the binaries
-(Updated 7.9.2009 for version 1.9)
+(Updated 2.1.2010 for version 1.10)
Compiling the binaries
Now you should get some stats about your network usage. See the config
file ~/.vnstatrc for interface and other settings.
-
+
-(Updated 7.9.2009 for version 1.9)
+(Updated 2.1.2010 for version 1.10)
What is vnStat
ensures light use of system resources. Optional image output is available
starting from version 1.7.
- See the webpage for 'screenshots'.
+ See the webpage http://humdi.net/vnstat/ for output examples.
Getting started
The current version of vnStat is always available from
http://humdi.net/vnstat/
+ Discussion forum
+ http://forums.humdi.net/
+
Email alerts about new versions are available by subscription at
http://freshmeat.net/projects/vnstat/
-(Updated 7.9.2009 for version 1.9)
+(Updated 2.1.2010 for version 1.10)
New configuration settings
::::::::::::::::::::::::::
+1.10: (none)
+
1.9: OutputStyle, SummaryLayout, SummaryRate, SaveOnStatusChange,
OfflineSaveInterval
1.7: UnitMode + all settings under vnstatd and vnstati
-Upgrading from versions 1.1 - 1.8 to 1.9
-::::::::::::::::::::::::::::::::::::::::
+Upgrading from versions 1.1 - 1.9 to 1.10
+:::::::::::::::::::::::::::::::::::::::::
1) Follow the normal install procedure, 'make install' will not overwrite
your configuration file
-# vnStat 1.9 config file
+# vnStat 1.10 config file
##
# default interface
-.TH VNSTAT 1 "SEPTEMBER 2009" "version 1.9" "User Manuals"
+.TH VNSTAT 1 "JANUARY 2010" "version 1.10" "User Manuals"
.SH NAME
+
vnStat \- a console-based network traffic monitor
+
.SH SYNOPSIS
+
.B vnstat
[
.B \-Ddhlmqrstuvw?
] [
-.B \-i
-.I interface
-] [
-.B \-ru
-] [
-.B \-tr
-.I time
-] [
.B \-\-cleartop
] [
.B \-\-config
] [
.B \-\-hours
] [
+.B \-i
+.I interface
+] [
.B \-\-iface
.I interface
] [
.B \-\-iflist
] [
.B \-\-live
+.I mode
] [
.B \-\-locale
.I locale
] [
.B \-\-reset
] [
+.B \-ru
+] [
+.B \-\-savemerged
+] [
.B \-\-short
] [
.B \-\-showconfig
] [
.B \-\-top10
] [
+.B \-tr
+.I time
+] [
.B \-\-traffic
.I time
] [
] [
.B \-\-xml
]
+
.SH DESCRIPTION
+
.B vnStat
is a console-based network traffic monitor. It keeps a log of hourly,
daily and monthly network traffic for the selected interface(s). However,
.BR sys
filesystems depending on availability. That way vnStat can be used even
without root permissions on most systems.
+
.SH OPTIONS
-.TP
-.BI "-d, --days"
-Show traffic for days.
-.TP
-.BI "-h, --hours"
-Show traffic for the last 24 hours.
-.TP
-.BI "-m, --months"
-Show traffic for months.
-.TP
-.BI "-s, --short"
-Use short output mode. This mode is also used if more than one
-database is available.
-.TP
-.BI "-t, --top10"
-Show all time top10 traffic days.
-.TP
-.BI "-w, --weeks"
-Show traffic for 7 days, current and previous week.
-.TP
-.BI "--style " number
-Modify the content and style of outputs. Set
-.I number
-to 0 for a more narrow output, 1 for enabling bar column, 2
-for same as previous but with average traffic rate visible in summary
-and weekly outputs and 3 for enabling average traffic rate in all
-outputs where it is supported.
-.TP
-.BI "-tr " time
-Calculate how much traffic goes through the selected interface during
-the given
-.I time
-seconds. The
-.I time
-will be 5 seconds if a number parameter isn't included.
-.TP
-.BI "-l, --live"
-Display current transfer rate for the selected interface in real time
-until interrupted. Statistics will be shown after interruption if runtime
-was more than 10 seconds.
-.TP
-.BI "-ru, --rateunit"
-Swap the configured rate unit. If rate has been configured to be shown in
-bytes then rate will be shown in bits if this option is present. In the same
-way, if rate has been configured to be shown in bits then rate will be shown
-in bytes when this option is present. Alternatively 0 or 1 can be given as
-parameter for this option in order to select between bytes (0) and bits
-(1) regardless of the configuration file setting.
-.TP
-.BI "-i, --iface " interface
-Select one specific
-.I interface
-and apply actions to only it.
-.TP
-.BI "--iflist"
-Show list of currently available interfaces.
-.TP
-.BI "-q, --query"
-Force database query mode.
-.TP
-.BI "-u, --update"
-Update all enabled databases or only the one specified with
-.B -i
-parameter.
-.TP
-.BI "-r, --reset"
-Reset the internal counters in the database for the selected
-interface. Use this if the interface goes down and back up,
-otherwise that interface will get some extra traffic to its database.
-.TP
-.BI "--sync"
-Synchronize internal counters in the database with interface
-counters for the selected interface. Use this if the system is
-rebooted but interface counters aren't reseted. Such can occur
-when suspend to ram/disk is used.
-.TP
-.BI "--enable, --disable"
-Enable or disable updates for selected interface. Useful for
-interfaces that aren't always available, like ppp0. If the interface
-goes down it should be disabled in order to avoid errors. Add something
-like
-.B "vnstat -r --disable -i ppp0"
-to the script that's executed when
-the interface goes down and
-.B "vnstat --enable -i ppp0"
-to the up script. These two options aren't needed when the daemon is used.
-.TP
-.BI "--delete"
-Delete the database for the selected interface and stop monitoring it.
-.TP
-.BI "-v, --version"
-Show current version.
+
.TP
.BI "--cleartop"
Remove all top10 entries.
-.TP
-.BI "-?, --help"
-Show a command summary.
-.TP
-.BI "--longhelp"
-Show complete options list.
-.TP
-.BI "--nick " nickname
-Set the selected interfaces
-.I nickname
-as an alias the will be displayed in queries. Usage of
-.B -u
-is required to save the change.
+
.TP
.BI "--config " file
Use
.I file
as config file instead of using normal config file search function.
+
+.TP
+.BI "-d, --days"
+Show traffic for days.
+
.TP
.BI "--dbdir " directory
Use
.I directory
as database directory instead of using the directory specified in the configuration
file or the hardcoded default if no configuration file is available.
-.TP
-.BI "--locale " locale
-Use
-.I locale
-instead of using the locale setting specified in the configuration file or the system
-default if no configuration file is available.
-.TP
-.BI "--rebuildtotal"
-Reset the total traffic counters and recount those using recorded months.
-.TP
-.BI "--testkernel"
-Test if the kernel boot time information always stays the same like it should or
-if it's shifting.
+
.TP
.BI "-D, --debug"
Show additional debug output.
+
.TP
-.BI "--xml"
-Show database content for selected interface or all interfaces in xml format. All
-traffic values in the output are in KiB.
-.TP
-.BI "--oneline"
-Show traffic summary for selected interface using one line with a parseable
-format. The output contains 15 fields with ; used as field delimeter. The 1st
-field contains the version information of the output that will be changed
-in future versions of vnStat if the field structure changes. The following
-fields in order 2) interface name, 3) timestamp for today, 4) rx for today,
-5) tx for today, 6) total for today, 7) average traffic rate for today,
-8) timestamp for current month, 9) rx for current month, 10) tx for current
-month, 11) total for current month, 12) average traffic rate for today,
-13) all time total rx, 14) all time total tx, 15) all time total traffic.
+.BI "--delete"
+Delete the database for the selected interface and stop monitoring it.
+
.TP
.BI "--dumpdb"
Instead of showing the database with a formated output, this output will
m = months, t = top10 and h = hours, all other fields are in the same order as in days
except hours that doesn't have a separate KiB value. For hours the forth and fifth fields
have values in KiB.
+
+.TP
+.BI "--enable, --disable"
+Enable or disable updates for selected interface. Useful for
+interfaces that aren't always available, like ppp0. If the interface
+goes down it should be disabled in order to avoid errors. Add something
+like
+.B "vnstat -r --disable -i ppp0"
+to the script that's executed when
+the interface goes down and
+.B "vnstat --enable -i ppp0"
+to the up script. These two options aren't needed when the daemon is used.
+
+.TP
+.BI "-h, --hours"
+Show traffic for the last 24 hours.
+
+.TP
+.BI "-i, --iface " interface
+Select one specific
+.I interface
+and apply actions to only it.
+
+.TP
+.BI "--iflist"
+Show list of currently available interfaces.
+
+.TP
+.BI "-l, --live " mode
+Display current transfer rate for the selected interface in real time
+until interrupted. Statistics will be shown after interruption if the runtime
+was more than 10 seconds. An optional
+.I mode
+parameter can be used to select between the displaying of packets per
+second (mode 0) and transfer counters (mode 1) during execution.
+.B "--style"
+can also be used to affect the layout of the output.
+
+.TP
+.BI "--locale " locale
+Use
+.I locale
+instead of using the locale setting specified in the configuration file or the system
+default if no configuration file is available.
+
+.TP
+.BI "--longhelp"
+Show complete options list.
+
+.TP
+.BI "-m, --months"
+Show traffic for months.
+
+.TP
+.BI "--nick " nickname
+Set the selected interfaces
+.I nickname
+as an alias the will be displayed in queries. Usage of
+.B -u
+is required to save the change.
+
+.TP
+.BI "--oneline"
+Show traffic summary for selected interface using one line with a parseable
+format. The output contains 15 fields with ; used as field delimeter. The 1st
+field contains the version information of the output that will be changed
+in future versions of vnStat if the field structure changes. The following
+fields in order 2) interface name, 3) timestamp for today, 4) rx for today,
+5) tx for today, 6) total for today, 7) average traffic rate for today,
+8) timestamp for current month, 9) rx for current month, 10) tx for current
+month, 11) total for current month, 12) average traffic rate for today,
+13) all time total rx, 14) all time total tx, 15) all time total traffic.
+
+.TP
+.BI "-q, --query"
+Force database query mode.
+
+.TP
+.BI "-r, --reset"
+Reset the internal counters in the database for the selected
+interface. Use this if the interface goes down and back up,
+otherwise that interface will get some extra traffic to its database.
+
+.TP
+.BI "--rebuildtotal"
+Reset the total traffic counters and recount those using recorded months.
+
+.TP
+.BI "-ru, --rateunit"
+Swap the configured rate unit. If rate has been configured to be shown in
+bytes then rate will be shown in bits if this option is present. In the same
+way, if rate has been configured to be shown in bits then rate will be shown
+in bytes when this option is present. Alternatively 0 or 1 can be given as
+parameter for this option in order to select between bytes (0) and bits
+(1) regardless of the configuration file setting.
+
+.TP
+.BI "--savemerged"
+Write the end result of a database merge to the file
+.I mergeddb
+that can then be used as a new database if renamed. Top10 traffic days
+isn't included in the merge and will start empty in the new database.
+
+.TP
+.BI "-s, --short"
+Use short output mode. This mode is also used if more than one
+database is available.
+
+.TP
+.BI "--style " number
+Modify the content and style of outputs. Set
+.I number
+to 0 for a more narrow output, 1 for enabling bar column, 2
+for same as previous but with average traffic rate visible in summary
+and weekly outputs and 3 for enabling average traffic rate in all
+outputs where it is supported. 4 disables the use of terminal control
+characters in
+.B "-l / --live"
+mode.
+
+.TP
+.BI "--sync"
+Synchronize internal counters in the database with interface
+counters for the selected interface. Use this if the system is
+rebooted but interface counters aren't reseted. Such can occur
+when suspend to ram/disk is used.
+
+.TP
+.BI "--testkernel"
+Test if the kernel boot time information always stays the same like it should or
+if it's shifting.
+
+.TP
+.BI "-t, --top10"
+Show all time top10 traffic days.
+
+.TP
+.BI "-tr " time
+Calculate how much traffic goes through the selected interface during
+the given
+.I time
+seconds. The
+.I time
+will be 5 seconds if a number parameter isn't included.
+
+.TP
+.BI "-u, --update"
+Update all enabled databases or only the one specified with
+.B -i
+parameter.
+
+.TP
+.BI "-v, --version"
+Show current version.
+
+.TP
+.BI "-w, --weeks"
+Show traffic for 7 days, current and previous week.
+
+.TP
+.BI "--xml"
+Show database content for selected interface or all interfaces in xml format. All
+traffic values in the output are in KiB.
+
+.TP
+.BI "-?, --help"
+Show a command summary.
+
.SH FILES
+
.TP
.I /var/lib/vnstat/
This directory contains all databases the program uses. Files are
named according to the monitored interfaces.
+
.TP
.I /etc/vnstat.conf
Config file that will be used unless
exists. See
.BR vnstat.conf (5)
for more information.
+
.SH EXAMPLES
+
.TP
.BI "vnstat"
Display traffic summary for the default interface.
+
.TP
.BI "vnstat -i eth0+eth1+eth3"
Display traffic summary for a merge of interfaces eth0, eth1 and eth3.
+
.TP
.BI "vnstat -i eth2 --xml"
Output all information about interface eth2 in xml format.
+
.TP
.BI "vnstat -u -i eth0"
Force a database update for interface eth0 or create the database if it doesn't
exist. This is usually the first command used after a fresh install.
+
.TP
.BI "vnstat -u -i eth0 --nick local"
Give interface eth0 the nickname "local". That information will be later
later visible as a label when eth0 is queried. The database will also be updated
when this command is executed or created if the database doesn't exist.
+
.TP
.BI "vnstat -i eth2 --delete"
Delete database of interface eth2 and stop monitoring it.
+
.SH RESTRICTIONS
+
Updates needs to be executed at least as often as it is possible for the interface
to generate enough traffic to wrap the kernel interface traffic counter. Otherwise
it is possible that some traffic won't be seen. This isn't an issue for 64 bit kernels
.RS
.TS
l l.
-10 Mbit: 54 minutes
-100 Mbit: 5 minutes
-1000 Mbit: 30 seconds
+10 Mbit: 54 minutes
+100 Mbit: 5 minutes
+1000 Mbit: 30 seconds
.TE
.RE
Estimated traffic values are likely to be somewhat inaccurate if daily
traffic is low because only the MiB counter is used to calculate the
estimate.
+
.PP
Virtual and aliased interfaces cannot be monitored because the kernel doesn't
provide traffic information for that type of interfaces. Such interfaces are
usually named eth0:0, eth0:1, eth0:2 etc. where eth0 is the actual interface
being aliased.
+
.SH AUTHOR
+
Teemu Toivola <tst at iki dot fi>
+
.SH "SEE ALSO"
+
.BR vnstatd (1),
.BR vnstati (1),
.BR vnstat.conf (5),
-.TH VNSTAT.CONF 5 "SEPTEMBER 2009" "version 1.9" "User Manuals"
+.TH VNSTAT.CONF 5 "JANUARY 2010" "version 1.10" "User Manuals"
.SH NAME
+
vnstat.conf \- vnStat configuration file
+
.SH SYNOPSIS
+
.B /etc/vnstat.conf
+
.SH DESCRIPTION
+
.BR vnstat (1),
.BR vnstati (1)
and
to represent arguments containing spaces. Arguments can be padded
with spaces or tabulator characters. A hardcoded default value
will be used if a keyword can't be found from the configuration file.
+
.SH COMMON KEYWORDS
+
+.TP
+.BI BootVariation
+Time in seconds how much the boot time reported by system kernel can variate
+between updates.
+
+.TP
+.BI CheckDiskSpace
+Enable or disable the checking of at least some free disk space before
+a database write. 1 = enabled, 0 = disabled.
+
.TP
.BI DatabaseDir
Specifies the directory where interface databases are to be stored.
A full path must be given and a leading '/' isn't required.
+
+.TP
+.BI "DayFormat, MonthFormat, TopFormat"
+Formatting of date in available outputs. Uses the same format as
+.BR date (1).
+(vnstat and vnstati only)
+
+.TP
+.BI Interface
+Default interface used when no other interface is specified on
+the command line. (vnstat and vnstati only)
+
.TP
.BI Locale
Locale setting to be used for prints. This replaces the LC_ALL
environment variable. Set to "-" in order to use the system default
value. (vnstat and vnstati only)
+
+.TP
+.BI MaxBandwidth
+Maximum bandwidth for all interfaces. If the counted traffic exceeds
+the given value then the data is assumed to be invalid and rejected.
+Set to 0 in order to disable the feature. (vnstat and vnstatd only)
+
+.TP
+.BI MaxBW
+Same as MaxBandwidth but can be used for setting individual limits
+for selected interfaces. The name of the interface is specified directly
+after the MaxBW keyword without spaces. For example MaxBWeth0 for eth0
+and MaxBWppp0 for ppp0. (vnstat and vnstatd only)
+
.TP
.BI MonthRotate
Day of month that months are expected to change. Usually set to
1 but can be set to alternative values for example for tracking
monthly billed traffic where the billing period doesn't start on
the first day. (vnstat and vnstatd only)
-.TP
-.BI "DayFormat, MonthFormat, TopFormat"
-Formatting of date in available outputs. Uses the same format as
-.BR date (1).
-(vnstat and vnstati only)
-.TP
-.BI "RXCharacter, TXCharacter"
-Character used for representing the percentual share of received
-and transmitted traffic in daily output. (vnstat only)
-.TP
-.BI "RXHourCharacter, TXHourCharacter"
-Character used for representing the percentual share of received
-and transmitted traffic in hourly output. (vnstat only)
-.TP
-.BI UnitMode
-Select how units are prefixed. 0 = IEC standard prefixes
-(KiB/MiB/GiB/TiB), 1 = old style binary prefixes (KB/MB/GB/TB).
-(vnstat and vnstati only)
+
.TP
.BI OutputStyle
Modify the content and style of text outputs. 0 = minimal and
bar column visible, 2 = same as 1 except rate is visible in summary
and weekly outputs, 3 = rate column is visible in all outputs where it
is supported. (vnstat and vnstati only)
+
+.TP
+.BI QueryMode
+Default query mode when no parameters are given. 0 = normal, 1 = days,
+2 = months, 3 = top10, 4 = dumpdb, 5 = short, 6 = weeks, 7 = hours and
+8 = xml.
+(vnstat only)
+
.TP
.BI RateUnit
Select which unit is used when traffic rate is visible. 0 = bytes, 1 = bits.
(vnstat and vnstati only)
+
.TP
-.BI Interface
-Default interface used when no other interface is specified on
-the command line. (vnstat and vnstati only)
-.TP
-.BI MaxBandwidth
-Maximum bandwidth for all interfaces. If the counted traffic exceeds
-the given value then the data is assumed to be invalid and rejected.
-Set to 0 in order to disable the feature. (vnstat and vnstatd only)
+.BI "RXCharacter, TXCharacter"
+Character used for representing the percentual share of received
+and transmitted traffic in daily output. (vnstat only)
+
.TP
-.BI MaxBW
-Same as MaxBandwidth but can be used for setting individual limits
-for selected interfaces. The name of the interface is specified directly
-after the MaxBW keyword without spaces. For example MaxBWeth0 for eth0
-and MaxBWppp0 for ppp0. (vnstat and vnstatd only)
+.BI "RXHourCharacter, TXHourCharacter"
+Character used for representing the percentual share of received
+and transmitted traffic in hourly output. (vnstat only)
+
.TP
.BI Sampletime
Defines how many seconds the -tr option will sample traffic. (vnstat only)
+
.TP
-.BI QueryMode
-Default query mode when no parameters are given. 0 = normal, 1 = days,
-2 = months, 3 = top10, 4 = dumpdb, 5 = short, 6 = weeks, 7 = hours and
-8 = xml.
-(vnstat only)
+.BI TrafficlessDays
+Log days without any traffic to daily list. 1 = enabled, 0 = disabled.
+(vnstat and vnstatd only)
+
.TP
-.BI CheckDiskSpace
-Enable or disable the checking of at least some free disk space before
-a database write. 1 = enabled, 0 = disabled.
+.BI UnitMode
+Select how units are prefixed. 0 = IEC standard prefixes
+(KiB/MiB/GiB/TiB), 1 = old style binary prefixes (KB/MB/GB/TB).
+(vnstat and vnstati only)
+
.TP
.BI UseFileLocking
Enable or disable the use of file locking during database access. Disabling
file locking may cause database corruption if several processes are trying
to write to the file at the same time.
+
+.SH DAEMON RELATED KEYWORDS
+
.TP
-.BI BootVariation
-Time in seconds how much the boot time reported by system kernel can variate
-between updates.
+.BI LogFile
+Specify log file path and name to be used if UseLogging is set to 1.
+
.TP
-.BI TrafficlessDays
-Log days without any traffic to daily list. 1 = enabled, 0 = disabled.
-(vnstat and vnstatd only)
-.SH DAEMON RELATED KEYWORDS
+.BI OfflineSaveInterval
+How often in minutes cached interface data is saved to file when all monitored
+interfaces are offline.
+
.TP
-.BI UpdateInterval
-How often in seconds the interface data is updated.
+.BI PidFile
+Specify pid file path and name to be used.
+
.TP
.BI PollInterval
How often in seconds interfaces are checked for status changes.
+
.TP
.BI SaveInterval
How often in minutes cached interface data is saved to file.
-.TP
-.BI OfflineSaveInterval
-How often in minutes cached interface data is saved to file when all monitored
-interfaces are offline.
+
.TP
.BI SaveOnStatusChange
Enable or disable the additional saving to file of cached interface data
when the availability of an interface changes, i.e., when an interface goes
offline or comes online. 1 = enabled, 0 = disabled.
+
+.TP
+.BI UpdateInterval
+How often in seconds the interface data is updated.
+
.TP
.BI UseLogging
Enable or disable logging. 0 = disabled, 1 = logfile and 2 = syslog.
-.TP
-.BI LogFile
-Specify log file path and name to be used if UseLogging is set to 1.
-.TP
-.BI PidFile
-Specify pid file path and name to be used.
+
.SH IMAGE OUTPUT RELATED KEYWORDS
-.TP
-.BI HeaderFormat
-Formatting of date in header. Uses the same format as
-.BR date (1).
-.TP
-.BI HourlyRate
-Show hours with rate instead of transfered amount. 1 = enabled, 0 = disabled.
-.TP
-.BI SummaryRate
-Show rate in summary output if available. 1 = enabled, 0 = disabled.
-.TP
-.BI SummaryLayout
-Select the used layout of the summary output. 1 = layout introduced in version
-1.8 with monthly traffic included, 0 = layout used before version 1.8, doesn't
-contain monthly traffic and doesn't support average rate.
-.TP
-.BI TransparentBg
-Set background color as transparent. 1 = enabled, 0 = disabled.
+
.TP
.BI CBackground
Background color.
+
.TP
.BI CEdge
Edge color if visible.
+
.TP
.BI CHeader
Header background color.
+
.TP
.BI CHeaderTitle
Header title text color.
+
.TP
.BI CHeaderDate
Header date text color.
-.TP
-.BI CText
-Common text color.
+
.TP
.BI CLine
Line color.
+
.TP
.BI CLineL
Lighter version of line color. Set to '-' in order to use a calculated
value based on CLine.
+
.TP
.BI CRx
Color for received data.
-.TP
-.BI CTx
-Color for transmitted data.
+
.TP
.BI CRxD
Darker version of received data color. Set to '-' in order to use
a calculated value based on CRx.
+
+.TP
+.BI CText
+Common text color.
+
+.TP
+.BI CTx
+Color for transmitted data.
+
.TP
.BI CTxD
Darker version of transmitted data color. Set to '-' in order to use
a calculated value based on CTx.
+
+.TP
+.BI HeaderFormat
+Formatting of date in header. Uses the same format as
+.BR date (1).
+
+.TP
+.BI HourlyRate
+Show hours with rate instead of transfered amount. 1 = enabled, 0 = disabled.
+
+.TP
+.BI SummaryLayout
+Select the used layout of the summary output. 1 = layout introduced in version
+1.8 with monthly traffic included, 0 = layout used before version 1.8, doesn't
+contain monthly traffic and doesn't support average rate.
+
+.TP
+.BI SummaryRate
+Show rate in summary output if available. 1 = enabled, 0 = disabled.
+
+.TP
+.BI TransparentBg
+Set background color as transparent. 1 = enabled, 0 = disabled.
+
.SH FILES
+
.TP
.I /etc/vnstat.conf
Config file that will be used unless
.I $HOME/.vnstatrc
exists or alternative value is given as command line parameter.
+
.SH AUTHOR
+
Teemu Toivola <tst at iki dot fi>
+
.SH "SEE ALSO"
+
.BR vnstat (1),
.BR vnstati (1),
.BR vnstatd (1),
-.TH VNSTATD 1 "SEPTEMBER 2009" "version 1.9" "User Manuals"
+.TH VNSTATD 1 "JANUARY 2010" "version 1.10" "User Manuals"
.SH NAME
+
vnStat daemon \- the alternative for cron based updating
+
.SH SYNOPSIS
+
.B vnstatd
[
.B \-Ddnpsv?
] [
-.B \-\-daemon
-] [
-.B \-\-nodaemon
+.B \-\-config
+.I file
] [
-.B \-\-sync
+.B \-\-daemon
] [
.B \-\-debug
] [
.B \-\-help
] [
-.B \-\-version
+.B \-\-nodaemon
] [
.B \-\-pidfile
.I file
] [
-.B \-\-config
-.I file
+.B \-\-sync
+] [
+.B \-\-version
]
+
.SH DESCRIPTION
+
The purpose of
.B vnstatd
is to provide a more flexible way for updating
file and exit if no databases can be found. The reason for this behaviour
is to avoid starting the daemon when it's clear that it wouldn't have
anything to do.
+
.SH OPTIONS
+
+.TP
+.BI "--config " file
+Use
+.I file
+as config file instead of using normal config file search function.
+
.TP
.BI "-d, --daemon"
Fork process to background and run as a daemon.
+
+.TP
+.BI "-D, --debug"
+Provide additional output for debug purposes. The process will stay
+attached to the terminal for output.
+
.TP
.BI "-n, --nodaemon"
Stay in foreground attached to the current terminal and start update
process.
+
+.TP
+.BI "-p, --pidfile " file
+Write the process id to
+.I file
+and use it for locking so that another instance of the daemon cannot
+be started if the same
+.I file
+is specified.
+
.TP
.BI "-s, --sync"
Synchronize internal counters in the database with interface
the internal counters after a system reboot, if enought time has passed
since the daemon was previously running or if the internal counters are
clearly out of sync.
-.TP
-.BI "-D, --debug"
-Provide additional output for debug purposes. The process will stay
-attached to the terminal for output.
-.TP
-.BI "-?, --help"
-Show a command summary.
+
.TP
.BI "-v, --version"
Show current version.
+
.TP
-.BI "-p, --pidfile " file
-Write the process id to
-.I file
-and use it for locking so that another instance of the daemon cannot
-be started if the same
-.I file
-is specified.
-.TP
-.BI "--config " file
-Use
-.I file
-as config file instead of using normal config file search function.
+.BI "-?, --help"
+Show a command summary.
+
.SH CONFIGURATION
+
The behaviour of the daemon is configured mainly using the configuration
keywords
.BR "UpdateInterval, PollInterval"
and
.BR SaveInterval
in the configuration file.
+
.PP
.BR UpdateInterval
defines in seconds how often the interface data is updated.
This is similar to the run interval for alternative cron based updating.
However, the difference is that the data doesn't get written to disk
during updates.
-.PP
-.BR SaveInterval
-defines in minutes how often cached interface data is written to disk.
-A write can only occur during the updating of interface data. Therefore,
-the value should be a multiple of
-.BR UpdateInterval
-with a maximum value of 60 minutes.
+
.PP
.BR PollInterval
defines in seconds how often the list of available interfaces is checked
seconds.
.BR PollInterval
also defines the resolution for other intervals.
+
+.PP
+.BR SaveInterval
+defines in minutes how often cached interface data is written to disk.
+A write can only occur during the updating of interface data. Therefore,
+the value should be a multiple of
+.BR UpdateInterval
+with a maximum value of 60 minutes.
+
.PP
The default values of
.BR UpdateInterval
2 are usually suitable for most systems and provide a similar behaviour
as cron based updating does but with a better resolution for interface
changes and fast interfaces.
+
.PP
For embedded and/or low power systems more tuned configurations are possible.
In such cases if the interfaces are mostly static the
.BR SaveInterval
can be rised for example to 15, 30 or even 60 minutes depending on how
often the data needs to be viewed.
+
.SH SIGNALS
+
The daemon is listening to signals
.BR "SIGHUP, SIGINT"
and
a rescan of the database directory and a reload of settings from the
configuration file. However, the pid file will not be updated even if
it's configuration setting has been changed.
+
.PP
.BR SIGTERM
and
.BR SIGINT
signals will cause the daemon to write all cached data to disk and
then exit.
+
.SH FILES
+
.TP
.I /var/lib/vnstat/
Default database directory. Files are named according to the monitored
.I /var/run/vnstat.pid
File used for storing the process id if no other file is specified in the
configuration file or using the command line parameter.
+
.SH RESTRICTIONS
+
Updates needs to be executed at least as often as it is possible for the interface
to generate enough traffic to wrap the kernel interface traffic counter. Otherwise
it is possible that some traffic won't be seen. This isn't an issue for 64 bit kernels
.RS
.TS
l l.
-10 Mbit: 54 minutes
-100 Mbit: 5 minutes
-1000 Mbit: 30 seconds
+10 Mbit: 54 minutes
+100 Mbit: 5 minutes
+1000 Mbit: 30 seconds
.TE
.RE
provide traffic information for that type of interfaces. Such interfaces are
usually named eth0:0, eth0:1, eth0:2 etc. where eth0 is the actual interface
being aliased.
+
.SH AUTHOR
+
Teemu Toivola <tst at iki dot fi>
+
.SH "SEE ALSO"
+
.BR vnstat (1),
.BR vnstati (1),
.BR vnstat.conf (5),
-.TH VNSTATI 1 "SEPTEMBER 2009" "version 1.9" "User Manuals"
+.TH VNSTATI 1 "JANUARY 2010" "version 1.10" "User Manuals"
.SH NAME
+
vnStat image output \- png image output support for vnStat
+
.SH SYNOPSIS
+
.B vnstati
[
.B \-cdhimostv?
] [
-.B \-i
-.I interface
+.B \-\-cache
+.I time
] [
-.B \-\-hours
+.B \-\-config
+.I file
] [
.B \-\-days
] [
-.B \-\-months
+.B \-\-dbdir
+.I directory
] [
-.B \-\-top10
+.B \-\-help
] [
-.B \-\-summary
+.B \-\-hours
] [
.B \-hs
] [
.B \-\-hsummary
] [
-.B \-vs
+.B \-i
+.I interface
] [
-.B \-\-vsummary
+.B \-\-iface
+.I interface
] [
-.B \-ne
+.B \-\-locale
+.I locale
] [
-.B \-\-noedge
+.B \-\-months
+] [
+.B \-ne
] [
.B \-nh
] [
+.B \-\-noedge
+] [
.B \-\-noheader
] [
+.B \-\-output
+.I file
+] [
.B \-ru
] [
.B \-\-rateunit
.B \-\-style
.I number
] [
-.B \-\-transparent
-] [
-.B \-\-output
-.I file
-] [
-.B \-\-cache
-.I time
-] [
-.B \-\-iface
-.I interface
+.B \-\-summary
] [
-.B \-\-config
-.I file
+.B \-\-top10
] [
-.B \-\-dbdir
-.I directory
+.B \-\-transparent
] [
-.B \-\-locale
-.I locale
+.B \-\-version
] [
-.B \-\-help
+.B \-vs
] [
-.B \-\-version
+.B \-\-vsummary
]
+
.SH DESCRIPTION
+
The purpose of
.B vnstati
is to provide image output support for statistics collected using
The image file format is limited to png. All basic outputs
of vnStat are supported excluding live traffic features. The image
can be outputted either to a file or to standard output.
+
.SH OPTIONS
+
.TP
-.BI "-s, --summary"
-Output traffic summary.
-.TP
-.BI "-hs, --hsummary"
-Output traffic summary including hourly data using a horizontal layout.
+.BI "-c, --cache " time
+Update output file only if at least
+.I time
+minutes have passed since the previous file update. This option is ignored if
+stdout is used as output.
+
.TP
-.BI "-vs, --vsummary"
-Output traffic summary including hourly data using a vertical layout.
+.BI "--config " file
+Use
+.I file
+as config file instead of using normal config file search function.
+
.TP
.BI "-d, --days"
Output traffic for days.
+
+.TP
+.BI "--dbdir " directory
+Use
+.I directory
+as database directory instead of using the directory specified in the configuration
+file or the hardcoded default if no configuration file is available.
+
.TP
.BI "-h, --hours"
Output traffic for the last 24 hours.
+
+.TP
+.BI "-hs, --hsummary"
+Output traffic summary including hourly data using a horizontal layout.
+
+.TP
+.BI "-i, --iface " interface
+Use
+.I interface
+instead of default or configured interface.
+
+.TP
+.BI "--locale " locale
+Use
+.I locale
+instead of using the locale setting specified in the configuration file or the system
+default if no configuration file is available.
+
.TP
.BI "-m, --months"
Output traffic for months.
-.TP
-.BI "-t, --top10"
-Output all time top10 traffic days.
+
.TP
.BI "-ne, --noedge"
Remove darker edges from around the image.
+
.TP
.BI "-nh, --noheader"
Remove header containing title and update time. Time of the previous update
will still be visible in the lower right corner using a less visible color.
+
+.TP
+.BI "-o, --output " file
+Write png image to
+.I file
+and exit. Output can be directed to stdout by giving "-" as filename.
+
.TP
.BI "-ru, --rateunit"
Swap the configured rate unit. If rate has been configured to be shown in
in bytes when this option is present. Alternatively 0 or 1 can be given as
parameter for this option in order to select between bytes (0) and bits
(1) regardless of the configuration file setting.
+
.TP
.BI "--style " number
Modify the content and style of outputs. Setting
.I number
to 3 will show average traffic rate in all outputs where it is supported.
Other values will show bar graphics instead.
+
+.TP
+.BI "-s, --summary"
+Output traffic summary.
+
+.TP
+.BI "-t, --top10"
+Output all time top10 traffic days.
+
.TP
.BI "--transparent"
Toggle background color transparency depending of the TransparentBg setting
in the configuration file. Alternatively 0 or 1 can be given as parameter
for this option in order to either disable (0) or enable (1) transparency
regardless of the configuration file setting.
+
.TP
-.BI "-o, --output " file
-Write png image to
-.I file
-and exit. Output can be directed to stdout by giving "-" as filename.
-.TP
-.BI "-c, --cache " time
-Update output file only if at least
-.I time
-minutes have passed since the previous file update. This option is ignored if
-stdout is used as output.
-.TP
-.BI "-i, --iface " interface
-Use
-.I interface
-instead of default or configured interface.
-.TP
-.BI "--config " file
-Use
-.I file
-as config file instead of using normal config file search function.
-.TP
-.BI "--dbdir " directory
-Use
-.I directory
-as database directory instead of using the directory specified in the configuration
-file or the hardcoded default if no configuration file is available.
+.BI "-v, --version"
+Show current version.
+
.TP
-.BI "--locale " locale
-Use
-.I locale
-instead of using the locale setting specified in the configuration file or the system
-default if no configuration file is available.
+.BI "-vs, --vsummary"
+Output traffic summary including hourly data using a vertical layout.
+
.TP
.BI "-?, --help"
Show a command summary.
-.TP
-.BI "-v, --version"
-Show current version.
+
.SH FILES
+
.TP
.I /var/lib/vnstat/
Default database directory. Files are named according to the monitored interfaces.
.BR vnstat.conf (5)
for more information.
.SH EXAMPLES
+
.TP
.BI "vnstati -s -i eth0 -o /tmp/vnstat.png"
Output traffic summary for interface eth0 to file /tmp/vnstat.png.
+
.TP
.BI "vnstati -vs -i eth0+eth1+eth2 -o /tmp/vnstat.png"
Output traffic summary with hourly data under the normal summary for a merge of
interfaces eth0, eth1 and eth2 to file /tmp/vnstat.png.
+
.TP
.BI "vnstati -h -c 15 -o /tmp/vnstat_h.png"
Output hourly traffic statistics for default interface to file /tmp/vnstat_h.png
if the file has not been updated within the last 15 minutes.
+
.TP
.BI "vnstati -d -ne -nh -o -"
Output daily traffic statistics without displaying the header section and edges
for default interface to standard output (stdout).
+
.TP
.BI "vnstati -m --config /home/me/vnstat.cfg -i -o -"
Output monthly traffic statistics for default interface specified in configuration
file /home/me/vnstat.cfg to standard output (stdout).
+
.SH AUTHOR
+
Teemu Toivola <tst at iki dot fi>
+
.SH "SEE ALSO"
+
.BR vnstat (1),
.BR vnstatd (1),
.BR vnstat.conf (5),
break;
}
- linelen = strlen(cfgline);
+ linelen = (int)strlen(cfgline);
if (linelen>2 && cfgline[0]!='#') {
for (i=0; cset[i].name!=0; i++) {
continue;
}
- cfglen = strlen(cset[i].name);
+ cfglen = (int)strlen(cset[i].name);
if ( (linelen>=(cfglen+2)) && (strncasecmp(cfgline, cset[i].name, cfglen)==0) ) {
/* clear value buffer */
} /* if */
} /* for */
+
+ if ((debug) && (!cset[i].found) && (strncasecmp(cfgline, "MaxBW", 5)!=0))
+ printf("Unknown configuration line: %s", cfgline);
} /* if */
int ibwadd(const char *iface, int limit)
{
- ibwnode *p = malloc(sizeof(ibwnode));
+ ibwnode *n, *p = ifacebw;
+ /* add new node if list is empty */
if (p == NULL) {
- return 0;
- }
- p->next = ifacebw;
- ifacebw = p;
- strncpy(p->interface, iface, 32);
- p->limit = limit;
+ n = malloc(sizeof(ibwnode));
+
+ if (n == NULL) {
+ return 0;
+ }
+
+ n->next = ifacebw;
+ ifacebw = n;
+ strncpy(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(n->interface, iface, 32);
+ n->limit = limit;
+ }
return 1;
}
break;
}
- linelen = strlen(cfgline);
+ linelen = (int)strlen(cfgline);
if (linelen>8 && cfgline[0]!='#') {
char *locc;
short *loci;
short namelen;
- short found;;
+ short found;
};
#endif
int dmonth(int month)
{
- static int dmonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+ static int dmon[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int year;
time_t current;
return 28;
}
} else {
- return dmonth[month];
+ return dmon[month];
}
}
d = localtime(&data.month[0].month);
+ if (d == NULL) {
+ return 0;
+ }
+
if (d->tm_mday < cfg.monthrotate) {
return 0;
}
*/
/* location of the database directory */
-#if defined(__linux__)
-#define DATABASEDIR "/var/lib/vnstat"
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
#define DATABASEDIR "/var/db/vnstat"
+#else
+#define DATABASEDIR "/var/lib/vnstat"
#endif
/* on which day should months change */
#define DBVERSION 3
/* version string */
-#define VNSTATVERSION "1.9"
+#define VNSTATVERSION "1.10"
/* xml format version */
/* 1 = 1.7- */
if (noexit) {
return -1;
} else {
- exit(1);
+ exit(EXIT_FAILURE);
}
} else {
if (debug) {
if (noexit) {
return -1;
} else {
- exit(1);
+ exit(EXIT_FAILURE);
}
}
}
if (noexit) {
return -1;
} else {
- exit(1);
+ exit(EXIT_FAILURE);
}
}
}
if (noexit) {
return -1;
} else {
- exit(1);
+ exit(EXIT_FAILURE);
}
}
return 0;
}
- data.lastupdated=time(NULL);
+ /* update timestamp when not merging */
+ if (newdb!=2) {
+ data.lastupdated=time(NULL);
+ }
+
if (fwrite(&data,sizeof(DATA),1,db)==0) {
snprintf(errorstring, 512, "Unable to write database \"%s\".", file);
printe(PT_Error);
b = fileno(bf);
/* copy data */
- while((bytes = read(c, buffer, sizeof(buffer))) > 0) {
+ while((bytes = (int)read(c, buffer, sizeof(buffer))) > 0) {
if (write(b, buffer, bytes) < 0) {
close(c);
fclose(bf);
data12.day[i].date=current-(i*86400);
data12.day[i].used=1;
} else {
- data12.day[i].rx=data12.day[i].tx=0;
+ data12.day[i].rx=0;
+ data12.day[i].tx=0;
data12.day[i].used=0;
}
}
days+=dmonth(mod);
data12.month[i].used=1;
} else {
- data12.month[i].rx=data12.month[i].tx=0;
+ data12.month[i].rx=0;
+ data12.month[i].tx=0;
data12.month[i].used=0;
}
}
} else {
data12.top10[i].used=0;
- data12.top10[i].rx=data12.top10[i].tx=0;
+ data12.top10[i].rx=0;
+ data12.top10[i].tx=0;
}
unlink(file);
snprintf(file, 512, "%s/%s", dirname, iface);
- if (!unlink(file)) {
+ if (unlink(file)!=0) {
perror("unlink");
return 0;
}
data.hour[i].tx=0;
data.hour[i].date=0;
if (debug) {
- printf("db: Hour %d (%d) cleaned.\n", i, (int)data.hour[i].date);
+ printf("db: Hour %d (%u) cleaned.\n", i, (unsigned int)data.hour[i].date);
}
}
}
data.hour[hour].rx=0;
data.hour[hour].tx=0;
if (debug) {
- printf("db: Current hour %d (%d) cleaned.\n", hour, (int)data.hour[hour].date);
+ printf("db: Current hour %d (%u) cleaned.\n", hour, (unsigned int)data.hour[hour].date);
}
data.hour[hour].date=current;
}
int b = 13, count = 0;
datanode *p = dataptr;
- sprintf(buffer, "Monitoring: ");
+ snprintf(buffer, b, "Monitoring: ");
if (p != NULL) {
printe(PT_Info);
}
-int cacheget(const datanode *dn)
+int cacheget(datanode *dn)
{
if (dn->filled) {
memcpy(&data, &dn->data, sizeof(data));
+
+ /* do simple data validation */
+ if (data.version != DBVERSION ||
+ data.created == 0 ||
+ data.lastupdated == 0 ||
+ data.interface[0] == '\0' ||
+ data.active > 1 ||
+ data.active < 0) {
+
+ if (debug)
+ printf("cache get: validation failed (%d/%u/%u/%d/%d)\n", data.version, (unsigned int)data.created, (unsigned int)data.lastupdated, data.interface[0], data.active);
+
+ /* force reading of database file */
+ dn->filled = 0;
+ }
}
if (debug) {
return 0;
}
- newhash = simplehash(ifacelist, strlen(ifacelist));
+ newhash = simplehash(ifacelist, (int)strlen(ifacelist));
/* search for changes if hash doesn't match */
if (newhash!=dbhash) {
if (p->filled) {
found = offset = 0;
- while (offset <= strlen(ifacelist)) {
+ while (offset <= (int)strlen(ifacelist)) {
sscanf(ifacelist+offset, "%32s", interface);
if (strcmp(p->data.interface, interface)==0) {
found = 1;
break;
}
- offset += strlen(interface)+1;
+ offset += (int)strlen(interface)+1;
}
if (p->data.active==1 && found==0) {
int cacheupdate(void);
void cacheshow(void);
void cachestatus(void);
-int cacheget(const datanode *dn);
+int cacheget(datanode *dn);
void cacheflush(const char *dirname);
int cachecount(void);
int cacheactivecount(void);
#include "dbaccess.h"
#include "dbmerge.h"
-int mergedb(char iface[32], char dirname[512])
+int mergedb(char iface[], char dirname[])
{
DATA mergedata;
char *ifaceptr;
#ifndef DBMERGE_H
#define DBMERGE_H
-int mergedb(char iface[32], char dirname[512]);
+int mergedb(char iface[], char dirname[]);
void emptydb(DATA *dat);
int mergewith(DATA *dat);
void cleanmerged(DATA *dat);
strncpy(daytemp2, " today", 32);
}
- printf("Database updated: %s\n",(char*)asctime(localtime(&data.lastupdated)));
+ if (data.lastupdated) {
+ printf("Database updated: %s\n",(char*)asctime(localtime(&data.lastupdated)));
+ } else {
+ printf("\n");
+ }
indent(3);
if (strcmp(data.interface, data.nick)==0) {
void showhours(void)
{
- int i, j, k;
- int tmax=0, max=0, s=0, dots=0;
- char matrix[24][80];
-
- int hour, min;
+ int i, k, s=0, hour, minute;
+ unsigned int j, tmax=0, dots=0;
+ uint64_t max=0;
+ char matrix[24][81]; /* width is one over 80 so that snprintf can write the end char */
struct tm *d;
/* tmax = time max = current hour */
d=localtime(&data.lastupdated);
hour=d->tm_hour;
- min=d->tm_min;
+ minute=d->tm_min;
for (i=0;i<=23;i++) {
if (data.hour[i].date>=data.hour[tmax].date) {
/* mr. proper */
for (i=0;i<24;i++) {
- for (j=0;j<80;j++) {
+ for (j=0;j<81;j++) {
matrix[i][j]=' ';
}
}
/* structure */
- sprintf(matrix[11]," -+--------------------------------------------------------------------------->");
+ snprintf(matrix[11], 81, " -+--------------------------------------------------------------------------->");
if (cfg.unit==0) {
- sprintf(matrix[14]," h rx (KiB) tx (KiB) h rx (KiB) tx (KiB) h rx (KiB) tx (KiB)");
+ snprintf(matrix[14], 81, " h rx (KiB) tx (KiB) h rx (KiB) tx (KiB) h rx (KiB) tx (KiB)");
} else {
- sprintf(matrix[14]," h rx (KB) tx (KB) h rx (KB) tx (KB) h rx (KB) tx (KB)");
+ snprintf(matrix[14], 81, " h rx (KB) tx (KB) h rx (KB) tx (KB) h rx (KB) tx (KB)");
}
for (i=10;i>1;i--)
/* title */
if (strcmp(data.interface, data.nick)==0) {
if (data.active)
- sprintf(matrix[0]," %s", data.interface);
+ snprintf(matrix[0], 81, " %s", data.interface);
else
- sprintf(matrix[0]," %s [disabled]", data.interface);
+ snprintf(matrix[0], 81, " %s [disabled]", data.interface);
} else {
if (data.active)
- sprintf(matrix[0]," %s (%s)", data.nick, data.interface);
+ snprintf(matrix[0], 81, " %s (%s)", data.nick, data.interface);
else
- sprintf(matrix[0]," %s (%s) [disabled]", data.nick, data.interface);
+ snprintf(matrix[0], 81, " %s (%s) [disabled]", data.nick, data.interface);
}
/* time to the corner */
- sprintf(matrix[0]+74,"%02d:%02d", hour, min);
+ snprintf(matrix[0]+74, 7, "%02d:%02d", hour, minute);
/* numbers under x-axis and graphics :) */
k=5;
if (s<0)
s+=24;
- sprintf(matrix[12]+k,"%02d ",s);
+ snprintf(matrix[12]+k, 81-k, "%02d ", s);
dots=10*(data.hour[s].rx/(float)max);
for (j=0;j<dots;j++)
for (i=0;i<=7;i++) {
s=tmax+i+1;
#if !defined(__OpenBSD__)
- sprintf(matrix[15+i],"%02d %'10"PRIu64" %'10"PRIu64" %02d %'10"PRIu64" %'10"PRIu64" %02d %'10"PRIu64" %'10"PRIu64"",s%24, data.hour[s%24].rx, data.hour[s%24].tx, (s+8)%24, data.hour[(s+8)%24].rx, data.hour[(s+8)%24].tx, (s+16)%24, data.hour[(s+16)%24].rx, data.hour[(s+16)%24].tx);
+ snprintf(matrix[15+i], 81, "%02d %'10"PRIu64" %'10"PRIu64" %02d %'10"PRIu64" %'10"PRIu64" %02d %'10"PRIu64" %'10"PRIu64"",s%24, data.hour[s%24].rx, data.hour[s%24].tx, (s+8)%24, data.hour[(s+8)%24].rx, data.hour[(s+8)%24].tx, (s+16)%24, data.hour[(s+16)%24].rx, data.hour[(s+16)%24].tx);
#else
- sprintf(matrix[15+i],"%02d %10"PRIu64" %10"PRIu64" %02d %10"PRIu64" %10"PRIu64" %02d %10"PRIu64" %10"PRIu64"",s%24, data.hour[s%24].rx, data.hour[s%24].tx, (s+8)%24, data.hour[(s+8)%24].rx, data.hour[(s+8)%24].tx, (s+16)%24, data.hour[(s+16)%24].rx, data.hour[(s+16)%24].tx);
+ snprintf(matrix[15+i], 81, "%02d %10"PRIu64" %10"PRIu64" %02d %10"PRIu64" %10"PRIu64" %02d %10"PRIu64" %10"PRIu64"",s%24, data.hour[s%24].rx, data.hour[s%24].tx, (s+8)%24, data.hour[(s+8)%24].rx, data.hour[(s+8)%24].tx, (s+16)%24, data.hour[(s+16)%24].rx, data.hour[(s+16)%24].tx);
#endif
}
printf("active;%d\n", data.active);
printf("interface;%s\n", data.interface);
printf("nick;%s\n", data.nick);
- printf("created;%d\n", (int)data.created);
- printf("updated;%d\n", (int)data.lastupdated);
+ printf("created;%u\n", (unsigned int)data.created);
+ printf("updated;%u\n", (unsigned int)data.lastupdated);
printf("totalrx;%"PRIu64"\n", data.totalrx);
printf("totaltx;%"PRIu64"\n", data.totaltx);
printf("btime;%"PRIu64"\n", data.btime);
for (i=0;i<=29;i++) {
- printf("d;%d;%d;%"PRIu64";%"PRIu64";%d;%d;%d\n", i, (int)data.day[i].date, data.day[i].rx, data.day[i].tx, data.day[i].rxk, data.day[i].txk, data.day[i].used);
+ printf("d;%d;%u;%"PRIu64";%"PRIu64";%d;%d;%d\n", i, (unsigned int)data.day[i].date, data.day[i].rx, data.day[i].tx, data.day[i].rxk, data.day[i].txk, data.day[i].used);
}
for (i=0;i<=11;i++) {
- printf("m;%d;%d;%"PRIu64";%"PRIu64";%d;%d;%d\n", i, (int)data.month[i].month, data.month[i].rx, data.month[i].tx, data.month[i].rxk, data.month[i].txk, data.month[i].used);
+ printf("m;%d;%u;%"PRIu64";%"PRIu64";%d;%d;%d\n", i, (unsigned int)data.month[i].month, data.month[i].rx, data.month[i].tx, data.month[i].rxk, data.month[i].txk, data.month[i].used);
}
for (i=0;i<=9;i++) {
- printf("t;%d;%d;%"PRIu64";%"PRIu64";%d;%d;%d\n", i, (int)data.top10[i].date, data.top10[i].rx, data.top10[i].tx, data.top10[i].rxk, data.top10[i].txk, data.top10[i].used);
+ printf("t;%d;%u;%"PRIu64";%"PRIu64";%d;%d;%d\n", i, (unsigned int)data.top10[i].date, data.top10[i].rx, data.top10[i].tx, data.top10[i].rxk, data.top10[i].txk, data.top10[i].used);
}
for (i=0;i<=23;i++) {
- printf("h;%d;%d;%"PRIu64";%"PRIu64"\n", i, (int)data.hour[i].date, data.hour[i].rx, data.hour[i].tx);
+ printf("h;%d;%u;%"PRIu64";%"PRIu64"\n", i, (unsigned int)data.hour[i].date, data.hour[i].rx, data.hour[i].tx);
}
}
{
int rxarc = 0, txarc = 0;
- if ( (rxp + txp) > 0 ) {
+ if ( (int)(rxp + txp) > 0 ) {
rxarc = 360 * (rxp / (float)100);
- if ( (rxp + txp) == 100 ) {
+ if ( (int)(rxp + txp) == 100 ) {
txarc = 360 - rxarc;
} else {
txarc = 360 * (txp / (float)100);
gdImageFilledArc(im, x, y, DOUTRAD, DOUTRAD, 0, 360, cbgoffset, 0);
- if ( (rxp + txp) > 0 ) {
+ if ( (int)(rxp + txp) > 0 ) {
gdImageFilledArc(im, x, y, DOUTRAD, DOUTRAD, 270, 270+txarc, ctx, 0);
gdImageFilledArc(im, x, y, DOUTRAD, DOUTRAD, 270, 270+txarc, ctxd, gdEdged|gdNoFill);
gdImageFilledArc(im, x, y, DOUTRAD, DOUTRAD, 270+txarc, 270+txarc+rxarc, crx, 0);
float ratediv;
uint64_t max=1, scaleunit=0;
char buffer[32];
- time_t current;
struct tm *d;
current = time(NULL);
step = 1;
}
- for (i=step; scaleunit*i <= max; i=i+step) {
+ for (i=step; (uint64_t)(scaleunit*i) <= max; i=i+step) {
s = 121 * ((scaleunit * i) / (float)max);
gdImageLine(im, x+36, y+124-s, x+460, y+124-s, cline);
gdImageLine(im, x+36, y+124-((s+prev)/2), x+460, y+124-((s+prev)/2), clinel);
if (s<0) {
s+=24;
}
- sprintf(buffer, "%02d ", s);
+ snprintf(buffer, 32, "%02d ", s);
gdImageString(im, gdFontGetTiny(), x+440-(i*17), y+128, (unsigned char*)buffer, ctext);
drawpole(x+438-(i*17), y, 124, data.hour[s].rx, data.hour[s].tx, max);
}
colorinit();
if (strcmp(data.nick, data.interface)==0) {
- sprintf(buffer, "%s", data.interface);
+ snprintf(buffer, 512, "%s", data.interface);
} else {
- sprintf(buffer, "%s (%s)", data.nick, data.interface);
+ snprintf(buffer, 512, "%s (%s)", data.nick, data.interface);
}
layoutinit(buffer, width, height, showheader, showedge);
offset = 0;
}
- drawdonut(150+offset, 75, rxp, txp);
+ drawdonut(150+offset, 75-headermod, rxp, txp);
textx = 100+offset;
texty = 30-headermod;
txp = txp * mod;
}
- drawdonut(330, 75, rxp, txp);
+ drawdonut(330, 75-headermod, rxp, txp);
textx = 280;
texty = 30-headermod;
offset = 0;
}
- drawdonut(150+offset, 163, rxp, txp);
+ drawdonut(150+offset, 163-headermod, rxp, txp);
textx = 100+offset;
texty = 118-headermod;
txp = txp * mod;
}
- drawdonut(330, 163, rxp, txp);
+ drawdonut(330, 163-headermod, rxp, txp);
textx = 280;
texty = 118-headermod;
colorinit();
if (strcmp(data.nick, data.interface)==0) {
- sprintf(buffer, "%s", data.interface);
+ snprintf(buffer, 512, "%s", data.interface);
} else {
- sprintf(buffer, "%s (%s)", data.nick, data.interface);
+ snprintf(buffer, 512, "%s (%s)", data.nick, data.interface);
}
layoutinit(buffer, width, height, showheader, showedge);
texty = 48-headermod;
/* totals */
- sprintf(buffer, " received: %s (%.1f%%)", getvalue(data.totalrx, data.totalrxk, 14, 1), rxp);
+ snprintf(buffer, 512, " received: %s (%.1f%%)", getvalue(data.totalrx, data.totalrxk, 14, 1), rxp);
gdImageString(im, gdFontGetLarge(), textx, texty, (unsigned char*)buffer, ctext);
- sprintf(buffer, "transmitted: %s (%.1f%%)", getvalue(data.totaltx, data.totaltxk, 14, 1), txp);
+ snprintf(buffer, 512, "transmitted: %s (%.1f%%)", getvalue(data.totaltx, data.totaltxk, 14, 1), txp);
gdImageString(im, gdFontGetLarge(), textx, texty+15, (unsigned char*)buffer, ctext);
- sprintf(buffer, " total: %s", getvalue(data.totalrx+data.totaltx, data.totalrxk+data.totaltxk, 14, 1));
+ snprintf(buffer, 512, " total: %s", getvalue(data.totalrx+data.totaltx, data.totalrxk+data.totaltxk, 14, 1));
gdImageString(im, gdFontGetLarge(), textx, texty+30, (unsigned char*)buffer, ctext);
/* get formated date for yesterday */
strncat(buffer, getvalue(data.day[0].rx+data.day[0].tx, data.day[0].rxk+data.day[0].txk, 10, 1), 32);
gdImageString(im, gdFontGetSmall(), textx, texty+32, (unsigned char*)buffer, ctext);
- sprintf(buffer, "estimated ");
+ snprintf(buffer, 32, "estimated ");
strncat(buffer, getvalue(e_rx, 0, 10, 2), 32);
strcat(buffer, " ");
strncat(buffer, getvalue(e_tx, 0, 10, 2), 32);
colorinit();
if (strcmp(data.nick, data.interface)==0) {
- sprintf(buffer, "%s / hourly", data.interface);
+ snprintf(buffer, 512, "%s / hourly", data.interface);
} else {
- sprintf(buffer, "%s (%s) / hourly", data.nick, data.interface);
+ snprintf(buffer, 512, "%s (%s) / hourly", data.nick, data.interface);
}
layoutinit(buffer, width, height, showheader, showedge);
colorinit();
if (strcmp(data.nick, data.interface)==0) {
- sprintf(buffer, "%s / daily", data.interface);
+ snprintf(buffer, 512, "%s / daily", data.interface);
} else {
- sprintf(buffer, "%s (%s) / daily", data.nick, data.interface);
+ snprintf(buffer, 512, "%s (%s) / daily", data.nick, data.interface);
}
layoutinit(buffer, width, height, showheader, showedge);
e_rx=((data.day[0].rx)/(float)(d->tm_hour*60+d->tm_min))*1440;
e_tx=((data.day[0].tx)/(float)(d->tm_hour*60+d->tm_min))*1440;
}
- sprintf(buffer, " estimated ");
+ snprintf(buffer, 32, " estimated ");
strncat(buffer, getvalue(e_rx, 0, 10, 2), 32);
strcat(buffer, " ");
strncat(buffer, getvalue(e_tx, 0, 10, 2), 32);
colorinit();
if (strcmp(data.nick, data.interface)==0) {
- sprintf(buffer, "%s / monthly", data.interface);
+ snprintf(buffer, 512, "%s / monthly", data.interface);
} else {
- sprintf(buffer, "%s (%s) / monthly", data.nick, data.interface);
+ snprintf(buffer, 512, "%s (%s) / monthly", data.nick, data.interface);
}
layoutinit(buffer, width, height, showheader, showedge);
e_rx=(data.month[0].rx/(float)(mosecs()))*(dmonth(d->tm_mon)*86400);
e_tx=(data.month[0].tx/(float)(mosecs()))*(dmonth(d->tm_mon)*86400);
}
- sprintf(buffer, " estimated ");
+ snprintf(buffer, 32, " estimated ");
strncat(buffer, getvalue(e_rx, 0, 10, 2), 32);
strcat(buffer, " ");
strncat(buffer, getvalue(e_tx, 0, 10, 2), 32);
colorinit();
if (strcmp(data.nick, data.interface)==0) {
- sprintf(buffer, "%s / top 10", data.interface);
+ snprintf(buffer, 512, "%s / top 10", data.interface);
} else {
- sprintf(buffer, "%s (%s) / top 10", data.nick, data.interface);
+ snprintf(buffer, 512, "%s (%s) / top 10", data.nick, data.interface);
}
layoutinit(buffer, width, height, showheader, showedge);
offset = 0;
}
- sprintf(hex, "%c%c", input[(0+offset)], input[(1+offset)]);
- sprintf(dec, "%d", (int)strtol(hex, NULL, 16));
+ snprintf(hex, 3, "%c%c", input[(0+offset)], input[(1+offset)]);
+ snprintf(dec, 4, "%d", (int)strtol(hex, NULL, 16));
rgb[0] = atoi(dec);
- sprintf(hex, "%c%c", input[(2+offset)], input[(3+offset)]);
- sprintf(dec, "%d", (int)strtol(hex, NULL, 16));
+ snprintf(hex, 3, "%c%c", input[(2+offset)], input[(3+offset)]);
+ snprintf(dec, 4, "%d", (int)strtol(hex, NULL, 16));
rgb[1] = atoi(dec);
- sprintf(hex, "%c%c", input[(4+offset)], input[(5+offset)]);
- sprintf(dec, "%d", (int)strtol(hex, NULL, 16));
+ snprintf(hex, 3, "%c%c", input[(4+offset)], input[(5+offset)]);
+ snprintf(dec, 4, "%d", (int)strtol(hex, NULL, 16));
rgb[2] = atoi(dec);
if (debug) {
int declen=0;
if (kb==0){
- sprintf(buffer, "%*s", len, "--");
+ snprintf(buffer, 64, "%*s", len, "--");
} else {
/* try to figure out what unit to use */
if (rate) {
if (kb>=1000000000) { /* 1000*1000*1000 - value >=1000 Gbps -> show in Tbps */
- sprintf(buffer, "%*.*f", len, declen, kb/(float)1000000000); /* 1000*1000*1000 */
+ snprintf(buffer, 64, "%*.*f", len, declen, kb/(float)1000000000); /* 1000*1000*1000 */
} else if (kb>=1000000) { /* 1000*1000 - value >=1000 Mbps -> show in Gbps */
- sprintf(buffer, "%*.*f", len, declen, kb/(float)1000000); /* 1000*1000 */
+ snprintf(buffer, 64, "%*.*f", len, declen, kb/(float)1000000); /* 1000*1000 */
} else if (kb>=1000) {
- sprintf(buffer, "%*.*f", len, declen, kb/(float)1000);
+ snprintf(buffer, 64, "%*.*f", len, declen, kb/(float)1000);
} else {
- sprintf(buffer, "%*"PRIu64"", len, kb);
- }
+ snprintf(buffer, 64, "%*"PRIu64"", len, kb);
+ }
} else {
if (kb>=1048576000) { /* 1024*1024*1000 - value >=1000 GiB -> show in TiB */
- sprintf(buffer, "%*.*f", len, declen, kb/(float)1073741824); /* 1024*1024*1024 */
+ snprintf(buffer, 64, "%*.*f", len, declen, kb/(float)1073741824); /* 1024*1024*1024 */
} else if (kb>=1024000) { /* 1024*1000 - value >=1000 MiB -> show in GiB */
- sprintf(buffer, "%*.*f", len, declen, kb/(float)1048576); /* 1024*1024 */
+ snprintf(buffer, 64, "%*.*f", len, declen, kb/(float)1048576); /* 1024*1024 */
} else if (kb>=1000) {
- sprintf(buffer, "%*.*f", len, declen, kb/(float)1024);
+ snprintf(buffer, 64, "%*.*f", len, declen, kb/(float)1024);
} else {
- sprintf(buffer, "%*"PRIu64"", len, kb);
+ snprintf(buffer, 64, "%*"PRIu64"", len, kb);
}
}
}
char *getimagescale(uint64_t kb, int rate)
{
- static char buffer[6];
+ static char buffer[8];
uint32_t limit[3];
int unit;
if (kb==0) {
- sprintf(buffer, "--");
+ snprintf(buffer, 8, "--");
} else {
if (rate) {
}
if (kb>=limit[2]) {
- sprintf(buffer, "%s", getrateunit(unit, 4));
+ snprintf(buffer, 8, "%s", getrateunit(unit, 4));
} else if (kb>=limit[1]) {
- sprintf(buffer, "%s", getrateunit(unit, 3));
+ snprintf(buffer, 8, "%s", getrateunit(unit, 3));
} else if (kb>=limit[0]) {
- sprintf(buffer, "%s", getrateunit(unit, 2));
+ snprintf(buffer, 8, "%s", getrateunit(unit, 2));
} else {
- sprintf(buffer, "%s", getrateunit(unit, 1));
+ snprintf(buffer, 8, "%s", getrateunit(unit, 1));
}
} else {
if (kb>=1048576000) { /* 1024*1024*1000 - value >=1000 GiB -> show in TiB */
- sprintf(buffer, "%s", getunit(4));
+ snprintf(buffer, 8, "%s", getunit(4));
} else if (kb>=1024000) { /* 1024*1000 - value >=1000 MiB -> show in GiB */
- sprintf(buffer, "%s", getunit(3));
+ snprintf(buffer, 8, "%s", getunit(3));
} else if (kb>=1000) {
- sprintf(buffer, "%s", getunit(2));
+ snprintf(buffer, 8, "%s", getunit(2));
} else {
- sprintf(buffer, "%s", getunit(1));
+ snprintf(buffer, 8, "%s", getunit(1));
}
}
} else {
snprintf(errorstring, 512, "Free diskspace check failed.");
printe(PT_Error);
- exit(1);
+ exit(EXIT_FAILURE);
}
}
}
if ( (type==2) && (kB==0) ){
- sprintf(buffer, "%*s ", len-cfg.unit, "--");
+ snprintf(buffer, 64, "%*s ", len-cfg.unit, "--");
} else {
#if !defined(__OpenBSD__) && !defined(__NetBSD__)
/* try to figure out what unit to use */
if (kB>=1048576000) { /* 1024*1024*1000 - value >=1000 GiB -> show in TiB */
- sprintf(buffer, "%'*.*f %s", len, declen, kB/(float)1073741824, getunit(4)); /* 1024*1024*1024 */
+ snprintf(buffer, 64, "%'*.*f %s", len, declen, kB/(float)1073741824, getunit(4)); /* 1024*1024*1024 */
} else if (kB>=1024000) { /* 1024*1000 - value >=1000 MiB -> show in GiB */
- sprintf(buffer, "%'*.*f %s", len, declen, kB/(float)1048576, getunit(3)); /* 1024*1024 */
+ snprintf(buffer, 64, "%'*.*f %s", len, declen, kB/(float)1048576, getunit(3)); /* 1024*1024 */
} else if (kB>=1000) {
if (type==2) {
declen=0;
}
- sprintf(buffer, "%'*.*f %s", len, declen, kB/(float)1024, getunit(2));
+ snprintf(buffer, 64, "%'*.*f %s", len, declen, kB/(float)1024, getunit(2));
} else {
- sprintf(buffer, "%'*"PRIu64" %s", len, kB, getunit(1));
+ snprintf(buffer, 64, "%'*"PRIu64" %s", len, kB, getunit(1));
}
#else
/* try to figure out what unit to use */
if (kB>=1048576000) { /* 1024*1024*1000 - value >=1000 GiB -> show in TiB */
- sprintf(buffer, "%*.*f %s", len, declen, kB/(float)1073741824, getunit(4)); /* 1024*1024*1024 */
+ snprintf(buffer, 64, "%*.*f %s", len, declen, kB/(float)1073741824, getunit(4)); /* 1024*1024*1024 */
} else if (kB>=1024000) { /* 1024*1000 - value >=1000 MiB -> show in GiB */
- sprintf(buffer, "%*.*f %s", len, declen, kB/(float)1048576, getunit(3)); /* 1024*1024 */
+ snprintf(buffer, 64, "%*.*f %s", len, declen, kB/(float)1048576, getunit(3)); /* 1024*1024 */
} else if (kB>=1000) {
if (type==2) {
declen=0;
}
- sprintf(buffer, "%*.*f %s", len, declen, kB/(float)1024, getunit(2));
+ snprintf(buffer, 64, "%*.*f %s", len, declen, kB/(float)1024, getunit(2));
} else {
- sprintf(buffer, "%*"PRIu64" %s", len, kB, getunit(1));
+ snprintf(buffer, 64, "%*"PRIu64" %s", len, kB, getunit(1));
}
#endif
}
float rate;
if (interval==0) {
- sprintf(buffer, "%*s", len, "n/a");
+ snprintf(buffer, 64, "%*s", len, "n/a");
return buffer;
}
#if !defined(__OpenBSD__) && !defined(__NetBSD__)
/* try to figure out what unit to use */
if (rate>=limit[2]) {
- sprintf(buffer, "%'*.2f %s", len, rate/(float)limit[2], getrateunit(unit, 4));
+ snprintf(buffer, 64, "%'*.2f %s", len, rate/(float)limit[2], getrateunit(unit, 4));
} else if (rate>=limit[1]) {
- sprintf(buffer, "%'*.2f %s", len, rate/(float)limit[1], getrateunit(unit, 3));
+ snprintf(buffer, 64, "%'*.2f %s", len, rate/(float)limit[1], getrateunit(unit, 3));
} else if (rate>=limit[0]) {
- sprintf(buffer, "%'*.2f %s", len, rate/(float)limit[0], getrateunit(unit, 2));
+ snprintf(buffer, 64, "%'*.2f %s", len, rate/(float)limit[0], getrateunit(unit, 2));
} else {
- sprintf(buffer, "%'*.*f %s", len, declen, rate, getrateunit(unit, 1));
+ snprintf(buffer, 64, "%'*.*f %s", len, declen, rate, getrateunit(unit, 1));
}
#else
/* try to figure out what unit to use */
if (rate>=limit[2]) {
- sprintf(buffer, "%*.2f %s", len, rate/(float)limit[2], getrateunit(unit, 4));
+ snprintf(buffer, 64, "%*.2f %s", len, rate/(float)limit[2], getrateunit(unit, 4));
} else if (rate>=limit[1]) {
- sprintf(buffer, "%*.2f %s", len, rate/(float)limit[1], getrateunit(unit, 3));
+ snprintf(buffer, 64, "%*.2f %s", len, rate/(float)limit[1], getrateunit(unit, 3));
} else if (rate>=limit[0]) {
- sprintf(buffer, "%*.2f %s", len, rate/(float)limit[0], getrateunit(unit, 2));
+ snprintf(buffer, 64, "%*.2f %s", len, rate/(float)limit[0], getrateunit(unit, 2));
} else {
- sprintf(buffer, "%*.*f %s", len, declen, rate, getrateunit(unit, 1));
+ snprintf(buffer, 64, "%*.*f %s", len, declen, rate, getrateunit(unit, 1));
}
#endif
#include "misc.h"
#include "traffic.h"
-void trafficmeter(char iface[32], int sampletime)
+void trafficmeter(char iface[], int sampletime)
{
/* received bytes packets errs drop fifo frame compressed multicast */
/* transmitted bytes packets errs drop fifo colls carrier compressed */
/* less than 2 seconds doesn't produce good results */
if (sampletime<2) {
printf("Error: Time for sampling too short.\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
/* read interface info and get values to the first list */
if (!getifinfo(iface)) {
printf("Error: Interface \"%s\" not available, exiting.\n", iface);
- exit(1);
+ exit(EXIT_FAILURE);
}
firstinfo.rx = ifinfo.rx;
firstinfo.tx = ifinfo.tx;
/* wait sampletime and print some nice dots so that the user thinks
something is done :) */
- sprintf(buffer,"Sampling %s (%d seconds average)",iface,sampletime);
- printf("%s",buffer);
+ snprintf(buffer, 256, "Sampling %s (%d seconds average)", iface,sampletime);
+ printf("%s", buffer);
fflush(stdout);
sleep(sampletime/3);
printf(".");
/* read those values again... */
if (!getifinfo(iface)) {
printf("Error: Interface \"%s\" not available, exiting.\n", iface);
- exit(1);
+ exit(EXIT_FAILURE);
}
/* calculate traffic and packets seen between updates */
}
-void livetrafficmeter(char iface[32])
+void livetrafficmeter(char iface[32], int mode)
{
/* received bytes packets errs drop fifo frame compressed multicast */
/* transmitted bytes packets errs drop fifo colls carrier compressed */
uint64_t rxtotal, txtotal, rxptotal, txptotal;
uint64_t rxpmin, txpmin, rxpmax, txpmax;
float rxmin, txmin, rxmax, txmax, rxc, txc;
- int i, len;
+ int i, len=0;
char buffer[256], buffer2[256];
IFINFO previnfo;
printf("Monitoring %s... (press CTRL-C to stop)\n\n", iface);
- printf(" getting traffic...");
- len=21; /* length of previous print */
- fflush(stdout);
+ if (cfg.ostyle != 4) {
+ printf(" getting traffic...");
+ len=21; /* length of previous print */
+ fflush(stdout);
+ }
/* enable signal trap */
intsignal = 0;
if (signal(SIGINT, sighandler) == SIG_ERR) {
perror("signal");
- exit(1);
+ exit(EXIT_FAILURE);
}
/* set some defaults */
rxtotal=txtotal=rxptotal=txptotal=rxpmax=txpmax=0;
- rxpmin=txpmin=-1;
+ rxpmin=txpmin=FP64;
rxmax=txmax=0.0;
rxmin=txmin=-1.0;
/* read /proc/net/dev and get values to the first list */
if (!getifinfo(iface)) {
printf("Error: Interface \"%s\" not available, exiting.\n", iface);
- exit(1);
+ exit(EXIT_FAILURE);
}
/* loop until user gets bored */
/* read those values again... */
if (!getifinfo(iface)) {
printf("Error: Interface \"%s\" not available, exiting.\n", iface);
- exit(1);
+ exit(EXIT_FAILURE);
}
/* calculate traffic and packets seen between updates */
txmax = txc;
}
- if ((rxpmin==-1) || (rxpmin>rxpc)) {
+ if ((rxpmin==FP64) || (rxpmin>rxpc)) {
rxpmin = rxpc;
}
- if ((txpmin==-1) || (txpmin>txpc)) {
+ if ((txpmin==FP64) || (txpmin>txpc)) {
txpmin = txpc;
}
if (rxpmax<rxpc) {
}
/* show the difference in a readable format */
- snprintf(buffer, 128, " rx: %s %5"PRIu64" p/s", getrate(0, rxc, LIVETIME, 15), (uint64_t)rxpc);
- snprintf(buffer2, 128, " tx: %s %5"PRIu64" p/s", getrate(0, txc, LIVETIME, 15), (uint64_t)txpc);
+ if (cfg.ostyle != 0) {
+ if (mode == 0) {
+ snprintf(buffer, 128, " rx: %s %5"PRIu64" p/s", getrate(0, rxc, LIVETIME, 15), (uint64_t)rxpc);
+ snprintf(buffer2, 128, " tx: %s %5"PRIu64" p/s", getrate(0, txc, LIVETIME, 15), (uint64_t)txpc);
+ } else {
+ snprintf(buffer, 128, " rx: %s %s", getrate(0, rxc, LIVETIME, 13), getvalue(0, rintf(rxtotal/(float)1024), 1, 1));
+ snprintf(buffer2, 128, " tx: %s %s", getrate(0, txc, LIVETIME, 13), getvalue(0, rintf(txtotal/(float)1024), 1, 1));
+ }
+ } else {
+ if (mode == 0) {
+ snprintf(buffer, 128, " rx: %s %3"PRIu64" p/s", getrate(0, rxc, LIVETIME, 12), (uint64_t)rxpc);
+ snprintf(buffer2, 128, " tx: %s %3"PRIu64" p/s", getrate(0, txc, LIVETIME, 12), (uint64_t)txpc);
+ } else {
+ snprintf(buffer, 128, " rx: %s %s", getrate(0, rxc, LIVETIME, 12), getvalue(0, rintf(rxtotal/(float)1024), 1, 1));
+ snprintf(buffer2, 128, " tx: %s %s", getrate(0, txc, LIVETIME, 12), getvalue(0, rintf(txtotal/(float)1024), 1, 1));
+ }
+ }
strncat(buffer, buffer2, 127);
- if (len>1) {
+ if (len>1 && cfg.ostyle!=4) {
if (debug) {
printf("\nlinelen: %d\n", len);
} else {
fflush(stdout);
}
}
- printf("%s", buffer);
- fflush(stdout);
+ if (cfg.ostyle!=4) {
+ printf("%s", buffer);
+ fflush(stdout);
+ } else {
+ printf("%s\n", buffer);
+ }
len=strlen(buffer);
}
printf("\n %s / traffic statistics\n\n", iface);
printf(" rx | tx\n");
- printf("--------------------------------------+------------------------\n");
+ printf("--------------------------------------+------------------\n");
printf(" bytes %s", getvalue(0, rintf(rxtotal/(float)1024), 13, 1));
printf(" | %s", getvalue(0, rintf(txtotal/(float)1024), 13, 1));
printf("\n");
- printf("--------------------------------------+------------------------\n");
+ printf("--------------------------------------+------------------\n");
printf(" max %s", getrate(0, rxmax, LIVETIME, 13));
printf(" | %s\n", getrate(0, txmax, LIVETIME, 13));
printf(" average %s", getrate(0, rintf(rxtotal/(float)1024), timespent, 13));
printf(" | %s\n", getrate(0, rintf(txtotal/(float)1024), timespent, 13));
printf(" min %s", getrate(0, rxmin, LIVETIME, 13));
printf(" | %s\n", getrate(0, txmin, LIVETIME, 13));
- printf("--------------------------------------+------------------------\n");
+ printf("--------------------------------------+------------------\n");
printf(" packets %12"PRIu64" | %12"PRIu64"\n", rxptotal, txptotal);
- printf("--------------------------------------+------------------------\n");
+ printf("--------------------------------------+------------------\n");
printf(" max %9"PRIu64" p/s | %9"PRIu64" p/s\n", rxpmax, txpmax);
printf(" average %9"PRIu64" p/s | %9"PRIu64" p/s\n", rxptotal/timespent, txptotal/timespent);
printf(" min %9"PRIu64" p/s | %9"PRIu64" p/s\n", rxpmin, txpmin);
- printf("--------------------------------------+------------------------\n");
-
+ printf("--------------------------------------+------------------\n");
+
if (timespent<=60) {
printf(" time %9"PRIu64" seconds\n", timespent);
} else {
#ifndef TRAFFIC_H
#define TRAFFIC_H
-void trafficmeter(char iface[32], int sampletime);
-void livetrafficmeter(char iface[32]);
+void trafficmeter(char iface[], int sampletime);
+void livetrafficmeter(char iface[], int mode);
#endif
/*
-vnStat - Copyright (c) 2002-09 Teemu Toivola <tst@iki.fi>
+vnStat - Copyright (c) 2002-10 Teemu Toivola <tst@iki.fi>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
int main(int argc, char *argv[]) {
int i;
- int currentarg, update=0, query=1, newdb=0, reset=0, sync=0, merged=0;
+ int currentarg, update=0, query=1, newdb=0, reset=0, sync=0, merged=0, savemerged=0;
int active=-1, files=0, force=0, cleartop=0, rebuildtotal=0, traffic=0;
- int livetraffic=0, defaultiface=1, delete=0;
+ int livetraffic=0, defaultiface=1, delete=0, livemode=0;
char interface[32], dirname[512], nick[32];
- char definterface[32], cfgfile[512], *ifacelist;
+ char definterface[32], cfgfile[512], *ifacelist=NULL;
time_t current;
- DIR *dir;
- struct dirent *di;
+ DIR *dir=NULL;
+ struct dirent *di=NULL;
noexit = 0; /* allow functions to exit in case of error */
debug = 0; /* debug disabled by default */
printf(" -v, --version show version\n");
printf(" -tr, --traffic calculate traffic\n");
printf(" -l, --live show transfer rate in real time\n");
- printf(" --style select output style (0-3)\n");
+ printf(" --style select output style (0-4)\n");
printf(" --delete delete database and stop monitoring\n");
printf(" --iflist show list of available interfaces\n");
printf(" --dbdir select database directory\n");
printf(" --locale set locale\n");
printf(" --config select config file\n");
+ printf(" --savemerged save merged database to current directory\n");
printf(" --showconfig dump config file with current settings\n");
printf(" --testkernel check if the kernel is broken\n");
printf(" --longhelp display this help\n\n");
} 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 > 3 || cfg.ostyle < 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;
}
if (debug)
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) {
cfg.qmode=9;
} else if (strcmp(argv[currentarg],"--xml")==0) {
cfg.qmode=8;
+ } else if (strcmp(argv[currentarg],"--savemerged")==0) {
+ savemerged=1;
} else if ((strcmp(argv[currentarg],"-ru")==0) || (strcmp(argv[currentarg],"--rateunit"))==0) {
if (currentarg+1<argc && isdigit(argv[currentarg+1][0])) {
cfg.rateunit = atoi(argv[currentarg+1]);
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;
}
if (debug)
traffic=1;
query=0;
} else if ((strcmp(argv[currentarg],"-l")==0) || (strcmp(argv[currentarg],"--live")==0)) {
+ if (currentarg+1<argc && argv[currentarg+1][0]!='-') {
+ livemode = atoi(argv[currentarg+1]);
+ if (!isdigit(argv[currentarg+1][0]) || livemode > 1 || 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;
+ }
+ currentarg++;
+ }
livetraffic=1;
query=0;
} else if (strcmp(argv[currentarg],"--force")==0) {
} else if (strcmp(argv[currentarg],"--showconfig")==0) {
printcfgfile();
return 0;
- } else if (strcmp(argv[currentarg],"--showconfig")==0) {
+ } else if (strcmp(argv[currentarg],"--delete")==0) {
delete=1;
query=0;
} else if (strcmp(argv[currentarg],"--iflist")==0) {
}
}
+ /* save merged database */
+ if (merged && savemerged) {
+ data.lastupdated = 0;
+ if (writedb("mergeddb", ".", 2)) {
+ printf("Database saved as \"mergeddb\" in the current directory.\n");
+ }
+ return 0;
+ }
+
/* counter reset */
if (reset) {
if (!spacecheck(dirname) && !force) {
/* live traffic */
if (livetraffic) {
- livetrafficmeter(interface);
+ livetrafficmeter(interface, livemode);
}
/* if nothing was shown previously */
printf("Nothing to do. Use --help for help.\n");
}
}
+
+ /* cleanup */
+ ibwflush();
return 0;
}
close(pidfile);
unlink(cfg.pidfile);
}
+ ibwflush();
return 1;
}
close(pidfile);
unlink(cfg.pidfile);
}
+ ibwflush();
return 1;
}
close(pidfile);
unlink(cfg.pidfile);
}
+ ibwflush();
return 1;
} else {
datalist = datalist->next;
snprintf(errorstring, 512, "SIGHUP received, flushing data to disk and reloading config.");
printe(PT_Info);
cacheflush(dirname);
+ ibwflush();
if (loadcfg(cfgfile)) {
strncpy(dirname, cfg.dbdir, 512);
}
} /* while */
cacheflush(dirname);
+ ibwflush();
/* clean daemon stuff */
if (rundaemon && !debug) {
return; /* already a daemon */
}
- i = fork();
+ i = (int)fork();
if (i<0) { /* fork error */
perror("fork");
- exit(1);
+ exit(EXIT_FAILURE);
}
if (i>0) { /* parent exits */
- exit(0);
+ exit(EXIT_SUCCESS);
}
/* child (daemon) continues */
snprintf(errorstring, 512, "vnStat daemon %s started.", VNSTATVERSION);
if (!printe(PT_Info)) {
printf("Error: Unable to use logfile. Exiting.\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
}
perror("pidfile");
snprintf(errorstring, 512, "pidfile failed, exiting.");
printe(PT_Error);
- exit(1); /* can't open */
+ exit(EXIT_FAILURE); /* can't open */
}
if (lockf(pidfile,F_TLOCK,0)<0) {
perror("pidfile lock");
snprintf(errorstring, 512, "pidfile lock failed, exiting.");
printe(PT_Error);
- exit(1); /* can't lock */
+ exit(EXIT_FAILURE); /* can't lock */
}
/* close all descriptors except lock file */
perror("dup(stdout)");
snprintf(errorstring, 512, "dup(stdout) failed, exiting.");
printe(PT_Error);
- exit(1);
+ exit(EXIT_FAILURE);
}
/* stderr */
if (dup(i) < 0) {
perror("dup(stderr)");
snprintf(errorstring, 512, "dup(stderr) failed, exiting.");
printe(PT_Error);
- exit(1);
+ exit(EXIT_FAILURE);
}
umask(027); /* set newly created file permissions */
perror("chdir(/)");
snprintf(errorstring, 512, "directory change to / failed, exiting.");
printe(PT_Error);
- exit(1);
+ exit(EXIT_FAILURE);
}
/* first instance continues */
- snprintf(str, 10, "%d\n", getpid());
+ snprintf(str, 10, "%d\n", (int)getpid());
/* record pid to lockfile */
if (write(pidfile,str,strlen(str)) < 0) {
perror("write(pidfile)");
snprintf(errorstring, 512, "writing to pidfile %s failed, exiting.", cfg.pidfile);
printe(PT_Error);
- exit(1);
+ exit(EXIT_FAILURE);
}
signal(SIGCHLD,SIG_IGN); /* ignore child */
signal(SIGTTIN,SIG_IGN);
if (cfg.uselogging==1) {
- snprintf(errorstring, 512, "Daemon running with pid %d.", getpid());
+ snprintf(errorstring, 512, "Daemon running with pid %d.", (int)getpid());
printe(PT_Info);
}
}
strncpy(interface, argv[currentarg+1], 32);
interface[31] = '\0';
if (debug)
- printf("Used interface: \"%s\"\n", filename);
+ printf("Used interface: \"%s\"\n", interface);
currentarg++;
continue;
} else {
cfg.rateunit = atoi(argv[currentarg+1]);
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;
}
if (debug)
fclose(pngout);
gdImageDestroy(im);
+ /* cleanup */
+ ibwflush();
+
if (debug)
printf("all done\n");