-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstatistic.c
128 lines (102 loc) · 3.75 KB
/
statistic.c
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
#include "statistic.h"
#include <stdbool.h>
#define MAX_QUERY_SIZE 1000
#define UPDATE_QUERY "update ips set count = count + 1 where ip = '%s' and iface = '%s'; \
select * from ips where ip = '%s' and iface = '%s'"
#define IP_QUERY "select * from ips where ip = '%s'"
#define ADD_QUERY "insert into ips (ip, count, iface) values ('%s', 1, '%s')"
#define RESET_QUERY "delete from ips"
#define ALL_QUERY "select * from ips where iface glob '%s'"
#define BUSY_TIMEOUTS_MS 5000
static int update_callback(void *data, int num_columns,
char **column_values, char **column_names);
static int show_all_callback(void *data, int num_columns,
char **column_values, char **column_names);
static int get_ip_callback(void *data, int num_columns,
char **column_values, char **column_names);
static sqlite3 *db;
void connect_to_db(){
if (db != NULL)
fprintf (stderr, "[DATABASE] Reopening existing connection?");
if (sqlite3_open (DB_NAME, &db) != 0)
fprintf (stderr, "[DATABASE] Unable to connect");
sqlite3_busy_timeout(db, BUSY_TIMEOUTS_MS);
}
void disconnect_from_db(){
sqlite3_close(db);
}
void add_entry(char *ip_address, char *iface){
char query[MAX_QUERY_SIZE];
char *error;
sprintf(query, UPDATE_QUERY, ip_address, iface, ip_address, iface);
bool updated = false;
if (sqlite3_exec (db, query, update_callback, (void *) &updated, &error) != 0){
fprintf (stderr, "[DATABASE] %s at 'add_entry:update'\n", error);
sqlite3_free(error);
}
if (!updated) {
sprintf(query, ADD_QUERY, ip_address, iface);
if (sqlite3_exec (db, query, NULL, NULL, &error) != 0){
fprintf (stderr, "[DATABASE] %s at 'add_entry:insert'\n", error);
sqlite3_free(error);
}
}
}
void print_ip_count(char *ip_address){
char query[MAX_QUERY_SIZE];
char *error;
sprintf(query, IP_QUERY, ip_address);
bool printed = false;
if (sqlite3_exec (db, query, get_ip_callback, &printed, &error) != 0){
fprintf (stderr, "[DATABASE] %s at 'get_ip_count'\n", error);
sqlite3_free(error);
}
if (printed) {
printf ("Ip %s is not contained in database\n", ip_address);
}
}
void print_all_statistics(char *iface){
char query[MAX_QUERY_SIZE];
char *error;
sprintf(query, ALL_QUERY, iface != NULL ? iface : "*");
bool printed = false;
if (sqlite3_exec (db, query, show_all_callback, &printed, &error) != 0){
fprintf (stderr, "[DATABASE] %s at 'show_all_stats'\n", error);
sqlite3_free(error);
return;
}
if (!printed){
printf ("No data yet :(\n");
}
}
void reset_db(){
char query[MAX_QUERY_SIZE];
char *error;
sprintf(query, RESET_QUERY);
if (sqlite3_exec (db, query, NULL, NULL, &error) != 0){
fprintf (stderr, "[DATABASE] %s at 'reset'\n", error);
sqlite3_free(error);
}
}
static int show_all_callback(void *data, int num_columns,
char **column_values, char **column_names){
char *ip_addr = *column_values;
char *count_str = *(column_values + 1);
printf ("%s %s\n", ip_addr, count_str);
*(bool *) data = true;
return 0;
}
static int update_callback(void *data, int num_columns,
char **column_values, char **column_names){
// Set flag that row with given ip was found
*(bool *)data = true;
return 0;
}
static int get_ip_callback(void *data, int num_columns,
char **column_values, char **column_names){
char *ip_addr = *column_values;
char *count_str = *(column_values + 1);
printf ("%s %s\n", ip_addr, count_str);
*(bool *)data = true;
return 0;
}