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
134
135
136
137
|
#include "utils.hpp"
#include <netinet/in.h>
#include <sys/time.h>
#include <algorithm>
#include "cxxstdio.hpp"
#include "extract.hpp"
#include "../poison.hpp"
//---------------------------------------------------
// E-mail check: return 0 (not correct) or 1 (valid).
//---------------------------------------------------
bool e_mail_check(XString email)
{
// athena limits
if (email.size() < 3 || email.size() > 39)
return 0;
// part of RFC limits (official reference of e-mail description)
XString::iterator at = std::find(email.begin(), email.end(), '@');
if (at == email.end())
return 0;
XString username = email.xislice_h(at);
XString hostname = email.xislice_t(at + 1);
if (!username || !hostname)
return 0;
if (hostname.contains('@'))
return 0;
if (hostname.front() == '.' || hostname.back() == '.')
return 0;
if (hostname.contains_seq(".."))
return 0;
if (email.contains_any(" ;"))
return 0;
return email.is_print();
}
//-------------------------------------------------
// Return numerical value of a switch configuration
// on/off, english, français, deutsch, español
//-------------------------------------------------
int config_switch (ZString str)
{
if (str == "on" || str == "yes"
|| str == "oui" || str == "ja"
|| str == "si")
return 1;
if (str == "off" || str == "no"
|| str == "non" || str == "nein")
return 0;
int rv;
if (extract(str, &rv))
return rv;
FPRINTF(stderr, "Fatal: bad option value %s", str);
abort();
}
IP_String ip2str(struct in_addr ip)
{
const uint8_t *p = reinterpret_cast<const uint8_t *>(&ip);
IP_String out;
SNPRINTF(out, 16, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
return out;
}
VString<16> ip2str_extradot(struct in_addr ip)
{
const uint8_t *p = reinterpret_cast<const uint8_t *>(&ip);
VString<16> out;
SNPRINTF(out, 17, "%d.%d.%d.%d.", p[0], p[1], p[2], p[3]);
return out;
}
bool split_key_value(const FString& line, SString *w1, TString *w2)
{
FString::iterator begin = line.begin(), end = line.end();
if (line.startswith("//"))
return false;
if (begin == end)
return false;
if (std::find_if(begin, end,
[](unsigned char c) { return c < ' '; }
) != line.end())
return false;
FString::iterator colon = std::find(begin, end, ':');
if (colon == end)
return false;
*w1 = line.oislice(begin, colon);
++colon;
while (std::isspace(*colon))
++colon;
*w2 = line.oislice(colon, end);
return true;
}
static_assert(sizeof(timestamp_seconds_buffer) == 20, "seconds buffer");
static_assert(sizeof(timestamp_milliseconds_buffer) == 24, "millis buffer");
void stamp_time(timestamp_seconds_buffer& out, const TimeT *t)
{
struct tm when = t ? *t : TimeT::now();
char buf[20];
strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &when);
out = stringish<timestamp_seconds_buffer>(const_(buf));
}
void stamp_time(timestamp_milliseconds_buffer& out)
{
struct timeval tv;
gettimeofday(&tv, NULL);
struct tm when = TimeT(tv.tv_sec);
char buf[24];
strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &when);
sprintf(buf + 19, ".%03d", static_cast<int>(tv.tv_usec / 1000));
out = stringish<timestamp_milliseconds_buffer>(const_(buf));
}
void log_with_timestamp(FILE *out, XString line)
{
if (!line)
{
fputc('\n', out);
return;
}
timestamp_milliseconds_buffer tmpstr;
stamp_time(tmpstr);
fputs(tmpstr.c_str(), out);
fputs(": ", out);
fwrite(line.data(), 1, line.size(), out);
if (line.back() != '\n')
fputc('\n', out);
}
|