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