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