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