]> git.stg.codes - stg.git/blob - stglibs/common.lib/common.cpp
2bb327dfebb5a34be36277167d8fa77366289311
[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 #ifdef FREE_BSD
32 #include <sys/types.h>
33 #endif
34 #include <sys/time.h>
35
36 #ifdef WIN32
37 #include <winsock2.h>
38 #else
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42 #include <sys/select.h>
43 #endif
44
45 #include <iconv.h>
46
47 #include <cstdlib>
48 #include <cstdarg>
49 #include <cstdio>
50 #include <cstring>
51 #include <cerrno>
52 #include <cassert>
53
54 #include "stg/common.h"
55
56 #ifndef INET_ADDRSTRLEN
57 #   define INET_ADDRSTRLEN 16
58 #endif
59
60 using namespace std;
61
62 #ifdef WIN32
63 //-----------------------------------------------------------------------------
64 const char * inet_ntop(int af, const void * src, char * dst, unsigned long length)
65 {
66 struct sockaddr_in addr;
67 addr.sin_family = af;
68 addr.sin_port = 0;
69 memcpy(&addr.sin_addr.s_addr, src, sizeof(addr.sin_addr.s_addr));
70 if (WSAAddressToStringA(reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr), 0, dst, &length))
71     {
72     return NULL;
73     }
74 return dst;
75 }
76 //-----------------------------------------------------------------------------
77 int inet_pton(int af, const char * src, void * dst)
78 {
79 // Fuck you Microsoft!
80 // Why the hell not to use const char *?
81 size_t slen = strlen(src);
82 char * buf = new char[slen + 1];
83 strncpy(buf, src, slen + 1);
84 buf[slen] = 0;
85 struct sockaddr_in addr;
86 addr.sin_family = af;
87 addr.sin_port = 0;
88 addr.sin_addr.s_addr = 0;
89 int length = sizeof(addr);
90 if (WSAStringToAddressA(buf, af, 0, reinterpret_cast<struct sockaddr *>(&addr), &length))
91     {
92     delete[] buf;
93     return -1;
94     }
95 memcpy(dst, &addr, sizeof(addr));
96 delete[] buf;
97 return 1;
98 }
99 #endif
100 //-----------------------------------------------------------------------------
101 int strtodouble2(const char * s, double &a)
102 {
103 char *res;
104
105 a = strtod(s, &res);
106
107 if (*res != 0)
108     return EINVAL;
109
110 return 0;
111 }
112 //-----------------------------------------------------------------------------
113 #ifdef DEBUG
114 int printfd(const char * __file__, const char * fmt, ...)
115 #else
116 int printfd(const char *, const char *, ...)
117 #endif
118 {
119 #ifdef DEBUG
120 char buff[1024];
121
122 time_t t = time(NULL);
123
124 va_list vl;
125 va_start(vl, fmt);
126 vsnprintf(buff, sizeof(buff), fmt, vl);
127 va_end(vl);
128
129 printf("%18s > %s > ", __file__, LogDate(t)+11);
130 printf("%s", buff);
131
132 #endif
133 return 0;
134 }
135 //-----------------------------------------------------------------------------
136 int strprintf(string * str, const char * fmt, ...)
137 {
138 char buff[1024];
139
140 va_list vl;
141 va_start(vl, fmt);
142 int n = vsnprintf(buff, sizeof(buff), fmt, vl);
143 va_end(vl);
144 buff[1023] = 0;
145 *str = buff;
146
147 return n;
148 }
149 //-----------------------------------------------------------------------------
150 const char *IntToKMG(long long a, int stat)
151 {
152 static int64_t M = 1024*1024;
153 static int64_t G = 1024*1024*1024;
154 static char str[30];
155
156 switch (stat)
157     {
158     case ST_B:
159         #ifdef __WIN32__
160         sprintf(str, "%Ld", a);
161         #else
162         sprintf(str, "%lld", a);
163         #endif
164         break;
165     case ST_KB:
166         sprintf(str, "%.2f kb", double(a)/1024.0);
167         break;
168     case ST_MB:
169         sprintf(str, "%.2f Mb", double(a)/(1024.0*1024.0));
170         break;
171     default:
172         if (a > G)
173             {
174             sprintf(str, "%.2f Gb", double(a)/double(G));
175             return &str[0];
176             }
177         if (a < -G)
178             {
179             sprintf(str, "%.2f Gb", double(a)/double(G));
180             return &str[0];
181             }
182         if (a > M)
183             {
184             sprintf(str, "%.2f Mb", double(a)/double(M));
185             return &str[0];
186             }
187         if (a < -M)
188             {
189             sprintf(str, "%.2f Mb", double(a)/double(M));
190             return &str[0];
191             }
192
193         sprintf(str, "%.2f kb", double(a)/1024.0);
194         break;
195     }
196 return str;
197 }
198 //---------------------------------------------------------------------------
199 unsigned char koi2win[] = {
200         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
201         0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
202         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
203         0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
204         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
205         0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
206         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
207         0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
208         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
209         0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
210         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
211         0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
212         0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
213         0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
214         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
215         0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
216         0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
217         0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
218         0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
219         0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
220         0xA0, 0xA1, 0xA2, 0xB8, 0xBA, 0xA5, 0xB3, 0xBF,
221         0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xB4, 0xAE, 0xAF,
222         0xB0, 0xB1, 0xB2, 0xA8, 0xAA, 0xB5, 0xB2, 0xAF,
223         0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xA5, 0xBE, 0xBF,
224         0xFE, 0xE0, 0xE1, 0xF6, 0xE4, 0xE5, 0xF4, 0xE3,
225         0xF5, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE,
226         0xEF, 0xFF, 0xF0, 0xF1, 0xF2, 0xF3, 0xE6, 0xE2,
227         0xFC, 0xFB, 0xE7, 0xF8, 0xFD, 0xF9, 0xF7, 0xFA,
228         0xDE, 0xC0, 0xC1, 0xD6, 0xC4, 0xC5, 0xD4, 0xC3,
229         0xD5, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE,
230         0xCF, 0xDF, 0xD0, 0xD1, 0xD2, 0xD3, 0xC6, 0xC2,
231         0xDC, 0xDB, 0xC7, 0xD8, 0xDD, 0xD9, 0xD7, 0xDA};
232
233
234 unsigned char win2koi[] = {
235         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
236         0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
237         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
238         0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
239         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
240         0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
241         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
242         0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
243         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
244         0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
245         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
246         0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
247         0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
248         0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
249         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
250         0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
251         0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
252         0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
253         0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
254         0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
255         0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xBD, 0xA6, 0xA7,
256         0xB3, 0xA9, 0xB4, 0xAB, 0xAC, 0xAD, 0xAE, 0xB7,
257         0xB0, 0xB1, 0xB6, 0xA6, 0xAD, 0xB5, 0xB6, 0xB7,
258         0xA3, 0xB9, 0xA4, 0xBB, 0xBC, 0xBD, 0xBE, 0xA7,
259         0xE1, 0xE2, 0xF7, 0xE7, 0xE4, 0xE5, 0xF6, 0xFA,
260         0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0,
261         0xF2, 0xF3, 0xF4, 0xF5, 0xE6, 0xE8, 0xE3, 0xFE,
262         0xFB, 0xFD, 0xFF, 0xF9, 0xF8, 0xFC, 0xE0, 0xF1,
263         0xC1, 0xC2, 0xD7, 0xC7, 0xC4, 0xC5, 0xD6, 0xDA,
264         0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0,
265         0xD2, 0xD3, 0xD4, 0xD5, 0xC6, 0xC8, 0xC3, 0xDE,
266         0xDB, 0xDD, 0xDF, 0xD9, 0xD8, 0xDC, 0xC0, 0xD1};
267 //---------------------------------------------------------------------------
268 void KOIToWin(const char * s1, char * s2, int l)
269 {
270 unsigned char t;
271 for (int j = 0; j < l; j++)
272     {
273     t = s1[j];
274     s2[j] = koi2win[t];
275
276     if (s1[j] == 0)
277         break;
278     }
279 }
280 //---------------------------------------------------------------------------
281 void WinToKOI(const char * s1, char * s2, int l)
282 {
283 unsigned char t;
284 for (int j = 0; j < l; j++)
285     {
286     t = s1[j];
287     s2[j] = win2koi[t];
288
289     if (s1[j] == 0)
290         break;
291     }
292 }
293 //---------------------------------------------------------------------------
294 void KOIToWin(const string & s1, string * s2)
295 {
296 s2->erase(s2->begin(), s2->end());
297 unsigned char t;
298 s2->reserve(s1.length());
299 for (int j = 0; j < (int)s1.length(); j++)
300     {
301     t = s1[j];
302     s2->push_back(koi2win[t]);
303     }
304 }
305 //---------------------------------------------------------------------------
306 void WinToKOI(const string & s1, string * s2)
307 {
308 s2->erase(s2->begin(), s2->end());
309 unsigned char t;
310 s2->reserve(s1.length());
311 for (int j = 0; j < (int)s1.length(); j++)
312     {
313     t = s1[j];
314     s2->push_back(win2koi[t]);
315     }
316 }
317 //---------------------------------------------------------------------------
318 void Encode12str(string & dst, const string & src)
319 {
320 dst.erase(dst.begin(), dst.end());
321 for (size_t i = 0; i < src.length(); i++)
322     {
323     dst.push_back('a' + (src[i] & 0x0f));
324     dst.push_back('a' + ((src[i] & 0xf0) >> 4));
325     }
326 }
327 //---------------------------------------------------------------------------
328 void Decode21str(std::string & dst, const std::string & src)
329 {
330 dst.erase(dst.begin(), dst.end());
331 for (size_t i = 0; i < src.length() / 2; i++)
332     {
333     char c1 = src[i * 2];
334     char c2 = src[i * 2 + 1];
335
336     c1 -= 'a';
337     c2 -= 'a';
338
339     dst.push_back(c1 + (c2 << 4));
340     }
341 }
342 //---------------------------------------------------------------------------
343 void Encode12(char * dst, const char * src, size_t srcLen)
344 {
345 for (size_t i = 0; i <= srcLen; i++)
346     {
347     char c1 = src[i] & 0x0f;
348     char c2 = (src[i] & 0xf0) >> 4;
349
350     c1 += 'a';
351     c2 += 'a';
352
353     dst[i * 2] = c1;
354     dst[i * 2 + 1] = c2;
355     }
356 dst[srcLen * 2] = 0;
357 }
358 //---------------------------------------------------------------------------
359 void Decode21(char * dst, const char * src)
360 {
361 for (size_t i = 0; ; i++)
362     {
363     if (src[i * 2] == 0)
364         break;
365
366     char c1 = src[i * 2];
367     char c2 = src[i * 2 + 1];
368
369     c1 -= 'a';
370     c2 -= 'a';
371
372     dst[i] = c1 + (c2 << 4);
373     }
374 dst[strlen(src) / 2] = 0;
375 }
376 //---------------------------------------------------------------------------
377 int ParseIPString(const char * str, uint32_t * ips, int maxIP)
378 {
379 /*
380  *Function Name:ParseIPString
381  *
382  *Parameters:
383  ÓÔÒÏËÁ ÄÌÑ ÒÁÚÂÏÒÁ É ÍÁÓÓÉ× ËÕÄÁ ÚÁÎÏÓÉÔØ ÐÏÌÕÞÅÎÎÙÅ ÁÄÒÅÓÁ
384  *
385  *Description:
386  îÁ ×ÈÏÄÅ ÄÏÌÖÎÁ ÂÙÔØ ÓÔÒÏËÁ ×ÉÄÁ "ip1,ip2,ip3" ÉÌÉ "*"
387  ÷ ÐÅÒ×ÏÍ ÓÌÕÞÁÅ × ÍÁÓÓÉ× ÚÁÎÏÓÑÔÓÑ ÒÁÚÏÂÒÁÎÎÙÅ ÁÄÒÅÓÁ.
388  åÓÌÉ ÉÈ ÍÅÎØÛÅ MAX_IP?, ÔÏ ÐÏÓÌÅÄÎÉÊ ÁÄÒÅÓ ÂÕÄÅÔ 255.255.255.255
389  åÓÌÉ ÓÔÒÏËÁ * , ÔÏ ÐÅÒ×ÁÙÊ ÁÄÒÅÓ ÂÕÄÅÔ 0.0.0.0, Ô.Å. ÌÀÂÏÊ
390  *
391  *Returns: 0 ÅÓÌÉ ×ÓÅ ïë
392  *
393  */
394
395 char p[255];
396 char * p1, *pp;
397 int n = 0;
398
399 strncpy(p, str, 254);
400 pp = p;
401
402 memset(ips, 0xFF, sizeof(unsigned long) * maxIP);
403
404 if (str[0] == '*' && strlen(str) == 1)
405     {
406     ips[0] = 0;
407     return 0;
408     }
409
410 for (int i = 0; i < maxIP; i++)
411     {
412     p1 = strtok(pp, ",\n ");
413     pp = NULL;
414
415     if (p1 == NULL && n == 0)// ÕËÁÚÁÔÅÌØ ÎÕÌØ É ÐÒÏÞÉÔÁÎÏ ÁÄÒÅÓÏ× ÔÏÖÅ ÎÏÌØ
416         {
417         return EINVAL;
418         }
419
420     if (p1 == NULL && n)
421         {
422         return 0;
423         }
424
425     struct in_addr in;
426     if (inet_pton(AF_INET, p1, &in) != 1)
427         {
428         //printf("INADDR_NONE\n");
429         return EINVAL;
430         }
431
432     ips[n] = in.s_addr;
433
434     /*if (ips[n] == INADDR_NONE)
435         return EINVAL;*/
436
437     n++;
438
439     if (n >= maxIP)
440         return 0;
441
442     }
443
444 return 0;
445 }
446 //-----------------------------------------------------------------------------
447 int DaysInCurrentMonth()
448 {
449 time_t t = time(NULL);
450
451 struct tm * lt = localtime(&t);
452
453 return DaysInMonth(lt->tm_year, lt->tm_mon);
454 }
455 //-----------------------------------------------------------------------------
456 int DaysInMonth(unsigned year, unsigned mon)
457 {
458 assert(mon < 12 && "Month number should be 0 - 11");
459 switch (mon)
460     {
461     case 0: return 31;  //jan
462     case 1:
463         if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
464             return 29;
465         return 28;      //feb
466     case 2: return 31;  //mar
467     case 3: return 30;  //apr
468     case 4: return 31;  //may
469     case 5: return 30;  //june
470     case 6: return 31;  //jule
471     case 7: return 31;  //aug
472     case 8: return 30;  //sep
473     case 9: return 31;  //oct
474     case 10: return 30; //nov
475     case 11: return 31; //dec
476     }
477 return -1; // We will never reach here
478 }
479 //-----------------------------------------------------------------------------
480 int Min8(int a)
481 {
482 /*
483 æÕÎËÃÉÑ ×ÏÚ×ÒÁÝÁÅÔ ÎÁÉÍÅÎØÛÅÅ ÞÉÓÌÏ ËÒÁÔÎÏÅ 8-ÍÉ ÂÏÌØÛÅÅ ÉÌÉ ÒÁ×ÎÏÅ ÚÁÄÁÎÎÏÍÕ
484  * */
485 if (a % 8 == 0)
486     return a;
487
488 return a + (8 - a % 8);
489 }
490 //-----------------------------------------------------------------------------
491 /*char * inet_ntostr(unsigned long ip)
492 {
493 struct in_addr addr = {ip};
494 return inet_ntoa(addr);
495 }*/
496 //-----------------------------------------------------------------------------
497 std::string inet_ntostring(uint32_t ip)
498 {
499     char buf[INET_ADDRSTRLEN + 1];
500     return inet_ntop(AF_INET, &ip, buf, INET_ADDRSTRLEN);
501 }
502 //-----------------------------------------------------------------------------
503 uint32_t inet_strington(const std::string & value)
504 {
505     uint32_t result;
506
507     if (inet_pton(AF_INET, value.c_str(), &result) <= 0)
508         return 0;
509
510     return result;
511 }
512 //-----------------------------------------------------------------------------
513 int ParseTariffTimeStr(const char * str, int &h1, int &m1, int &h2, int &m2)
514 {
515 char hs1[10], ms1[10], hs2[10], ms2[10];
516 char s1[25], s2[25];
517 char ss[49];
518 char *p1, *p2;
519
520 strncpy(ss, str, 48);
521
522 p1 = strtok(ss, "-");
523 if (!p1)
524     return -1;
525
526 strncpy(s1, p1, 24);
527
528 p2 = strtok(NULL, "-");
529 if (!p2)
530     return -1;
531
532 strncpy(s2, p2, 24);
533
534 p1 = strtok(s1, ":");
535 if (!p1)
536     return -1;
537
538 strncpy(hs1, p1, 9);
539
540 p2 = strtok(NULL, ":");
541 if (!p2)
542     return -1;
543
544 strncpy(ms1, p2, 9);
545
546 p1 = strtok(s2, ":");
547 if (!p1)
548     return -1;
549
550 strncpy(hs2, p1, 9);
551
552 p2 = strtok(NULL, ":");
553 if (!p2)
554     return -1;
555
556 strncpy(ms2, p2, 9);
557
558 if (str2x(hs1, h1) != 0)
559     return -1;
560
561 if (str2x(ms1, m1) != 0)
562     return -1;
563
564 if (str2x(hs2, h2) != 0)
565     return -1;
566
567 if (str2x(ms2, m2) != 0)
568     return -1;
569
570 return 0;
571 }
572 /*//---------------------------------------------------------------------------
573 bool IsDigit(char c)
574 {
575 if (c >= '0' && c <= '9')
576     return true;
577 return false;
578 }
579 //-----------------------------------------------------------------------------
580 bool IsAlpha(char c)
581 {
582 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
583     return true;
584 return false;
585 }*/
586 //-----------------------------------------------------------------------------
587 const char * LogDate(time_t t)
588 {
589 static char s[32];
590 struct tm * tt = localtime(&t);
591
592 snprintf(s, 20, "%d-%s%d-%s%d %s%d:%s%d:%s%d",
593          tt->tm_year + 1900,
594          tt->tm_mon + 1 < 10 ? "0" : "", tt->tm_mon + 1,
595          tt->tm_mday    < 10 ? "0" : "", tt->tm_mday,
596          tt->tm_hour    < 10 ? "0" : "", tt->tm_hour,
597          tt->tm_min     < 10 ? "0" : "", tt->tm_min,
598          tt->tm_sec     < 10 ? "0" : "", tt->tm_sec);
599
600 return s;
601 }
602 //-----------------------------------------------------------------------------
603 uint32_t CalcMask(uint32_t msk)
604 {
605 if (msk >= 32) return 0xFFffFFff;
606 if (msk == 0) return 0;
607 return htonl(0xFFffFFff << (32 - msk));
608 }
609 //---------------------------------------------------------------------------
610 void TouchFile(const string & fileName)
611 {
612 FILE * f = fopen(fileName.c_str(), "w");
613 if (f)
614     fclose(f);
615 }
616 //---------------------------------------------------------------------------
617 #ifdef WIN32
618 void EncodeStr(char * str, unsigned long serial, int useHDD)
619 {
620 int len = strlen(str);
621 char stren[100];
622 int i, j = 0;
623 char c1, c2;
624 char serial_c[sizeof(serial)];
625 memcpy(serial_c, &serial, sizeof(serial));
626
627 for (i = 0; i < len; i++)
628     {
629     if (!useHDD)
630         str[i] = str[i]^49;
631     else
632         {
633         str[i] = str[i]^serial_c[j%sizeof(serial)];
634         j++;
635         }
636     }
637
638 for (i = 0; i < 2*len; i++)
639     {
640     if (i%2)
641         {
642         c1 = (str[i/2] >> 4);
643         c1 = c1 + 50;
644         stren[i] = c1;
645         }
646     else
647         {
648         c2 = (str[i/2] & 0x0f);
649         c2 += 50;
650         stren[i] = c2;
651         }
652     }
653 stren[i] = 0;
654 strcpy(str, stren);
655 }
656 //---------------------------------------------------------------------------
657 void DecodeStr(char * str, unsigned long serial, int useHDD)
658 {
659 int len = strlen(str);
660 char strdc[100];
661 int i, j = 0;
662 char c1, c2;
663 char serial_c[sizeof(serial)];
664 memcpy(serial_c, &serial, sizeof(serial));
665
666 for (i = 0; i < len; i += 2)
667     {
668     c1 = (str[i] - 50);
669     c2 = (str[i+1] - 50)<<4;
670     strdc[i/2] = c1+c2;
671     }
672 for (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 = (value >> 8) |
690             (value << 8);
691 }
692 //---------------------------------------------------------------------------
693 void SwapBytes(uint32_t & value)
694 {
695     value = (value >> 24) |
696             ((value << 8) &  0x00FF0000L)|
697             ((value >> 8) &  0x0000FF00L)|
698             (value << 24);
699 }
700 //---------------------------------------------------------------------------
701 void SwapBytes(uint64_t & value)
702 {
703     value = (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, int & x)
735 {
736 x = 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, unsigned & x)
745 {
746 x = strtoul(str.c_str(), NULL, 10);
747
748 if (errno == ERANGE)
749     return -1;
750
751 return 0;
752 }
753 //---------------------------------------------------------------------------
754 int str2x(const std::string & str, long & x)
755 {
756 x = strtol(str.c_str(), NULL, 10);
757
758 if (errno == ERANGE)
759     return -1;
760
761 return 0;
762 }
763 //---------------------------------------------------------------------------
764 int str2x(const std::string & str, unsigned long & x)
765 {
766 x = strtoul(str.c_str(), NULL, 10);
767
768 if (errno == ERANGE)
769     return -1;
770
771 return 0;
772 }
773 #ifndef WIN32
774 //---------------------------------------------------------------------------
775 int str2x(const std::string & str, long long & x)
776 {
777 x = strtoll(str.c_str(), NULL, 10);
778
779 if (errno == ERANGE)
780     return -1;
781
782 return 0;
783 }
784 //---------------------------------------------------------------------------
785 int str2x(const std::string & str, unsigned long long & x)
786 {
787 x = strtoull(str.c_str(), NULL, 10);
788
789 if (errno == ERANGE)
790     return -1;
791
792 return 0;
793 }
794 #endif
795 //---------------------------------------------------------------------------
796 const std::string & x2str(unsigned x, std::string & s)
797 {
798 return unsigned2str(x, s);
799 }
800 //---------------------------------------------------------------------------
801 const std::string & x2str(unsigned long x, std::string & s)
802 {
803 return unsigned2str(x, s);
804 }
805 //---------------------------------------------------------------------------
806 const std::string & x2str(unsigned long long x, std::string & s)
807 {
808 return unsigned2str(x, s);
809 }
810 //---------------------------------------------------------------------------
811 std::string & TrimL(std::string & val)
812 {
813 size_t pos = val.find_first_not_of(" \t");
814 if (pos == std::string::npos)
815     {
816     val.erase(val.begin(), val.end());
817     }
818 else
819     {
820     val.erase(0, pos);
821     }
822 return val;
823 }
824 //---------------------------------------------------------------------------
825 std::string & TrimR(std::string & val)
826 {
827 size_t pos = val.find_last_not_of(" \t");
828 if (pos != std::string::npos)
829     {
830     val.erase(pos + 1);
831     }
832 return val;
833 }
834 //---------------------------------------------------------------------------
835 std::string & Trim(std::string & val)
836 {
837 return TrimR(TrimL(val));
838 }
839 //---------------------------------------------------------------------------
840 #ifdef WIN32
841 static int is_leap(unsigned y)
842 {
843     y += 1900;
844     return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
845 }
846 #endif
847 //---------------------------------------------------------------------------
848
849 time_t stg_timegm(struct tm * brokenTime)
850 {
851 #ifdef WIN32
852 static const unsigned ndays[2][12] ={
853     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
854     {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
855 time_t res = 0;
856 for (int i = 70; i < brokenTime->tm_year; ++i)
857     res += is_leap(i) ? 366 : 365;
858 for (int i = 0; i < brokenTime->tm_mon; ++i)
859     res += ndays[is_leap(brokenTime->tm_year)][i];
860 res += brokenTime->tm_mday - 1;
861 res *= 24;
862 res += brokenTime->tm_hour;
863 res *= 60;
864 res += brokenTime->tm_min;
865 res *= 60;
866 res += brokenTime->tm_sec;
867 return res;
868 #else
869 #ifdef HAVE_TIMEGM
870 return timegm(brokenTime);
871 #else
872 time_t ret;
873 char *tz;
874 tz = getenv("TZ");
875 setenv("TZ", "", 1);
876 tzset();
877 ret = mktime(brokenTime);
878 if (tz)
879     setenv("TZ", tz, 1);
880 else
881     unsetenv("TZ");
882 tzset();
883 return ret;
884 #endif // HAVE_TIMEGM
885 #endif // WIN32
886 }
887 //---------------------------------------------------------------------------
888 std::string IconvString(const std::string & source,
889                         const std::string & from,
890                         const std::string & to)
891 {
892 if (source.empty())
893     return std::string();
894
895 size_t inBytesLeft = source.length() + 1;
896 size_t outBytesLeft = source.length() * 2 + 1;
897
898 char * inBuf = new char[inBytesLeft];
899 char * outBuf = new char[outBytesLeft];
900
901 strncpy(inBuf, source.c_str(), source.length());
902
903 inBuf[source.length()] = 0;
904
905 #if defined(FREE_BSD) || defined(FREE_BSD5) || defined(WIN32)
906 const char * srcPos = inBuf;
907 #else
908 char * srcPos = inBuf;
909 #endif
910 char * dstPos = outBuf;
911
912 iconv_t handle = iconv_open(to.c_str(),
913                             from.c_str());
914
915 if (handle == iconv_t(-1))
916     {
917     if (errno == EINVAL)
918         {
919         printfd(__FILE__, "IconvString(): iconv from %s to %s failed\n", from.c_str(), to.c_str());
920         delete[] outBuf;
921         delete[] inBuf;
922         return source;
923         }
924     else
925         printfd(__FILE__, "IconvString(): iconv_open error\n");
926
927     delete[] outBuf;
928     delete[] inBuf;
929     return source;
930     }
931
932 size_t res = iconv(handle,
933                    &srcPos, &inBytesLeft,
934                    &dstPos, &outBytesLeft);
935
936 if (res == size_t(-1))
937     {
938     printfd(__FILE__, "IconvString(): '%s'\n", strerror(errno));
939
940     iconv_close(handle);
941     delete[] outBuf;
942     delete[] inBuf;
943     return source;
944     }
945
946 dstPos = 0;
947
948 std::string dst(outBuf);
949
950 iconv_close(handle);
951
952 delete[] outBuf;
953 delete[] inBuf;
954
955 return dst;
956 }
957
958 int ParseYesNo(const std::string & str, bool * val)
959 {
960 if (0 == strncasecmp(str.c_str(), "yes", 3))
961     {
962     *val = true;
963     return 0;
964     }
965
966 if (0 == strncasecmp(str.c_str(), "no", 2))
967     {
968     *val = false;
969     return 0;
970     }
971
972 return -1;
973 }
974
975 int ParseInt(const std::string & str, int * val)
976 {
977 if (str2x<int>(str, *val))
978     return -1;
979 return 0;
980 }
981
982 int ParseUnsigned(const string & str, unsigned * val)
983 {
984 if (str2x<unsigned>(str, *val))
985     return -1;
986 return 0;
987 }
988
989 int ParseIntInRange(const string & str, int min, int max, int * val)
990 {
991 if (ParseInt(str, val) != 0)
992     return -1;
993
994 if (*val < min || *val > max)
995     return -1;
996
997 return 0;
998 }
999
1000 int ParseUnsignedInRange(const string & str, unsigned min,
1001                          unsigned max, unsigned * val)
1002 {
1003 if (ParseUnsigned(str, val) != 0)
1004     return -1;
1005
1006 if (*val < min || *val > max)
1007     return -1;
1008
1009 return 0;
1010 }
1011
1012 bool WaitPackets(int sd)
1013 {
1014 fd_set rfds;
1015 FD_ZERO(&rfds);
1016 FD_SET(sd, &rfds);
1017
1018 struct timeval tv;
1019 tv.tv_sec = 0;
1020 tv.tv_usec = 500000;
1021
1022 int res = select(sd + 1, &rfds, NULL, NULL, &tv);
1023 if (res == -1) // Error
1024     {
1025     if (errno != EINTR)
1026         printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
1027     return false;
1028     }
1029
1030 if (res == 0) // Timeout
1031     return false;
1032
1033 return true;
1034 }