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