]> git.stg.codes - stg.git/blob - stglibs/common.lib/common.cpp
Minor fix.
[stg.git] / stglibs / common.lib / common.cpp
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Date: 27.10.2002
19  */
20
21 /*
22  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
23  */
24
25  /*
26  $Revision: 1.42 $
27  $Date: 2010/11/08 10:11:19 $
28  $Author: faust $
29  */
30
31 // For old and dub systems
32 // Like FreeBSD4
33 #include <sys/types.h>
34 #include <sys/time.h>
35 #include <unistd.h>
36
37 #include <sys/select.h>
38
39 #ifdef WIN32
40 #include <winsock2.h>
41 #else
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45 #include <sys/select.h>
46 #endif
47
48 #include <iconv.h>
49
50 #include <cstdlib>
51 #include <cstdarg>
52 #include <cstdio>
53 #include <cstring>
54 #include <cerrno>
55 #include <cassert>
56
57 #include "stg/common.h"
58
59 #ifndef INET_ADDRSTRLEN
60 #   define INET_ADDRSTRLEN 16
61 #endif
62
63 namespace
64 {
65 //---------------------------------------------------------------------------
66 unsigned char koi2win[] = {
67         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
68         0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
69         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
70         0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
71         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
72         0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
73         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
74         0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
75         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
76         0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
77         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
78         0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
79         0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
80         0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
81         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
82         0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
83         0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
84         0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
85         0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
86         0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
87         0xA0, 0xA1, 0xA2, 0xB8, 0xBA, 0xA5, 0xB3, 0xBF,
88         0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xB4, 0xAE, 0xAF,
89         0xB0, 0xB1, 0xB2, 0xA8, 0xAA, 0xB5, 0xB2, 0xAF,
90         0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xA5, 0xBE, 0xBF,
91         0xFE, 0xE0, 0xE1, 0xF6, 0xE4, 0xE5, 0xF4, 0xE3,
92         0xF5, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE,
93         0xEF, 0xFF, 0xF0, 0xF1, 0xF2, 0xF3, 0xE6, 0xE2,
94         0xFC, 0xFB, 0xE7, 0xF8, 0xFD, 0xF9, 0xF7, 0xFA,
95         0xDE, 0xC0, 0xC1, 0xD6, 0xC4, 0xC5, 0xD4, 0xC3,
96         0xD5, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE,
97         0xCF, 0xDF, 0xD0, 0xD1, 0xD2, 0xD3, 0xC6, 0xC2,
98         0xDC, 0xDB, 0xC7, 0xD8, 0xDD, 0xD9, 0xD7, 0xDA};
99
100
101 unsigned char win2koi[] = {
102         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
103         0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
104         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
105         0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
106         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
107         0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
108         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
109         0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
110         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
111         0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
112         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
113         0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
114         0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
115         0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
116         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
117         0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
118         0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
119         0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
120         0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
121         0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
122         0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xBD, 0xA6, 0xA7,
123         0xB3, 0xA9, 0xB4, 0xAB, 0xAC, 0xAD, 0xAE, 0xB7,
124         0xB0, 0xB1, 0xB6, 0xA6, 0xAD, 0xB5, 0xB6, 0xB7,
125         0xA3, 0xB9, 0xA4, 0xBB, 0xBC, 0xBD, 0xBE, 0xA7,
126         0xE1, 0xE2, 0xF7, 0xE7, 0xE4, 0xE5, 0xF6, 0xFA,
127         0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0,
128         0xF2, 0xF3, 0xF4, 0xF5, 0xE6, 0xE8, 0xE3, 0xFE,
129         0xFB, 0xFD, 0xFF, 0xF9, 0xF8, 0xFC, 0xE0, 0xF1,
130         0xC1, 0xC2, 0xD7, 0xC7, 0xC4, 0xC5, 0xD6, 0xDA,
131         0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0,
132         0xD2, 0xD3, 0xD4, 0xD5, 0xC6, 0xC8, 0xC3, 0xDE,
133         0xDB, 0xDD, 0xDF, 0xD9, 0xD8, 0xDC, 0xC0, 0xD1};
134 }
135
136 #ifdef WIN32
137 //-----------------------------------------------------------------------------
138 const char * inet_ntop(int af, const void * src, char * dst, unsigned long length)
139 {
140 struct sockaddr_in addr;
141 addr.sin_family = af;
142 addr.sin_port = 0;
143 memcpy(&addr.sin_addr.s_addr, src, sizeof(addr.sin_addr.s_addr));
144 if (WSAAddressToStringA(reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr), 0, dst, &length))
145     {
146     return NULL;
147     }
148 return dst;
149 }
150 //-----------------------------------------------------------------------------
151 int inet_pton(int af, const char * src, void * dst)
152 {
153 // Fuck you Microsoft!
154 // Why the hell not to use const char *?
155 size_t slen = strlen(src);
156 char * buf = new char[slen + 1];
157 strncpy(buf, src, slen + 1);
158 buf[slen] = 0;
159 struct sockaddr_in addr;
160 addr.sin_family = af;
161 addr.sin_port = 0;
162 addr.sin_addr.s_addr = 0;
163 int length = sizeof(addr);
164 if (WSAStringToAddressA(buf, af, 0, reinterpret_cast<struct sockaddr *>(&addr), &length))
165     {
166     delete[] buf;
167     return -1;
168     }
169 memcpy(dst, &addr, sizeof(addr));
170 delete[] buf;
171 return 1;
172 }
173 #endif
174 //-----------------------------------------------------------------------------
175 int strtodouble2(const char * s, double &a)
176 {
177 char *res;
178
179 a = strtod(s, &res);
180
181 if (*res != 0)
182     return EINVAL;
183
184 return 0;
185 }
186 //-----------------------------------------------------------------------------
187 #ifdef DEBUG
188 int printfd(const char * __file__, const char * fmt, ...)
189 #else
190 int printfd(const char *, const char *, ...)
191 #endif
192 {
193 #ifdef DEBUG
194 char buff[1024];
195
196 time_t t = time(NULL);
197
198 va_list vl;
199 va_start(vl, fmt);
200 vsnprintf(buff, sizeof(buff), fmt, vl);
201 va_end(vl);
202
203 printf("%18s > %s > ", __file__, LogDate(t)+11);
204 printf("%s", buff);
205
206 #endif
207 return 0;
208 }
209 //-----------------------------------------------------------------------------
210 int strprintf(std::string * str, const char * fmt, ...)
211 {
212 char buff[1024];
213
214 va_list vl;
215 va_start(vl, fmt);
216 int n = vsnprintf(buff, sizeof(buff), fmt, vl);
217 va_end(vl);
218 buff[1023] = 0;
219 *str = buff;
220
221 return n;
222 }
223 //-----------------------------------------------------------------------------
224 const char *IntToKMG(int64_t a, int stat)
225 {
226 static const double K = 1024;
227 static const double M = 1024 * 1024;
228 static const double G = 1024 * 1024 * 1024;
229 static char str[30];
230 double value = a;
231
232 switch (stat)
233     {
234     case ST_B:
235         #ifdef __WIN32__
236         sprintf(str, "%Ld", a);
237         #else
238         sprintf(str, "%lld", a);
239         #endif
240         break;
241     case ST_KB:
242         sprintf(str, "%.2f kb", value / K);
243         break;
244     case ST_MB:
245         sprintf(str, "%.2f Mb", value / M);
246         break;
247     default:
248         if (a > G)
249             {
250             sprintf(str, "%.2f Gb", value / G);
251             return &str[0];
252             }
253         if (a < -G)
254             {
255             sprintf(str, "%.2f Gb", value / G);
256             return &str[0];
257             }
258         if (a > M)
259             {
260             sprintf(str, "%.2f Mb", value / M);
261             return &str[0];
262             }
263         if (a < -M)
264             {
265             sprintf(str, "%.2f Mb", value / M);
266             return &str[0];
267             }
268
269         sprintf(str, "%.2f kb", value / K);
270         break;
271     }
272 return str;
273 }
274 //---------------------------------------------------------------------------
275 void KOIToWin(const char * s1, char * s2, int l)
276 {
277 unsigned char t;
278 for (int j = 0; j < l; j++)
279     {
280     t = s1[j];
281     s2[j] = koi2win[t];
282
283     if (s1[j] == 0)
284         break;
285     }
286 }
287 //---------------------------------------------------------------------------
288 void WinToKOI(const char * s1, char * s2, int l)
289 {
290 unsigned char t;
291 for (int j = 0; j < l; j++)
292     {
293     t = s1[j];
294     s2[j] = win2koi[t];
295
296     if (s1[j] == 0)
297         break;
298     }
299 }
300 //---------------------------------------------------------------------------
301 void KOIToWin(const std::string & s1, std::string * s2)
302 {
303 s2->erase(s2->begin(), s2->end());
304 unsigned char t;
305 s2->reserve(s1.length());
306 for (int j = 0; j < (int)s1.length(); j++)
307     {
308     t = s1[j];
309     s2->push_back(koi2win[t]);
310     }
311 }
312 //---------------------------------------------------------------------------
313 void WinToKOI(const std::string & s1, std::string * s2)
314 {
315 s2->erase(s2->begin(), s2->end());
316 unsigned char t;
317 s2->reserve(s1.length());
318 for (int j = 0; j < (int)s1.length(); j++)
319     {
320     t = s1[j];
321     s2->push_back(win2koi[t]);
322     }
323 }
324 //---------------------------------------------------------------------------
325 void Encode12str(std::string & dst, const std::string & src)
326 {
327 dst.erase(dst.begin(), dst.end());
328 for (size_t i = 0; i < src.length(); i++)
329     {
330     dst.push_back('a' + (src[i] & 0x0f));
331     dst.push_back('a' + ((src[i] & 0xf0) >> 4));
332     }
333 }
334 //---------------------------------------------------------------------------
335 void Decode21str(std::string & dst, const std::string & src)
336 {
337 dst.erase(dst.begin(), dst.end());
338 for (size_t i = 0; i < src.length() / 2; i++)
339     {
340     char c1 = src[i * 2];
341     char c2 = src[i * 2 + 1];
342
343     c1 -= 'a';
344     c2 -= 'a';
345
346     dst.push_back(static_cast<char>(c1 + (c2 << 4)));
347     }
348 }
349 //---------------------------------------------------------------------------
350 std::string Encode12str(const std::string & src)
351 {
352 std::string res;
353 Encode12str(res, src);
354 return res;
355 }
356 //---------------------------------------------------------------------------
357 std::string Decode21str(const std::string & src)
358 {
359 std::string res;
360 Decode21str(res, src);
361 return res;
362 }
363 //---------------------------------------------------------------------------
364 void Encode12(char * dst, const char * src, size_t srcLen)
365 {
366 for (size_t i = 0; i <= srcLen; i++)
367     {
368     char c1 = src[i] & 0x0f;
369     char c2 = (src[i] & 0xf0) >> 4;
370
371     c1 += 'a';
372     c2 += 'a';
373
374     dst[i * 2] = c1;
375     dst[i * 2 + 1] = c2;
376     }
377 dst[srcLen * 2] = 0;
378 }
379 //---------------------------------------------------------------------------
380 void Decode21(char * dst, const char * src)
381 {
382 for (size_t i = 0; ; i++)
383     {
384     if (src[i * 2] == 0)
385         break;
386
387     char c1 = src[i * 2];
388     char c2 = src[i * 2 + 1];
389
390     c1 -= 'a';
391     c2 -= 'a';
392
393     dst[i] = static_cast<char>(c1 + (c2 << 4));
394     }
395 dst[strlen(src) / 2] = 0;
396 }
397 //---------------------------------------------------------------------------
398 int ParseIPString(const char * str, uint32_t * ips, int maxIP)
399 {
400 /*
401  *Function Name:ParseIPString
402  *
403  *Parameters:
404  ÓÔÒÏËÁ ÄÌÑ ÒÁÚÂÏÒÁ É ÍÁÓÓÉ× ËÕÄÁ ÚÁÎÏÓÉÔØ ÐÏÌÕÞÅÎÎÙÅ ÁÄÒÅÓÁ
405  *
406  *Description:
407  îÁ ×ÈÏÄÅ ÄÏÌÖÎÁ ÂÙÔØ ÓÔÒÏËÁ ×ÉÄÁ "ip1,ip2,ip3" ÉÌÉ "*"
408  ÷ ÐÅÒ×ÏÍ ÓÌÕÞÁÅ × ÍÁÓÓÉ× ÚÁÎÏÓÑÔÓÑ ÒÁÚÏÂÒÁÎÎÙÅ ÁÄÒÅÓÁ.
409  åÓÌÉ ÉÈ ÍÅÎØÛÅ MAX_IP?, ÔÏ ÐÏÓÌÅÄÎÉÊ ÁÄÒÅÓ ÂÕÄÅÔ 255.255.255.255
410  åÓÌÉ ÓÔÒÏËÁ * , ÔÏ ÐÅÒ×ÁÙÊ ÁÄÒÅÓ ÂÕÄÅÔ 0.0.0.0, Ô.Å. ÌÀÂÏÊ
411  *
412  *Returns: 0 ÅÓÌÉ ×ÓÅ ïë
413  *
414  */
415
416 char p[255];
417 char * p1, *pp;
418 int n = 0;
419
420 strncpy(p, str, 254);
421 pp = p;
422
423 memset(ips, 0xFF, sizeof(unsigned long) * maxIP);
424
425 if (str[0] == '*' && strlen(str) == 1)
426     {
427     ips[0] = 0;
428     return 0;
429     }
430
431 for (int i = 0; i < maxIP; i++)
432     {
433     p1 = strtok(pp, ",\n ");
434     pp = NULL;
435
436     if (p1 == NULL && n == 0)// ÕËÁÚÁÔÅÌØ ÎÕÌØ É ÐÒÏÞÉÔÁÎÏ ÁÄÒÅÓÏ× ÔÏÖÅ ÎÏÌØ
437         {
438         return EINVAL;
439         }
440
441     if (p1 == NULL && n)
442         {
443         return 0;
444         }
445
446     struct in_addr in;
447     if (inet_pton(AF_INET, p1, &in) != 1)
448         {
449         //printf("INADDR_NONE\n");
450         return EINVAL;
451         }
452
453     ips[n] = in.s_addr;
454
455     /*if (ips[n] == INADDR_NONE)
456         return EINVAL;*/
457
458     n++;
459
460     if (n >= maxIP)
461         return 0;
462
463     }
464
465 return 0;
466 }
467 //-----------------------------------------------------------------------------
468 int DaysInCurrentMonth()
469 {
470 time_t t = time(NULL);
471
472 struct tm * lt = localtime(&t);
473
474 return DaysInMonth(lt->tm_year, lt->tm_mon);
475 }
476 //-----------------------------------------------------------------------------
477 int DaysInMonth(unsigned year, unsigned mon)
478 {
479 assert(mon < 12 && "Month number should be 0 - 11");
480 switch (mon)
481     {
482     case 0: return 31;  //jan
483     case 1:
484         if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
485             return 29;
486         return 28;      //feb
487     case 2: return 31;  //mar
488     case 3: return 30;  //apr
489     case 4: return 31;  //may
490     case 5: return 30;  //june
491     case 6: return 31;  //jule
492     case 7: return 31;  //aug
493     case 8: return 30;  //sep
494     case 9: return 31;  //oct
495     case 10: return 30; //nov
496     case 11: return 31; //dec
497     }
498 return -1; // We will never reach here
499 }
500 //-----------------------------------------------------------------------------
501 int Min8(int a)
502 {
503 /*
504 æÕÎËÃÉÑ ×ÏÚ×ÒÁÝÁÅÔ ÎÁÉÍÅÎØÛÅÅ ÞÉÓÌÏ ËÒÁÔÎÏÅ 8-ÍÉ ÂÏÌØÛÅÅ ÉÌÉ ÒÁ×ÎÏÅ ÚÁÄÁÎÎÏÍÕ
505  * */
506 if (a % 8 == 0)
507     return a;
508
509 return a + (8 - a % 8);
510 }
511 //-----------------------------------------------------------------------------
512 /*char * inet_ntostr(unsigned long ip)
513 {
514 struct in_addr addr = {ip};
515 return inet_ntoa(addr);
516 }*/
517 //-----------------------------------------------------------------------------
518 std::string inet_ntostring(uint32_t ip)
519 {
520     char buf[INET_ADDRSTRLEN + 1];
521     return inet_ntop(AF_INET, &ip, buf, INET_ADDRSTRLEN);
522 }
523 //-----------------------------------------------------------------------------
524 uint32_t inet_strington(const std::string & value)
525 {
526     uint32_t result;
527
528     if (inet_pton(AF_INET, value.c_str(), &result) <= 0)
529         return 0;
530
531     return result;
532 }
533 //-----------------------------------------------------------------------------
534 std::string TimeToString(time_t time)
535 {
536 struct tm brokenTime;
537
538 brokenTime.tm_wday = 0;
539 brokenTime.tm_yday = 0;
540 brokenTime.tm_isdst = 0;
541
542 gmtime_r(&time, &brokenTime);
543
544 char buf[32];
545 strftime(buf, 32, "%Y-%m-%d %H:%M:%S", &brokenTime);
546
547 return buf;
548 }
549 //-----------------------------------------------------------------------------
550 int ParseTariffTimeStr(const char * str, int &h1, int &m1, int &h2, int &m2)
551 {
552 char hs1[10], ms1[10], hs2[10], ms2[10];
553 char s1[25], s2[25];
554 char ss[49];
555 char *p1, *p2;
556
557 strncpy(ss, str, 48);
558
559 p1 = strtok(ss, "-");
560 if (!p1)
561     return -1;
562
563 strncpy(s1, p1, 24);
564
565 p2 = strtok(NULL, "-");
566 if (!p2)
567     return -1;
568
569 strncpy(s2, p2, 24);
570
571 p1 = strtok(s1, ":");
572 if (!p1)
573     return -1;
574
575 strncpy(hs1, p1, 9);
576
577 p2 = strtok(NULL, ":");
578 if (!p2)
579     return -1;
580
581 strncpy(ms1, p2, 9);
582
583 p1 = strtok(s2, ":");
584 if (!p1)
585     return -1;
586
587 strncpy(hs2, p1, 9);
588
589 p2 = strtok(NULL, ":");
590 if (!p2)
591     return -1;
592
593 strncpy(ms2, p2, 9);
594
595 if (str2x(hs1, h1) != 0)
596     return -1;
597
598 if (str2x(ms1, m1) != 0)
599     return -1;
600
601 if (str2x(hs2, h2) != 0)
602     return -1;
603
604 if (str2x(ms2, m2) != 0)
605     return -1;
606
607 return 0;
608 }
609 /*//---------------------------------------------------------------------------
610 bool IsDigit(char c)
611 {
612 if (c >= '0' && c <= '9')
613     return true;
614 return false;
615 }
616 //-----------------------------------------------------------------------------
617 bool IsAlpha(char c)
618 {
619 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
620     return true;
621 return false;
622 }*/
623 //-----------------------------------------------------------------------------
624 const char * LogDate(time_t t)
625 {
626 static char s[32];
627 struct tm * tt = localtime(&t);
628
629 snprintf(s, 20, "%d-%s%d-%s%d %s%d:%s%d:%s%d",
630          tt->tm_year + 1900,
631          tt->tm_mon + 1 < 10 ? "0" : "", tt->tm_mon + 1,
632          tt->tm_mday    < 10 ? "0" : "", tt->tm_mday,
633          tt->tm_hour    < 10 ? "0" : "", tt->tm_hour,
634          tt->tm_min     < 10 ? "0" : "", tt->tm_min,
635          tt->tm_sec     < 10 ? "0" : "", tt->tm_sec);
636
637 return s;
638 }
639 //-----------------------------------------------------------------------------
640 uint32_t CalcMask(uint32_t msk)
641 {
642 if (msk >= 32) return 0xFFffFFff;
643 if (msk == 0) return 0;
644 return htonl(0xFFffFFff << (32 - msk));
645 }
646 //---------------------------------------------------------------------------
647 void TouchFile(const std::string & fileName)
648 {
649 FILE * f = fopen(fileName.c_str(), "w");
650 if (f)
651     fclose(f);
652 }
653 //---------------------------------------------------------------------------
654 #ifdef WIN32
655 void EncodeStr(char * str, unsigned long serial, int useHDD)
656 {
657 int len = strlen(str);
658 char stren[100];
659 int i, j = 0;
660 char c1, c2;
661 char serial_c[sizeof(serial)];
662 memcpy(serial_c, &serial, sizeof(serial));
663
664 for (i = 0; i < len; i++)
665     {
666     if (!useHDD)
667         str[i] = str[i]^49;
668     else
669         {
670         str[i] = str[i]^serial_c[j%sizeof(serial)];
671         j++;
672         }
673     }
674
675 for (i = 0; i < 2*len; i++)
676     {
677     if (i%2)
678         {
679         c1 = (str[i/2] >> 4);
680         c1 = c1 + 50;
681         stren[i] = c1;
682         }
683     else
684         {
685         c2 = (str[i/2] & 0x0f);
686         c2 += 50;
687         stren[i] = c2;
688         }
689     }
690 stren[i] = 0;
691 strcpy(str, stren);
692 }
693 //---------------------------------------------------------------------------
694 void DecodeStr(char * str, unsigned long serial, int useHDD)
695 {
696 int len = strlen(str);
697 char strdc[100];
698 int i, j = 0;
699 char c1, c2;
700 char serial_c[sizeof(serial)];
701 memcpy(serial_c, &serial, sizeof(serial));
702
703 for (i = 0; i < len; i += 2)
704     {
705     c1 = (str[i] - 50);
706     c2 = (str[i+1] - 50)<<4;
707     strdc[i/2] = c1+c2;
708     }
709 for (i = 0; i < len/2; i++)
710     {
711     if (!useHDD)
712         strdc[i] = strdc[i]^49;
713     else
714         {
715         strdc[i] = strdc[i]^serial_c[j%sizeof(serial)];
716         j++;
717         }
718     }
719 strdc[i] = 0;
720 strcpy(str, strdc);
721 }
722 //---------------------------------------------------------------------------
723 #endif //WIN32
724 void SwapBytes(uint16_t & value)
725 {
726     value = static_cast<uint16_t>((value >> 8) |
727                                   (value << 8));
728 }
729 //---------------------------------------------------------------------------
730 void SwapBytes(uint32_t & value)
731 {
732     value = static_cast<uint32_t>((value >> 24) |
733                                   ((value << 8) &  0x00FF0000L) |
734                                   ((value >> 8) &  0x0000FF00L) |
735                                   (value << 24));
736 }
737 //---------------------------------------------------------------------------
738 void SwapBytes(uint64_t & value)
739 {
740     value = static_cast<uint64_t>((value >> 56) |
741                                   ((value << 40) & 0x00FF000000000000LL) |
742                                   ((value << 24) & 0x0000FF0000000000LL) |
743                                   ((value << 8)  & 0x000000FF00000000LL) |
744                                   ((value >> 8)  & 0x00000000FF000000LL) |
745                                   ((value >> 24) & 0x0000000000FF0000LL) |
746                                   ((value >> 40) & 0x000000000000FF00LL) |
747                                   (value << 56));
748 }
749 //---------------------------------------------------------------------------
750 void SwapBytes(int16_t & value)
751 {
752     uint16_t temp = value;
753     SwapBytes(temp);
754     value = temp;
755 }
756 //---------------------------------------------------------------------------
757 void SwapBytes(int32_t & value)
758 {
759     uint32_t temp = value;
760     SwapBytes(temp);
761     value = temp;
762 }
763 //---------------------------------------------------------------------------
764 void SwapBytes(int64_t & value)
765 {
766     uint64_t temp = value;
767     SwapBytes(temp);
768     value = temp;
769 }
770 //---------------------------------------------------------------------------
771 int str2x(const std::string & str, int32_t & x)
772 {
773 x = static_cast<int32_t>(strtol(str.c_str(), NULL, 10));
774
775 if (errno == ERANGE)
776     return -1;
777
778 return 0;
779 }
780 //---------------------------------------------------------------------------
781 int str2x(const std::string & str, uint32_t & x)
782 {
783 x = static_cast<uint32_t>(strtoul(str.c_str(), NULL, 10));
784
785 if (errno == ERANGE)
786     return -1;
787
788 return 0;
789 }
790 #ifndef WIN32
791 //---------------------------------------------------------------------------
792 int str2x(const std::string & str, int64_t & x)
793 {
794 x = strtoll(str.c_str(), NULL, 10);
795
796 if (errno == ERANGE)
797     return -1;
798
799 return 0;
800 }
801 //---------------------------------------------------------------------------
802 int str2x(const std::string & str, uint64_t & x)
803 {
804 x = strtoull(str.c_str(), NULL, 10);
805
806 if (errno == ERANGE)
807     return -1;
808
809 return 0;
810 }
811 #endif
812 //---------------------------------------------------------------------------
813 const std::string & x2str(uint32_t x, std::string & s)
814 {
815 return unsigned2str(x, s);
816 }
817 //---------------------------------------------------------------------------
818 const std::string & x2str(uint64_t x, std::string & s)
819 {
820 return unsigned2str(x, s);
821 }
822 //---------------------------------------------------------------------------
823 const std::string & x2str(double x, std::string & s)
824 {
825 char buf[256];
826 snprintf(buf, sizeof(buf), "%f", x);
827 s = buf;
828 return s;
829 }
830 //---------------------------------------------------------------------------
831 std::string & TrimL(std::string & val)
832 {
833 size_t pos = val.find_first_not_of(" \t");
834 if (pos == std::string::npos)
835     {
836     val.erase(val.begin(), val.end());
837     }
838 else
839     {
840     val.erase(0, pos);
841     }
842 return val;
843 }
844 //---------------------------------------------------------------------------
845 std::string & TrimR(std::string & val)
846 {
847 size_t pos = val.find_last_not_of(" \t");
848 if (pos != std::string::npos)
849     {
850     val.erase(pos + 1);
851     }
852 return val;
853 }
854 //---------------------------------------------------------------------------
855 std::string & Trim(std::string & val)
856 {
857 return TrimR(TrimL(val));
858 }
859 //---------------------------------------------------------------------------
860 std::string Trim(const std::string & val)
861 {
862 std::string res(val);
863 return TrimR(TrimL(res));
864 }
865 //---------------------------------------------------------------------------
866 std::string ToLower(const std::string & value)
867 {
868     std::string res;
869     for (std::string::size_type pos = 0; pos < value.length(); ++pos)
870         res += tolower(value[pos]);
871     return res;
872 }
873 //---------------------------------------------------------------------------
874 std::string ToUpper(const std::string & value)
875 {
876     std::string res;
877     for (std::string::size_type pos = 0; pos < value.length(); ++pos)
878         res += toupper(value[pos]);
879     return res;
880 }
881 //---------------------------------------------------------------------------
882 #ifdef WIN32
883 static int is_leap(unsigned y)
884 {
885     y += 1900;
886     return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
887 }
888 #endif
889 //---------------------------------------------------------------------------
890
891 time_t stg_timegm(struct tm * brokenTime)
892 {
893 #ifdef WIN32
894 static const unsigned ndays[2][12] ={
895     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
896     {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
897 time_t res = 0;
898 for (int i = 70; i < brokenTime->tm_year; ++i)
899     res += is_leap(i) ? 366 : 365;
900 for (int i = 0; i < brokenTime->tm_mon; ++i)
901     res += ndays[is_leap(brokenTime->tm_year)][i];
902 res += brokenTime->tm_mday - 1;
903 res *= 24;
904 res += brokenTime->tm_hour;
905 res *= 60;
906 res += brokenTime->tm_min;
907 res *= 60;
908 res += brokenTime->tm_sec;
909 return res;
910 #else
911 #ifdef HAVE_TIMEGM
912 return timegm(brokenTime);
913 #else
914 time_t ret;
915 char *tz;
916 tz = getenv("TZ");
917 setenv("TZ", "", 1);
918 tzset();
919 ret = mktime(brokenTime);
920 if (tz)
921     setenv("TZ", tz, 1);
922 else
923     unsetenv("TZ");
924 tzset();
925 return ret;
926 #endif // HAVE_TIMEGM
927 #endif // WIN32
928 }
929 //---------------------------------------------------------------------------
930 std::string IconvString(const std::string & source,
931                         const std::string & from,
932                         const std::string & to)
933 {
934 if (source.empty())
935     return std::string();
936
937 size_t inBytesLeft = source.length() + 1;
938 size_t outBytesLeft = source.length() * 2 + 1;
939
940 char * inBuf = new char[inBytesLeft];
941 char * outBuf = new char[outBytesLeft];
942
943 strncpy(inBuf, source.c_str(), source.length());
944
945 inBuf[source.length()] = 0;
946
947 #if defined(FREE_BSD) || defined(FREE_BSD5) || defined(WIN32)
948 const char * srcPos = inBuf;
949 #else
950 char * srcPos = inBuf;
951 #endif
952 char * dstPos = outBuf;
953
954 iconv_t handle = iconv_open(to.c_str(),
955                             from.c_str());
956
957 if (handle == iconv_t(-1))
958     {
959     if (errno == EINVAL)
960         {
961         printfd(__FILE__, "IconvString(): iconv from %s to %s failed\n", from.c_str(), to.c_str());
962         delete[] outBuf;
963         delete[] inBuf;
964         return source;
965         }
966     else
967         printfd(__FILE__, "IconvString(): iconv_open error\n");
968
969     delete[] outBuf;
970     delete[] inBuf;
971     return source;
972     }
973
974 size_t res = iconv(handle,
975                    &srcPos, &inBytesLeft,
976                    &dstPos, &outBytesLeft);
977
978 if (res == size_t(-1))
979     {
980     printfd(__FILE__, "IconvString(): '%s'\n", strerror(errno));
981
982     iconv_close(handle);
983     delete[] outBuf;
984     delete[] inBuf;
985     return source;
986     }
987
988 dstPos = 0;
989
990 std::string dst(outBuf);
991
992 iconv_close(handle);
993
994 delete[] outBuf;
995 delete[] inBuf;
996
997 return dst;
998 }
999
1000 int ParseYesNo(const std::string & str, bool * val)
1001 {
1002 if (0 == strncasecmp(str.c_str(), "yes", 3))
1003     {
1004     *val = true;
1005     return 0;
1006     }
1007
1008 if (0 == strncasecmp(str.c_str(), "no", 2))
1009     {
1010     *val = false;
1011     return 0;
1012     }
1013
1014 return -1;
1015 }
1016
1017 int ParseInt(const std::string & str, int * val)
1018 {
1019 if (str2x<int>(str, *val))
1020     return -1;
1021 return 0;
1022 }
1023
1024 int ParseUnsigned(const std::string & str, unsigned * val)
1025 {
1026 if (str2x<unsigned>(str, *val))
1027     return -1;
1028 return 0;
1029 }
1030
1031 int ParseIntInRange(const std::string & str, int min, int max, int * val)
1032 {
1033 if (ParseInt(str, val) != 0)
1034     return -1;
1035
1036 if (*val < min || *val > max)
1037     return -1;
1038
1039 return 0;
1040 }
1041
1042 int ParseUnsignedInRange(const std::string & str, unsigned min,
1043                          unsigned max, unsigned * val)
1044 {
1045 if (ParseUnsigned(str, val) != 0)
1046     return -1;
1047
1048 if (*val < min || *val > max)
1049     return -1;
1050
1051 return 0;
1052 }
1053
1054 bool WaitPackets(int sd)
1055 {
1056 fd_set rfds;
1057 FD_ZERO(&rfds);
1058 FD_SET(sd, &rfds);
1059
1060 struct timeval tv;
1061 tv.tv_sec = 0;
1062 tv.tv_usec = 500000;
1063
1064 int res = select(sd + 1, &rfds, NULL, NULL, &tv);
1065 if (res == -1) // Error
1066     {
1067     if (errno != EINTR)
1068         printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
1069     return false;
1070     }
1071
1072 if (res == 0) // Timeout
1073     return false;
1074
1075 return true;
1076 }