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