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