]> git.stg.codes - stg.git/blob - stglibs/common.lib/common.cpp
622f64f7f11b2b31fbb31d359fea6af743707dbc
[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 s = snprintf(buf, sizeof(buf), "%f", x);
827 return s;
828 }
829 //---------------------------------------------------------------------------
830 std::string & TrimL(std::string & val)
831 {
832 size_t pos = val.find_first_not_of(" \t");
833 if (pos == std::string::npos)
834     {
835     val.erase(val.begin(), val.end());
836     }
837 else
838     {
839     val.erase(0, pos);
840     }
841 return val;
842 }
843 //---------------------------------------------------------------------------
844 std::string & TrimR(std::string & val)
845 {
846 size_t pos = val.find_last_not_of(" \t");
847 if (pos != std::string::npos)
848     {
849     val.erase(pos + 1);
850     }
851 return val;
852 }
853 //---------------------------------------------------------------------------
854 std::string & Trim(std::string & val)
855 {
856 return TrimR(TrimL(val));
857 }
858 //---------------------------------------------------------------------------
859 std::string Trim(const std::string & val)
860 {
861 std::string res(val);
862 return TrimR(TrimL(res));
863 }
864 //---------------------------------------------------------------------------
865 std::string ToLower(const std::string & value)
866 {
867     std::string res;
868     for (std::string::size_type pos = 0; pos < value.length(); ++pos)
869         res += tolower(value[pos]);
870     return res;
871 }
872 //---------------------------------------------------------------------------
873 std::string ToUpper(const std::string & value)
874 {
875     std::string res;
876     for (std::string::size_type pos = 0; pos < value.length(); ++pos)
877         res += toupper(value[pos]);
878     return res;
879 }
880 //---------------------------------------------------------------------------
881 #ifdef WIN32
882 static int is_leap(unsigned y)
883 {
884     y += 1900;
885     return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
886 }
887 #endif
888 //---------------------------------------------------------------------------
889
890 time_t stg_timegm(struct tm * brokenTime)
891 {
892 #ifdef WIN32
893 static const unsigned ndays[2][12] ={
894     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
895     {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
896 time_t res = 0;
897 for (int i = 70; i < brokenTime->tm_year; ++i)
898     res += is_leap(i) ? 366 : 365;
899 for (int i = 0; i < brokenTime->tm_mon; ++i)
900     res += ndays[is_leap(brokenTime->tm_year)][i];
901 res += brokenTime->tm_mday - 1;
902 res *= 24;
903 res += brokenTime->tm_hour;
904 res *= 60;
905 res += brokenTime->tm_min;
906 res *= 60;
907 res += brokenTime->tm_sec;
908 return res;
909 #else
910 #ifdef HAVE_TIMEGM
911 return timegm(brokenTime);
912 #else
913 time_t ret;
914 char *tz;
915 tz = getenv("TZ");
916 setenv("TZ", "", 1);
917 tzset();
918 ret = mktime(brokenTime);
919 if (tz)
920     setenv("TZ", tz, 1);
921 else
922     unsetenv("TZ");
923 tzset();
924 return ret;
925 #endif // HAVE_TIMEGM
926 #endif // WIN32
927 }
928 //---------------------------------------------------------------------------
929 std::string IconvString(const std::string & source,
930                         const std::string & from,
931                         const std::string & to)
932 {
933 if (source.empty())
934     return std::string();
935
936 size_t inBytesLeft = source.length() + 1;
937 size_t outBytesLeft = source.length() * 2 + 1;
938
939 char * inBuf = new char[inBytesLeft];
940 char * outBuf = new char[outBytesLeft];
941
942 strncpy(inBuf, source.c_str(), source.length());
943
944 inBuf[source.length()] = 0;
945
946 #if defined(FREE_BSD) || defined(FREE_BSD5) || defined(WIN32)
947 const char * srcPos = inBuf;
948 #else
949 char * srcPos = inBuf;
950 #endif
951 char * dstPos = outBuf;
952
953 iconv_t handle = iconv_open(to.c_str(),
954                             from.c_str());
955
956 if (handle == iconv_t(-1))
957     {
958     if (errno == EINVAL)
959         {
960         printfd(__FILE__, "IconvString(): iconv from %s to %s failed\n", from.c_str(), to.c_str());
961         delete[] outBuf;
962         delete[] inBuf;
963         return source;
964         }
965     else
966         printfd(__FILE__, "IconvString(): iconv_open error\n");
967
968     delete[] outBuf;
969     delete[] inBuf;
970     return source;
971     }
972
973 size_t res = iconv(handle,
974                    &srcPos, &inBytesLeft,
975                    &dstPos, &outBytesLeft);
976
977 if (res == size_t(-1))
978     {
979     printfd(__FILE__, "IconvString(): '%s'\n", strerror(errno));
980
981     iconv_close(handle);
982     delete[] outBuf;
983     delete[] inBuf;
984     return source;
985     }
986
987 dstPos = 0;
988
989 std::string dst(outBuf);
990
991 iconv_close(handle);
992
993 delete[] outBuf;
994 delete[] inBuf;
995
996 return dst;
997 }
998
999 int ParseYesNo(const std::string & str, bool * val)
1000 {
1001 if (0 == strncasecmp(str.c_str(), "yes", 3))
1002     {
1003     *val = true;
1004     return 0;
1005     }
1006
1007 if (0 == strncasecmp(str.c_str(), "no", 2))
1008     {
1009     *val = false;
1010     return 0;
1011     }
1012
1013 return -1;
1014 }
1015
1016 int ParseInt(const std::string & str, int * val)
1017 {
1018 if (str2x<int>(str, *val))
1019     return -1;
1020 return 0;
1021 }
1022
1023 int ParseUnsigned(const std::string & str, unsigned * val)
1024 {
1025 if (str2x<unsigned>(str, *val))
1026     return -1;
1027 return 0;
1028 }
1029
1030 int ParseIntInRange(const std::string & str, int min, int max, int * val)
1031 {
1032 if (ParseInt(str, val) != 0)
1033     return -1;
1034
1035 if (*val < min || *val > max)
1036     return -1;
1037
1038 return 0;
1039 }
1040
1041 int ParseUnsignedInRange(const std::string & str, unsigned min,
1042                          unsigned max, unsigned * val)
1043 {
1044 if (ParseUnsigned(str, val) != 0)
1045     return -1;
1046
1047 if (*val < min || *val > max)
1048     return -1;
1049
1050 return 0;
1051 }
1052
1053 bool WaitPackets(int sd)
1054 {
1055 fd_set rfds;
1056 FD_ZERO(&rfds);
1057 FD_SET(sd, &rfds);
1058
1059 struct timeval tv;
1060 tv.tv_sec = 0;
1061 tv.tv_usec = 500000;
1062
1063 int res = select(sd + 1, &rfds, NULL, NULL, &tv);
1064 if (res == -1) // Error
1065     {
1066     if (errno != EINTR)
1067         printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
1068     return false;
1069     }
1070
1071 if (res == 0) // Timeout
1072     return false;
1073
1074 return true;
1075 }