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