-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Utils.h
326 lines (256 loc) · 6.65 KB
/
Utils.h
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
#ifndef _UTILS_H
#define _UTILS_H
#include <unistd.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/file.h>
#include <stdio.h>
#include "String.h"
#include <vector>
#include <map>
using std::vector;
using std::map;
#ifdef _DEBUG
#define DEBUG_ONLY(f) f
#else
#define DEBUG_ONLY(f) ((void)0)
#endif
static const char g_HexDigits[] = "0123456789abcdef";
class CUtils {
public:
CUtils();
virtual ~CUtils();
static CString GetIP(unsigned long addr);
static unsigned long GetLongIP(const CString& sIP);
static CString ChangeDir(const CString& sPath, const CString& sAdd, const CString& sHomeDir);
static int MakeDir(const CString& sPath, mode_t iMode = 0700);
static void PrintError(const CString& sMessage);
static void PrintMessage(const CString& sMessage, bool bStrong = false);
static void PrintPrompt(const CString& sMessage);
static void PrintAction(const CString& sMessage);
static void PrintStatus(bool bSuccess, const CString& sMessage = "");
static CString GetHashPass();
static char* GetPass(const CString& sPrompt);
static bool GetInput(const CString& sPrompt, CString& sRet, const CString& sDefault = "", const CString& sHint = "");
static bool GetBoolInput(const CString& sPrompt, bool bDefault);
static bool GetBoolInput(const CString& sPrompt, bool *pbDefault = NULL);
static bool GetNumInput(const CString& sPrompt, unsigned int& uRet, unsigned int uMin = 0, unsigned int uMax = ~0, unsigned int uDefault = ~0);
static unsigned long long GetMillTime() {
struct timeval tv;
unsigned long long iTime = 0;
gettimeofday(&tv, NULL);
iTime = (unsigned long long) tv.tv_sec * 1000;
iTime += ((unsigned long long) tv.tv_usec / 1000);
return iTime;
}
#ifdef HAVE_LIBSSL
static void GenerateCert(FILE *pOut, bool bEncPrivKey = false);
#endif /* HAVE_LIBSSL */
private:
protected:
};
class CLockFile {
public:
CLockFile() {
m_bCreated = false;
m_fd = 0;
m_pid = 0;
}
CLockFile(const CString& sFile) {
Open(sFile);
}
virtual ~CLockFile() {
if (getpid() == m_pid) {
if (m_fd > -1) {
UnLock();
close(m_fd);
if (m_bCreated) {
unlink(m_sFileName.c_str());
}
}
}
}
void Open(const CString& sFile) {
m_fd = open(sFile.c_str(), O_RDONLY);
m_bCreated = false;
if (m_fd == -1) {
// i must create the file then
m_fd = open(sFile.c_str(), O_RDWR|O_CREAT, 0644);
m_bCreated = true;
}
m_pid = getpid(); // for destructor
m_sFileName = sFile;
}
//! timeout in milliseconds
bool TryExLock(const CString& sLockFile, unsigned long long iTimeout = 0) {
Open(sLockFile);
return TryExLock(iTimeout);
}
bool TryExLock(unsigned long long iTimeout = 0) {
if (iTimeout == 0) {
return Lock(LOCK_EX|LOCK_NB);
}
unsigned long long iNow = CUtils::GetMillTime();
while(true) {
if (Lock(LOCK_EX|LOCK_NB)) {
return true;
}
if ((CUtils::GetMillTime() - iNow) > iTimeout) {
break;
}
usleep(100);
}
return(false);
}
bool TryShLock(unsigned long long iTimeout = 0) {
if (iTimeout == 0) {
return(Lock(LOCK_SH|LOCK_NB));
}
unsigned long long iNow = CUtils::GetMillTime();
while(true) {
if (Lock(LOCK_SH|LOCK_NB)) {
return true;
}
if ((CUtils::GetMillTime() - iNow) > iTimeout) {
break;
}
usleep(100);
}
return false;
}
bool LockEx() { return Lock(LOCK_EX); }
bool LockSh() { return Lock(LOCK_SH); }
bool UnLock() { return Lock(LOCK_UN); }
private:
bool Lock(int iOperation) {
if (m_fd == -1) {
return false;
}
if (::flock(m_fd, iOperation) != 0) {
return false;
}
return true;
}
int m_fd;
int m_pid;
bool m_bCreated;
CString m_sFileName;
};
class CException {
public:
typedef enum {
EX_Shutdown,
EX_BadModVersion,
} EType;
CException(EType e) {
m_eType = e;
}
virtual ~CException() {}
EType GetType() const { return m_eType; }
private:
protected:
EType m_eType;
};
class CTable : public vector<map<CString, CString>* > {
public:
CTable();
virtual ~CTable();
bool AddColumn(const CString& sName);
unsigned int AddRow();
bool SetCell(const CString& sColumn, const CString& sValue, unsigned int uRowIdx = ~0);
bool GetLine(unsigned int uIdx, CString& sLine);
unsigned int GetColumnWidth(unsigned int uIdx);
private:
protected:
vector<CString> m_vsHeaders;
map<CString, unsigned int> m_msuWidths; // Used to cache the width of a column
};
#ifdef HAVE_LIBSSL
#include <openssl/blowfish.h>
#include <openssl/md5.h>
//! does Blowfish w/64 bit feedback, no padding
class CBlowfish {
public:
/**
* @sPassword key to encrypt with
* @iEncrypt encrypt method (BF_DECRYPT or BF_ENCRYPT)
* @sIvec what to set the ivector to start with, default sets it all 0's
*/
CBlowfish(const CString & sPassword, int iEncrypt, const CString & sIvec = "");
~CBlowfish();
//! output must be freed
static unsigned char *MD5(const unsigned char *input, u_int ilen);
//! returns an md5 of the CString (not hex encoded)
static CString MD5(const CString & sInput, bool bHexEncode = false);
//! output must be the same size as input
void Crypt(unsigned char *input, unsigned char *output, u_int ibytes);
//! must free result
unsigned char * Crypt(unsigned char *input, u_int ibytes);
CString Crypt(const CString & sData);
private:
unsigned char *m_ivec;
BF_KEY m_bkey;
int m_iEncrypt, m_num;
};
#endif /* HAVE_LIBSSL */
#define RF_BUFF 4096
inline bool ReadFile(const CString & sFilename, CString & sLine) {
char inbuff[RF_BUFF];
int bytes;
// clear ourselves out
sLine.clear();
FILE *f = fopen(sFilename.c_str(), "r");
if (!f) {
return false;
}
while((bytes = fread(inbuff, sizeof(char), RF_BUFF, f)) > 0) {
sLine.append(inbuff, bytes);
}
fclose(f);
if (bytes < 0) {
return false;
}
return true;
}
inline bool WriteFile(const CString & sFilename, const CString & sData) {
FILE *f = fopen(sFilename.c_str(), "w");
if (!f) {
return false;
}
int iRet = fwrite(sData.data(), sizeof(char), sData.length(), f);
fclose(f);
if (iRet <= 0) {
return false;
}
return true;
}
inline bool ReadLine(const CString & sData, CString & sLine, u_int & iPos) {
sLine.clear();
if (iPos >= sData.length()) {
return false;
}
u_int iFind = sData.find("\n", iPos);
if (iFind == CString::npos) {
sLine = sData.substr(iPos, (sData.length() - iPos));
iPos = CString::npos;
return true;
}
sLine = sData.substr(iPos, (iFind - iPos)) + "\n";
iPos = iFind + 1;
return true;
}
inline CString Lower(const CString & sLine) {
CString sRet;
for(u_int a = 0; a < sLine.length(); a++) {
sRet += tolower(sLine[a]);
}
return sRet;
}
inline CString Upper(const CString & sLine) {
CString sRet;
for(u_int a = 0; a < sLine.length(); a++) {
sRet += toupper(sLine[a]);
}
return sRet;
}
#endif // !_UTILS_H