aboutsummaryrefslogtreecommitdiff
path: root/fsbm.cpp
blob: 1daa23969f29664284cc147a220af7c669c3663f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "config.h"
#include "statistics.hpp"
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <sstream>

#include <curses.h>
#include <getopt.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <unistd.h>

#define PACKAGE "yo"
#define PACKAGE_STRING "yo mamma"

// Externs
extern int optind, opterr, optopt;

volatile bool quit = false;

void endHandler(int signum) {
    quit = true;
}

void formatBandwidth(double bytesPerSecond, bool showBits) {
    const char* prefixes[] = { "", "k", "M", "G", "T", "P", "E", "Z", "Y" };

    // Calculate the value
    double value;
    const char* unit;
    if (showBits){
       value = bytesPerSecond * 8;
       unit = "b/s";
    }
    else {
	   value = bytesPerSecond;
	   unit = "B/s";
    }

    // Choose the prefix
    unsigned prefix = 0;
    while (prefix < (sizeof(prefixes) / sizeof(const char*)) && value > 1000.) {
	   value /= 1000.;
	   ++prefix;
    }

    // Format the string
    std::cout << std::setprecision(2) << value << " " << prefixes[prefix] << unit;

}

int main(int argc, char **argv) {
    int retval = EXIT_SUCCESS;

	// parse the command line
    int c; 

    bool useBits = false;
    int interval = 10 * 100000;

      while ((c = getopt (argc, argv, "bi:hv")) != -1)
    switch (c)
        {
        case 'b':
            useBits = true;
            break;
        case 'i':
            // Magic numbers? fuck it that's not a magic number, that's a 'real' number.
            interval = atoi(optarg) * 100000;
            break;
        case 'h':
            std::cout << "USAGE: fsbm, -b specifies bits, -i sets interval in 10ths of seconds, 1 sec default\n";
            exit(EXIT_SUCCESS);
            break;
        case 'v':
            std::cout << "Version 1\n";
            exit(EXIT_SUCCESS);
            break;
        case '?':
            std::cerr << "bad flag\n";
            break;
        default:  
            exit(EXIT_FAILURE);
      }
       
	// Catch SIGINT
	signal(SIGINT, endHandler);



	// Create a socket (for ioctls)
	int sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (!sock)  {
		std::cerr  << "cannot open socket\n";
        exit(EXIT_FAILURE);
	}

	// Initialize curses
	   
	statistics::Reader statisticsReader;
    statisticsReader.update();
	while (!quit) {
        
		// Update the statistics
		statisticsReader.update();

		for (statistics::Reader::Interfaces::const_iterator 
			interface = statisticsReader.getInterfaces().begin();
			interface != statisticsReader.getInterfaces().end(); 
			++interface) {
		    
		    std::cout << interface->getName() << " (";
            formatBandwidth(interface->getReceiveSpeed(), useBits);
            std::cout << ", ";
            formatBandwidth(interface->getTransmitSpeed(), useBits);
            std::cout << ")";

		}
        std::cout << "\n";
        usleep(interval);



    }
    return retval;
}