]> git.stg.codes - stg.git/blob - stglibs/common.lib/common.cpp
Added last disconnect reason and last authorization time.
[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 std::string & TrimL(std::string & val)
794 {
795 size_t pos = val.find_first_not_of(" \t");
796 if (pos == std::string::npos)
797     {
798     val.erase(val.begin(), val.end());
799     }
800 else
801     {
802     val.erase(0, pos);
803     }
804 return val;
805 }
806 //---------------------------------------------------------------------------
807 std::string & TrimR(std::string & val)
808 {
809 size_t pos = val.find_last_not_of(" \t");
810 if (pos != std::string::npos)
811     {
812     val.erase(pos + 1);
813     }
814 return val;
815 }
816 //---------------------------------------------------------------------------
817 std::string & Trim(std::string & val)
818 {
819 return TrimR(TrimL(val));
820 }
821 //---------------------------------------------------------------------------
822 #ifdef WIN32
823 static int is_leap(unsigned y)
824 {
825     y += 1900;
826     return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
827 }
828 #endif
829 //---------------------------------------------------------------------------
830
831 time_t stg_timegm(struct tm * brokenTime)
832 {
833 #ifdef WIN32
834 static const unsigned ndays[2][12] ={
835     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
836     {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
837 time_t res = 0;
838 for (int i = 70; i < brokenTime->tm_year; ++i)
839     res += is_leap(i) ? 366 : 365;
840 for (int i = 0; i < brokenTime->tm_mon; ++i)
841     res += ndays[is_leap(brokenTime->tm_year)][i];
842 res += brokenTime->tm_mday - 1;
843 res *= 24;
844 res += brokenTime->tm_hour;
845 res *= 60;
846 res += brokenTime->tm_min;
847 res *= 60;
848 res += brokenTime->tm_sec;
849 return res;
850 #else
851 #ifdef HAVE_TIMEGM
852 return timegm(brokenTime);
853 #else
854 time_t ret;
855 char *tz;
856 tz = getenv("TZ");
857 setenv("TZ", "", 1);
858 tzset();
859 ret = mktime(brokenTime);
860 if (tz)
861     setenv("TZ", tz, 1);
862 else
863     unsetenv("TZ");
864 tzset();
865 return ret;
866 #endif // HAVE_TIMEGM
867 #endif // WIN32
868 }
869 //---------------------------------------------------------------------------
870 std::string IconvString(const std::string & source,
871                         const std::string & from,
872                         const std::string & to)
873 {
874 if (source.empty())
875     return std::string();
876
877 size_t inBytesLeft = source.length() + 1;
878 size_t outBytesLeft = source.length() * 2 + 1;
879
880 char * inBuf = new char[inBytesLeft];
881 char * outBuf = new char[outBytesLeft];
882
883 strncpy(inBuf, source.c_str(), source.length());
884
885 inBuf[source.length()] = 0;
886
887 #if defined(FREE_BSD) || defined(FREE_BSD5) || defined(WIN32)
888 const char * srcPos = inBuf;
889 #else
890 char * srcPos = inBuf;
891 #endif
892 char * dstPos = outBuf;
893
894 iconv_t handle = iconv_open(to.c_str(),
895                             from.c_str());
896
897 if (handle == iconv_t(-1))
898     {
899     if (errno == EINVAL)
900         {
901         printfd(__FILE__, "IconvString(): iconv from %s to %s failed\n", from.c_str(), to.c_str());
902         delete[] outBuf;
903         delete[] inBuf;
904         return source;
905         }
906     else
907         printfd(__FILE__, "IconvString(): iconv_open error\n");
908
909     delete[] outBuf;
910     delete[] inBuf;
911     return source;
912     }
913
914 size_t res = iconv(handle,
915                    &srcPos, &inBytesLeft,
916                    &dstPos, &outBytesLeft);
917
918 if (res == size_t(-1))
919     {
920     printfd(__FILE__, "IconvString(): '%s'\n", strerror(errno));
921
922     iconv_close(handle);
923     delete[] outBuf;
924     delete[] inBuf;
925     return source;
926     }
927
928 dstPos = 0;
929
930 std::string dst(outBuf);
931
932 iconv_close(handle);
933
934 delete[] outBuf;
935 delete[] inBuf;
936
937 return dst;
938 }
939
940 int ParseYesNo(const std::string & str, bool * val)
941 {
942 if (0 == strncasecmp(str.c_str(), "yes", 3))
943     {
944     *val = true;
945     return 0;
946     }
947
948 if (0 == strncasecmp(str.c_str(), "no", 2))
949     {
950     *val = false;
951     return 0;
952     }
953
954 return -1;
955 }
956
957 int ParseInt(const std::string & str, int * val)
958 {
959 if (str2x<int>(str, *val))
960     return -1;
961 return 0;
962 }
963
964 int ParseUnsigned(const std::string & str, unsigned * val)
965 {
966 if (str2x<unsigned>(str, *val))
967     return -1;
968 return 0;
969 }
970
971 int ParseIntInRange(const std::string & str, int min, int max, int * val)
972 {
973 if (ParseInt(str, val) != 0)
974     return -1;
975
976 if (*val < min || *val > max)
977     return -1;
978
979 return 0;
980 }
981
982 int ParseUnsignedInRange(const std::string & str, unsigned min,
983                          unsigned max, unsigned * val)
984 {
985 if (ParseUnsigned(str, val) != 0)
986     return -1;
987
988 if (*val < min || *val > max)
989     return -1;
990
991 return 0;
992 }
993
994 bool WaitPackets(int sd)
995 {
996 fd_set rfds;
997 FD_ZERO(&rfds);
998 FD_SET(sd, &rfds);
999
1000 struct timeval tv;
1001 tv.tv_sec = 0;
1002 tv.tv_usec = 500000;
1003
1004 int res = select(sd + 1, &rfds, NULL, NULL, &tv);
1005 if (res == -1) // Error
1006     {
1007     if (errno != EINTR)
1008         printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
1009     return false;
1010     }
1011
1012 if (res == 0) // Timeout
1013     return false;
1014
1015 return true;
1016 }