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