]> git.stg.codes - stg.git/blob - stglibs/common.lib/common.cpp
db2ff6b3e555e768127eb7943594b378cf4b4525
[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 void Encode12(char * dst, const char * src, size_t srcLen)
351 {
352 for (size_t i = 0; i <= srcLen; i++)
353     {
354     char c1 = src[i] & 0x0f;
355     char c2 = (src[i] & 0xf0) >> 4;
356
357     c1 += 'a';
358     c2 += 'a';
359
360     dst[i * 2] = c1;
361     dst[i * 2 + 1] = c2;
362     }
363 dst[srcLen * 2] = 0;
364 }
365 //---------------------------------------------------------------------------
366 void Decode21(char * dst, const char * src)
367 {
368 for (size_t i = 0; ; i++)
369     {
370     if (src[i * 2] == 0)
371         break;
372
373     char c1 = src[i * 2];
374     char c2 = src[i * 2 + 1];
375
376     c1 -= 'a';
377     c2 -= 'a';
378
379     dst[i] = static_cast<char>(c1 + (c2 << 4));
380     }
381 dst[strlen(src) / 2] = 0;
382 }
383 //---------------------------------------------------------------------------
384 int ParseIPString(const char * str, uint32_t * ips, int maxIP)
385 {
386 /*
387  *Function Name:ParseIPString
388  *
389  *Parameters:
390  ÓÔÒÏËÁ ÄÌÑ ÒÁÚÂÏÒÁ É ÍÁÓÓÉ× ËÕÄÁ ÚÁÎÏÓÉÔØ ÐÏÌÕÞÅÎÎÙÅ ÁÄÒÅÓÁ
391  *
392  *Description:
393  îÁ ×ÈÏÄÅ ÄÏÌÖÎÁ ÂÙÔØ ÓÔÒÏËÁ ×ÉÄÁ "ip1,ip2,ip3" ÉÌÉ "*"
394  ÷ ÐÅÒ×ÏÍ ÓÌÕÞÁÅ × ÍÁÓÓÉ× ÚÁÎÏÓÑÔÓÑ ÒÁÚÏÂÒÁÎÎÙÅ ÁÄÒÅÓÁ.
395  åÓÌÉ ÉÈ ÍÅÎØÛÅ MAX_IP?, ÔÏ ÐÏÓÌÅÄÎÉÊ ÁÄÒÅÓ ÂÕÄÅÔ 255.255.255.255
396  åÓÌÉ ÓÔÒÏËÁ * , ÔÏ ÐÅÒ×ÁÙÊ ÁÄÒÅÓ ÂÕÄÅÔ 0.0.0.0, Ô.Å. ÌÀÂÏÊ
397  *
398  *Returns: 0 ÅÓÌÉ ×ÓÅ ïë
399  *
400  */
401
402 char p[255];
403 char * p1, *pp;
404 int n = 0;
405
406 strncpy(p, str, 254);
407 pp = p;
408
409 memset(ips, 0xFF, sizeof(unsigned long) * maxIP);
410
411 if (str[0] == '*' && strlen(str) == 1)
412     {
413     ips[0] = 0;
414     return 0;
415     }
416
417 for (int i = 0; i < maxIP; i++)
418     {
419     p1 = strtok(pp, ",\n ");
420     pp = NULL;
421
422     if (p1 == NULL && n == 0)// ÕËÁÚÁÔÅÌØ ÎÕÌØ É ÐÒÏÞÉÔÁÎÏ ÁÄÒÅÓÏ× ÔÏÖÅ ÎÏÌØ
423         {
424         return EINVAL;
425         }
426
427     if (p1 == NULL && n)
428         {
429         return 0;
430         }
431
432     struct in_addr in;
433     if (inet_pton(AF_INET, p1, &in) != 1)
434         {
435         //printf("INADDR_NONE\n");
436         return EINVAL;
437         }
438
439     ips[n] = in.s_addr;
440
441     /*if (ips[n] == INADDR_NONE)
442         return EINVAL;*/
443
444     n++;
445
446     if (n >= maxIP)
447         return 0;
448
449     }
450
451 return 0;
452 }
453 //-----------------------------------------------------------------------------
454 int DaysInCurrentMonth()
455 {
456 time_t t = time(NULL);
457
458 struct tm * lt = localtime(&t);
459
460 return DaysInMonth(lt->tm_year, lt->tm_mon);
461 }
462 //-----------------------------------------------------------------------------
463 int DaysInMonth(unsigned year, unsigned mon)
464 {
465 assert(mon < 12 && "Month number should be 0 - 11");
466 switch (mon)
467     {
468     case 0: return 31;  //jan
469     case 1:
470         if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
471             return 29;
472         return 28;      //feb
473     case 2: return 31;  //mar
474     case 3: return 30;  //apr
475     case 4: return 31;  //may
476     case 5: return 30;  //june
477     case 6: return 31;  //jule
478     case 7: return 31;  //aug
479     case 8: return 30;  //sep
480     case 9: return 31;  //oct
481     case 10: return 30; //nov
482     case 11: return 31; //dec
483     }
484 return -1; // We will never reach here
485 }
486 //-----------------------------------------------------------------------------
487 int Min8(int a)
488 {
489 /*
490 æÕÎËÃÉÑ ×ÏÚ×ÒÁÝÁÅÔ ÎÁÉÍÅÎØÛÅÅ ÞÉÓÌÏ ËÒÁÔÎÏÅ 8-ÍÉ ÂÏÌØÛÅÅ ÉÌÉ ÒÁ×ÎÏÅ ÚÁÄÁÎÎÏÍÕ
491  * */
492 if (a % 8 == 0)
493     return a;
494
495 return a + (8 - a % 8);
496 }
497 //-----------------------------------------------------------------------------
498 /*char * inet_ntostr(unsigned long ip)
499 {
500 struct in_addr addr = {ip};
501 return inet_ntoa(addr);
502 }*/
503 //-----------------------------------------------------------------------------
504 std::string inet_ntostring(uint32_t ip)
505 {
506     char buf[INET_ADDRSTRLEN + 1];
507     return inet_ntop(AF_INET, &ip, buf, INET_ADDRSTRLEN);
508 }
509 //-----------------------------------------------------------------------------
510 uint32_t inet_strington(const std::string & value)
511 {
512     uint32_t result;
513
514     if (inet_pton(AF_INET, value.c_str(), &result) <= 0)
515         return 0;
516
517     return result;
518 }
519 //-----------------------------------------------------------------------------
520 int ParseTariffTimeStr(const char * str, int &h1, int &m1, int &h2, int &m2)
521 {
522 char hs1[10], ms1[10], hs2[10], ms2[10];
523 char s1[25], s2[25];
524 char ss[49];
525 char *p1, *p2;
526
527 strncpy(ss, str, 48);
528
529 p1 = strtok(ss, "-");
530 if (!p1)
531     return -1;
532
533 strncpy(s1, p1, 24);
534
535 p2 = strtok(NULL, "-");
536 if (!p2)
537     return -1;
538
539 strncpy(s2, p2, 24);
540
541 p1 = strtok(s1, ":");
542 if (!p1)
543     return -1;
544
545 strncpy(hs1, p1, 9);
546
547 p2 = strtok(NULL, ":");
548 if (!p2)
549     return -1;
550
551 strncpy(ms1, p2, 9);
552
553 p1 = strtok(s2, ":");
554 if (!p1)
555     return -1;
556
557 strncpy(hs2, p1, 9);
558
559 p2 = strtok(NULL, ":");
560 if (!p2)
561     return -1;
562
563 strncpy(ms2, p2, 9);
564
565 if (str2x(hs1, h1) != 0)
566     return -1;
567
568 if (str2x(ms1, m1) != 0)
569     return -1;
570
571 if (str2x(hs2, h2) != 0)
572     return -1;
573
574 if (str2x(ms2, m2) != 0)
575     return -1;
576
577 return 0;
578 }
579 /*//---------------------------------------------------------------------------
580 bool IsDigit(char c)
581 {
582 if (c >= '0' && c <= '9')
583     return true;
584 return false;
585 }
586 //-----------------------------------------------------------------------------
587 bool IsAlpha(char c)
588 {
589 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
590     return true;
591 return false;
592 }*/
593 //-----------------------------------------------------------------------------
594 const char * LogDate(time_t t)
595 {
596 static char s[32];
597 struct tm * tt = localtime(&t);
598
599 snprintf(s, 20, "%d-%s%d-%s%d %s%d:%s%d:%s%d",
600          tt->tm_year + 1900,
601          tt->tm_mon + 1 < 10 ? "0" : "", tt->tm_mon + 1,
602          tt->tm_mday    < 10 ? "0" : "", tt->tm_mday,
603          tt->tm_hour    < 10 ? "0" : "", tt->tm_hour,
604          tt->tm_min     < 10 ? "0" : "", tt->tm_min,
605          tt->tm_sec     < 10 ? "0" : "", tt->tm_sec);
606
607 return s;
608 }
609 //-----------------------------------------------------------------------------
610 uint32_t CalcMask(uint32_t msk)
611 {
612 if (msk >= 32) return 0xFFffFFff;
613 if (msk == 0) return 0;
614 return htonl(0xFFffFFff << (32 - msk));
615 }
616 //---------------------------------------------------------------------------
617 void TouchFile(const std::string & fileName)
618 {
619 FILE * f = fopen(fileName.c_str(), "w");
620 if (f)
621     fclose(f);
622 }
623 //---------------------------------------------------------------------------
624 #ifdef WIN32
625 void EncodeStr(char * str, unsigned long serial, int useHDD)
626 {
627 int len = strlen(str);
628 char stren[100];
629 int i, j = 0;
630 char c1, c2;
631 char serial_c[sizeof(serial)];
632 memcpy(serial_c, &serial, sizeof(serial));
633
634 for (i = 0; i < len; i++)
635     {
636     if (!useHDD)
637         str[i] = str[i]^49;
638     else
639         {
640         str[i] = str[i]^serial_c[j%sizeof(serial)];
641         j++;
642         }
643     }
644
645 for (i = 0; i < 2*len; i++)
646     {
647     if (i%2)
648         {
649         c1 = (str[i/2] >> 4);
650         c1 = c1 + 50;
651         stren[i] = c1;
652         }
653     else
654         {
655         c2 = (str[i/2] & 0x0f);
656         c2 += 50;
657         stren[i] = c2;
658         }
659     }
660 stren[i] = 0;
661 strcpy(str, stren);
662 }
663 //---------------------------------------------------------------------------
664 void DecodeStr(char * str, unsigned long serial, int useHDD)
665 {
666 int len = strlen(str);
667 char strdc[100];
668 int i, j = 0;
669 char c1, c2;
670 char serial_c[sizeof(serial)];
671 memcpy(serial_c, &serial, sizeof(serial));
672
673 for (i = 0; i < len; i += 2)
674     {
675     c1 = (str[i] - 50);
676     c2 = (str[i+1] - 50)<<4;
677     strdc[i/2] = c1+c2;
678     }
679 for (i = 0; i < len/2; i++)
680     {
681     if (!useHDD)
682         strdc[i] = strdc[i]^49;
683     else
684         {
685         strdc[i] = strdc[i]^serial_c[j%sizeof(serial)];
686         j++;
687         }
688     }
689 strdc[i] = 0;
690 strcpy(str, strdc);
691 }
692 //---------------------------------------------------------------------------
693 #endif //WIN32
694 void SwapBytes(uint16_t & value)
695 {
696     value = static_cast<uint16_t>((value >> 8) |
697                                   (value << 8));
698 }
699 //---------------------------------------------------------------------------
700 void SwapBytes(uint32_t & value)
701 {
702     value = static_cast<uint32_t>((value >> 24) |
703                                   ((value << 8) &  0x00FF0000L) |
704                                   ((value >> 8) &  0x0000FF00L) |
705                                   (value << 24));
706 }
707 //---------------------------------------------------------------------------
708 void SwapBytes(uint64_t & value)
709 {
710     value = static_cast<uint64_t>((value >> 56) |
711                                   ((value << 40) & 0x00FF000000000000LL) |
712                                   ((value << 24) & 0x0000FF0000000000LL) |
713                                   ((value << 8)  & 0x000000FF00000000LL) |
714                                   ((value >> 8)  & 0x00000000FF000000LL) |
715                                   ((value >> 24) & 0x0000000000FF0000LL) |
716                                   ((value >> 40) & 0x000000000000FF00LL) |
717                                   (value << 56));
718 }
719 //---------------------------------------------------------------------------
720 void SwapBytes(int16_t & value)
721 {
722     uint16_t temp = value;
723     SwapBytes(temp);
724     value = temp;
725 }
726 //---------------------------------------------------------------------------
727 void SwapBytes(int32_t & value)
728 {
729     uint32_t temp = value;
730     SwapBytes(temp);
731     value = temp;
732 }
733 //---------------------------------------------------------------------------
734 void SwapBytes(int64_t & value)
735 {
736     uint64_t temp = value;
737     SwapBytes(temp);
738     value = temp;
739 }
740 //---------------------------------------------------------------------------
741 int str2x(const std::string & str, int32_t & x)
742 {
743 x = static_cast<int32_t>(strtol(str.c_str(), NULL, 10));
744
745 if (errno == ERANGE)
746     return -1;
747
748 return 0;
749 }
750 //---------------------------------------------------------------------------
751 int str2x(const std::string & str, uint32_t & x)
752 {
753 x = static_cast<uint32_t>(strtoul(str.c_str(), NULL, 10));
754
755 if (errno == ERANGE)
756     return -1;
757
758 return 0;
759 }
760 #ifndef WIN32
761 //---------------------------------------------------------------------------
762 int str2x(const std::string & str, int64_t & x)
763 {
764 x = strtoll(str.c_str(), NULL, 10);
765
766 if (errno == ERANGE)
767     return -1;
768
769 return 0;
770 }
771 //---------------------------------------------------------------------------
772 int str2x(const std::string & str, uint64_t & x)
773 {
774 x = strtoull(str.c_str(), NULL, 10);
775
776 if (errno == ERANGE)
777     return -1;
778
779 return 0;
780 }
781 #endif
782 //---------------------------------------------------------------------------
783 const std::string & x2str(uint32_t x, std::string & s)
784 {
785 return unsigned2str(x, s);
786 }
787 //---------------------------------------------------------------------------
788 const std::string & x2str(uint64_t x, std::string & s)
789 {
790 return unsigned2str(x, s);
791 }
792 //---------------------------------------------------------------------------
793 const std::string & x2str(double x, std::string & s)
794 {
795 char buf[256];
796 snprintf(buf, sizeof(buf), "%f", x);
797 s = buf;
798 return s;
799 }
800 //---------------------------------------------------------------------------
801 std::string & TrimL(std::string & val)
802 {
803 size_t pos = val.find_first_not_of(" \t");
804 if (pos == std::string::npos)
805     {
806     val.erase(val.begin(), val.end());
807     }
808 else
809     {
810     val.erase(0, pos);
811     }
812 return val;
813 }
814 //---------------------------------------------------------------------------
815 std::string & TrimR(std::string & val)
816 {
817 size_t pos = val.find_last_not_of(" \t");
818 if (pos != std::string::npos)
819     {
820     val.erase(pos + 1);
821     }
822 return val;
823 }
824 //---------------------------------------------------------------------------
825 std::string & Trim(std::string & val)
826 {
827 return TrimR(TrimL(val));
828 }
829 //---------------------------------------------------------------------------
830 #ifdef WIN32
831 static int is_leap(unsigned y)
832 {
833     y += 1900;
834     return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
835 }
836 #endif
837 //---------------------------------------------------------------------------
838
839 time_t stg_timegm(struct tm * brokenTime)
840 {
841 #ifdef WIN32
842 static const unsigned ndays[2][12] ={
843     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
844     {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
845 time_t res = 0;
846 for (int i = 70; i < brokenTime->tm_year; ++i)
847     res += is_leap(i) ? 366 : 365;
848 for (int i = 0; i < brokenTime->tm_mon; ++i)
849     res += ndays[is_leap(brokenTime->tm_year)][i];
850 res += brokenTime->tm_mday - 1;
851 res *= 24;
852 res += brokenTime->tm_hour;
853 res *= 60;
854 res += brokenTime->tm_min;
855 res *= 60;
856 res += brokenTime->tm_sec;
857 return res;
858 #else
859 #ifdef HAVE_TIMEGM
860 return timegm(brokenTime);
861 #else
862 time_t ret;
863 char *tz;
864 tz = getenv("TZ");
865 setenv("TZ", "", 1);
866 tzset();
867 ret = mktime(brokenTime);
868 if (tz)
869     setenv("TZ", tz, 1);
870 else
871     unsetenv("TZ");
872 tzset();
873 return ret;
874 #endif // HAVE_TIMEGM
875 #endif // WIN32
876 }
877 //---------------------------------------------------------------------------
878 std::string IconvString(const std::string & source,
879                         const std::string & from,
880                         const std::string & to)
881 {
882 if (source.empty())
883     return std::string();
884
885 size_t inBytesLeft = source.length() + 1;
886 size_t outBytesLeft = source.length() * 2 + 1;
887
888 char * inBuf = new char[inBytesLeft];
889 char * outBuf = new char[outBytesLeft];
890
891 strncpy(inBuf, source.c_str(), source.length());
892
893 inBuf[source.length()] = 0;
894
895 #if defined(FREE_BSD) || defined(FREE_BSD5) || defined(WIN32)
896 const char * srcPos = inBuf;
897 #else
898 char * srcPos = inBuf;
899 #endif
900 char * dstPos = outBuf;
901
902 iconv_t handle = iconv_open(to.c_str(),
903                             from.c_str());
904
905 if (handle == iconv_t(-1))
906     {
907     if (errno == EINVAL)
908         {
909         printfd(__FILE__, "IconvString(): iconv from %s to %s failed\n", from.c_str(), to.c_str());
910         delete[] outBuf;
911         delete[] inBuf;
912         return source;
913         }
914     else
915         printfd(__FILE__, "IconvString(): iconv_open error\n");
916
917     delete[] outBuf;
918     delete[] inBuf;
919     return source;
920     }
921
922 size_t res = iconv(handle,
923                    &srcPos, &inBytesLeft,
924                    &dstPos, &outBytesLeft);
925
926 if (res == size_t(-1))
927     {
928     printfd(__FILE__, "IconvString(): '%s'\n", strerror(errno));
929
930     iconv_close(handle);
931     delete[] outBuf;
932     delete[] inBuf;
933     return source;
934     }
935
936 dstPos = 0;
937
938 std::string dst(outBuf);
939
940 iconv_close(handle);
941
942 delete[] outBuf;
943 delete[] inBuf;
944
945 return dst;
946 }
947
948 int ParseYesNo(const std::string & str, bool * val)
949 {
950 if (0 == strncasecmp(str.c_str(), "yes", 3))
951     {
952     *val = true;
953     return 0;
954     }
955
956 if (0 == strncasecmp(str.c_str(), "no", 2))
957     {
958     *val = false;
959     return 0;
960     }
961
962 return -1;
963 }
964
965 int ParseInt(const std::string & str, int * val)
966 {
967 if (str2x<int>(str, *val))
968     return -1;
969 return 0;
970 }
971
972 int ParseUnsigned(const std::string & str, unsigned * val)
973 {
974 if (str2x<unsigned>(str, *val))
975     return -1;
976 return 0;
977 }
978
979 int ParseIntInRange(const std::string & str, int min, int max, int * val)
980 {
981 if (ParseInt(str, val) != 0)
982     return -1;
983
984 if (*val < min || *val > max)
985     return -1;
986
987 return 0;
988 }
989
990 int ParseUnsignedInRange(const std::string & str, unsigned min,
991                          unsigned max, unsigned * val)
992 {
993 if (ParseUnsigned(str, val) != 0)
994     return -1;
995
996 if (*val < min || *val > max)
997     return -1;
998
999 return 0;
1000 }
1001
1002 bool WaitPackets(int sd)
1003 {
1004 fd_set rfds;
1005 FD_ZERO(&rfds);
1006 FD_SET(sd, &rfds);
1007
1008 struct timeval tv;
1009 tv.tv_sec = 0;
1010 tv.tv_usec = 500000;
1011
1012 int res = select(sd + 1, &rfds, NULL, NULL, &tv);
1013 if (res == -1) // Error
1014     {
1015     if (errno != EINTR)
1016         printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
1017     return false;
1018     }
1019
1020 if (res == 0) // Timeout
1021     return false;
1022
1023 return true;
1024 }