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