]> git.stg.codes - stg.git/blob - stglibs/ia.lib/ia.cpp
Replace deprecated usleep with POSIX-compliant nanosleep
[stg.git] / stglibs / ia.lib / ia.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 1, or (at your option)
5 ** 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., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17 /*
18  $Author: faust $
19  $Revision: 1.15 $
20  $Date: 2010/04/16 11:28:03 $
21 */
22
23 /*
24 * Author :
25 * Boris Mikhailenko <stg34@stargazer.dp.ua>
26 * Maxim Mamontov <faust@stargazer.dp.ua>
27 * Andrey Rakhmanov <andrey_rakhmanov@yahoo.com> - bugfixes.
28 */
29
30 //---------------------------------------------------------------------------
31
32 #include <cstdio>
33 #include <cstdlib>
34 #include <cstring>
35 #include <cassert>
36
37 #ifdef WIN32
38     #include <winsock2.h>
39     #include <windows.h>
40     #include <winbase.h>
41     #include <winnt.h>
42 #else
43     #include <fcntl.h>
44     #include <netdb.h>
45     #include <arpa/inet.h>
46     #include <unistd.h>
47 #endif
48
49 #include "stg/common.h"
50 #include "ia.h"
51
52 #define IA_NONE            (0)
53 #define IA_CONNECT         (1)
54 #define IA_DISCONNECT      (2)
55
56 #define IA_DEBUGPROTO   1
57
58 #define IA_ID "00100"
59 //---------------------------------------------------------------------------
60 //---------------------------------------------------------------------------
61 //---------------------------------------------------------------------------
62 #ifndef WIN32
63 #include <sys/time.h>
64 void * RunL(void * data)
65 {
66
67 IA_CLIENT_PROT * c = (IA_CLIENT_PROT *)data;
68 static int a = 0;
69
70 if (a == 0)
71     {
72     Sleep(50);
73     a = 1;
74     }
75
76 while (c->GetNonstop())
77     {
78     c->Run();
79     }
80 return NULL;
81 }
82 //---------------------------------------------------------------------------
83 void Sleep(int ms)
84 {
85 long long res = ms * 1000000;
86 struct timespec ts = {res / 1000000000, res % 1000000000};
87 nanosleep(&ts, NULL);
88 }
89 //---------------------------------------------------------------------------
90 long GetTickCount()
91 {
92 struct timeval tv;
93 gettimeofday(&tv, NULL);
94 return tv.tv_sec*1000 + tv.tv_usec/1000;
95 }
96 #else
97 //---------------------------------------------------------------------------
98 unsigned long WINAPI RunW(void * data)
99 {
100 IA_CLIENT_PROT * c = (IA_CLIENT_PROT *)data;
101 while (c->GetNonstop())
102     c->Run();
103 return 0;
104 }
105 //---------------------------------------------------------------------------
106 #endif
107 //---------------------------------------------------------------------------
108 //---------------------------------------------------------------------------
109 //---------------------------------------------------------------------------
110 IA_CLIENT_PROT::IA_CLIENT_PROT(const string & sn, unsigned short p, uint16_t localPort)
111     : action(IA_NONE),
112       phase(1),
113       phaseTime(0),
114       codeError(0),
115       nonstop(false),
116       isNetPrepared(false),
117       proxyMode(false),
118       serverName(sn),
119       port(p),
120       ip(0),
121       localPort(localPort),
122       firstConnect(true),
123       reconnect(0),
124       sockr(0),
125       protNum(0),
126       userTimeout(60),
127       aliveTimeout(5),
128       rnd(0),
129       pStatusChangedCb(NULL),
130       pStatChangedCb(NULL),
131       pInfoCb(NULL),
132       pErrorCb(NULL),
133       pDirNameCb(NULL),
134       statusChangedCbData(NULL),
135       statChangedCbData(NULL),
136       infoCbData(NULL),
137       errorCbData(NULL),
138       dirNameCbData(NULL),
139       connSyn8(NULL),
140       connSynAck8(NULL),
141       connAck8(NULL),
142       aliveSyn8(NULL),
143       aliveAck8(NULL),
144       disconnSyn8(NULL),
145       disconnSynAck8(NULL),
146       disconnAck8(NULL),
147       info(NULL)
148 {
149 memset(&stat, 0, sizeof(stat));
150
151 #ifdef WIN32
152 WSAStartup(MAKEWORD(2, 0), &wsaData);
153 #endif
154
155 packetTypes["CONN_SYN"] = CONN_SYN_N;
156 packetTypes["CONN_SYN_ACK"] = CONN_SYN_ACK_N;
157 packetTypes["CONN_ACK"] = CONN_ACK_N;
158 packetTypes["ALIVE_SYN"] = ALIVE_SYN_N;
159 packetTypes["ALIVE_ACK"] = ALIVE_ACK_N;
160 packetTypes["DISCONN_SYN"] = DISCONN_SYN_N;
161 packetTypes["DISCONN_SYN_ACK"] = DISCONN_SYN_ACK_N;
162 packetTypes["DISCONN_ACK"] = DISCONN_ACK_N;
163 packetTypes["FIN"] = FIN_N;
164 packetTypes["ERR"] = ERROR_N;
165 packetTypes["INFO"] = INFO_N;
166 packetTypes["INFO_7"] = INFO_7_N;
167 packetTypes["INFO_8"] = INFO_8_N;
168
169 unsigned char key[IA_PASSWD_LEN];
170 memset(key, 0, IA_PASSWD_LEN);
171 strncpy((char *)key, "pr7Hhen", 8);
172 Blowfish_Init(&ctxHdr, key, IA_PASSWD_LEN);
173
174 memset(key, 0, IA_PASSWD_LEN);
175 Blowfish_Init(&ctxPass, key, IA_PASSWD_LEN);
176
177 for (size_t i = 0; i < DIR_NUM; ++i)
178     {
179     selectedDirs[i] = false;
180     }
181
182 servAddr.sin_family = AF_INET;
183 servAddr.sin_port = htons(port);
184 servAddr.sin_addr.s_addr = ip;
185 }
186 //---------------------------------------------------------------------------
187 void IA_CLIENT_PROT::PrepareNet()
188 {
189 struct hostent * phe;
190 unsigned long ip;
191
192 ip = inet_addr(serverName.c_str());
193 if (ip == INADDR_NONE)
194     {
195     phe = gethostbyname(serverName.c_str());
196     if (phe)
197         {
198         ip = *((unsigned long*)phe->h_addr_list[0]);
199         }
200     else
201         {
202         strError = string("Unknown host ") + "\'" + serverName + "\'";
203         codeError = IA_GETHOSTBYNAME_ERROR;
204         if (pErrorCb != NULL)
205             pErrorCb(strError, IA_GETHOSTBYNAME_ERROR, errorCbData);
206         }
207     }
208
209 #ifndef WIN32
210 close(sockr);
211 #else
212 closesocket(sockr);
213 #endif
214
215 sockr = socket(AF_INET, SOCK_DGRAM, 0);
216
217 struct sockaddr_in  localAddrR;
218 localAddrR.sin_family = AF_INET;
219
220 if (localPort)
221     localAddrR.sin_port = htons(localPort);
222 else
223     localAddrR.sin_port = htons(port);
224 localAddrR.sin_addr.s_addr = inet_addr("0.0.0.0");
225
226 servAddr.sin_family = AF_INET;
227 servAddr.sin_port = htons(port);
228 servAddr.sin_addr.s_addr = ip;
229
230 int res = bind(sockr, (struct sockaddr*)&localAddrR, sizeof(localAddrR));
231 if (res == -1)
232     {
233     strError = "bind error";
234     codeError = IA_BIND_ERROR;
235     if (pErrorCb != NULL)
236         pErrorCb(strError, IA_BIND_ERROR, errorCbData);
237     return;
238     }
239
240 #ifdef WIN32
241 unsigned long arg = 1;
242 res = ioctlsocket(sockr, FIONBIO, &arg);
243 #else
244 if (0 != fcntl(sockr, F_SETFL, O_NONBLOCK))
245     {
246     strError = "fcntl error";
247     codeError = IA_FCNTL_ERROR;
248     if (pErrorCb != NULL)
249         pErrorCb(strError, IA_FCNTL_ERROR, errorCbData);
250     }
251 #endif
252
253 }
254 //---------------------------------------------------------------------------
255 IA_CLIENT_PROT::~IA_CLIENT_PROT()
256 {
257 #ifndef WIN32
258 close(sockr);
259 #else
260 closesocket(sockr);
261 WSACleanup();
262 #endif
263 }
264 //---------------------------------------------------------------------------
265 int IA_CLIENT_PROT::DeterminatePacketType(const char * buffer)
266 {
267 map<string, int>::iterator pi;
268 pi = packetTypes.find(buffer);
269 if (pi == packetTypes.end())
270     {
271     return -1;
272     }
273 else
274     {
275     return pi->second;
276     }
277 }
278 //---------------------------------------------------------------------------
279 void IA_CLIENT_PROT::FillHdr8(char * buffer, unsigned long)
280 {
281 strncpy(buffer, IA_ID, 6);
282 buffer[IA_MAGIC_LEN] = 0;
283 buffer[IA_MAGIC_LEN + 1] = IA_PROTO_VER;
284 strncpy(buffer + sizeof(HDR_8), login.c_str(), IA_LOGIN_LEN);
285 }
286 //---------------------------------------------------------------------------
287 int IA_CLIENT_PROT::Send(char * buffer, int len)
288 {
289 if (!isNetPrepared)
290     {
291     PrepareNet();
292     isNetPrepared = true;
293     }
294
295 int db = sizeof(HDR_8);
296 for (int i = 0; i < IA_LOGIN_LEN/8; i++)
297     {
298     Blowfish_Encrypt(&ctxHdr, (uint32_t*)(buffer + db + i*8), (uint32_t*)(buffer + db + i*8 + 4));
299     }
300
301 db += IA_LOGIN_LEN;
302 int encLen = (len - sizeof(HDR_8) - IA_LOGIN_LEN)/8;
303 for (int i = 0; i < encLen; i++)
304     {
305     Blowfish_Encrypt(&ctxPass, (uint32_t*)(buffer + db), (uint32_t*)(buffer + db + 4));
306     db += 8;
307     }
308
309 return sendto(sockr, buffer, len, 0, (struct sockaddr*)&servAddr, sizeof(servAddr));
310 }
311 //---------------------------------------------------------------------------
312 int IA_CLIENT_PROT::Recv(char * buffer, int len)
313 {
314 #ifdef WIN32
315 int fromLen;
316 #else
317 socklen_t fromLen;
318 #endif
319
320 struct sockaddr_in addr;
321 fromLen = sizeof(addr);
322 int res = recvfrom(sockr, buffer, len, 0, (struct sockaddr*)&addr, &fromLen);
323
324 if (res == -1)
325     return res;
326
327 if (strcmp(buffer + 4 + sizeof(HDR_8), "ERR"))
328     {
329     for (int i = 0; i < len/8; i++)
330         Blowfish_Decrypt(&ctxPass, (uint32_t*)(buffer + i*8), (uint32_t*)(buffer + i*8 + 4));
331     }
332
333 return 0;
334 }
335 //---------------------------------------------------------------------------
336 int IA_CLIENT_PROT::NetSend(int n)
337 {
338 char buffer[2048];
339 int msgLen;
340
341 memset(buffer, 0, 2048);
342
343 switch (n)
344     {
345     case CONN_SYN_N:
346         msgLen = Prepare_CONN_SYN_8(buffer);
347         break;
348
349     case CONN_ACK_N:
350         msgLen = Prepare_CONN_ACK_8(buffer);
351         break;
352
353     case ALIVE_ACK_N:
354         msgLen = Prepare_ALIVE_ACK_8(buffer);
355         break;
356
357     case DISCONN_SYN_N:
358         msgLen = Prepare_DISCONN_SYN_8(buffer);
359         break;
360
361     case DISCONN_ACK_N:
362         msgLen = Prepare_DISCONN_ACK_8(buffer);
363         break;
364
365     default:
366         return -1;
367     }
368
369 FillHdr8(buffer, 0);
370 Send(buffer, msgLen);
371
372 return 0;
373 }
374 //---------------------------------------------------------------------------
375 int IA_CLIENT_PROT::NetRecv()
376 {
377 char buffer[2048];
378
379 if (Recv(buffer, sizeof(buffer)) < 0)
380     return -1;
381
382 char packetName[20];
383 strncpy(packetName, buffer + 12, sizeof(packetName));
384 packetName[sizeof(packetName) - 1] = 0;
385 int pn = DeterminatePacketType(buffer + 12);
386
387 int ret;
388 switch (pn)
389     {
390     case CONN_SYN_ACK_N:
391         ret = Process_CONN_SYN_ACK_8(buffer);
392         break;
393
394     case ALIVE_SYN_N:
395         ret = Process_ALIVE_SYN_8(buffer);
396         break;
397
398     case DISCONN_SYN_ACK_N:
399         ret = Process_DISCONN_SYN_ACK_8(buffer);
400         break;
401
402     case FIN_N:
403         ret = Process_FIN_8(buffer);
404         break;
405
406     case INFO_8_N:
407         ret = Process_INFO_8(buffer);
408         break;
409
410     case ERROR_N:
411         ret = Process_ERROR(buffer);
412         break;
413
414     default:
415         ret = -1;
416     }
417 return ret;
418 }
419 //---------------------------------------------------------------------------
420 void IA_CLIENT_PROT::Start()
421 {
422 nonstop = true;
423 #ifdef WIN32
424 unsigned long pt;
425 CreateThread(NULL, 16384, RunW, this, 0, &pt);
426 #else
427 pthread_create(&thread, NULL, RunL, this);
428 #endif
429 }
430 //---------------------------------------------------------------------------
431 void IA_CLIENT_PROT::Stop()
432 {
433 nonstop = false;
434 }
435 //---------------------------------------------------------------------------
436 void IA_CLIENT_PROT::Run()
437 {
438 NetRecv();
439
440 switch (phase)
441     {
442     case 1:
443         if (action == IA_CONNECT)
444             {
445             action = IA_NONE;
446             NetSend(CONN_SYN_N);
447             phase = 2;
448             phaseTime = GetTickCount();
449             }
450         if (reconnect && !firstConnect)
451             {
452             action = IA_CONNECT;
453             }
454         break;
455
456     case 2:
457         if ((int)(GetTickCount() - phaseTime)/1000 > aliveTimeout)
458             {
459             phase = 1;
460             phaseTime = GetTickCount();
461             if (pStatusChangedCb != NULL)
462                 pStatusChangedCb(0, statusChangedCbData);
463             }
464
465         if (action == IA_DISCONNECT)
466             {
467             action = IA_NONE;
468             NetSend(DISCONN_SYN_N);
469             phase = 4;
470             phaseTime = GetTickCount();
471             }
472
473         break;
474
475     case 3:
476         if ((int)(GetTickCount() - phaseTime)/1000 > userTimeout)
477             {
478             phase = 1;
479             phaseTime = GetTickCount();
480             if (pStatusChangedCb != NULL)
481                 pStatusChangedCb(0, statusChangedCbData);
482             firstConnect = false;
483             }
484
485         if (action == IA_DISCONNECT)
486             {
487             action = IA_NONE;
488             NetSend(DISCONN_SYN_N);
489             phase = 4;
490             phaseTime = GetTickCount();
491             }
492
493         break;
494
495     case 4:
496         if ((int)(GetTickCount() - phaseTime)/1000 > aliveTimeout)
497             {
498             phase=1;
499             phaseTime = GetTickCount();
500             if (pStatusChangedCb != NULL)
501                 pStatusChangedCb(0, statusChangedCbData);
502             }
503
504         if (action == IA_CONNECT)
505             {
506             action = IA_NONE;
507             NetSend(CONN_SYN_N);
508             phase = 2;
509             phaseTime = GetTickCount();
510             }
511
512         break;
513
514     case 5:
515         if ((int)(GetTickCount() - phaseTime)/1000 > aliveTimeout)
516             {
517             phase = 1;
518             phaseTime = GetTickCount();
519             if (pStatusChangedCb != NULL)
520                 pStatusChangedCb(0, statusChangedCbData);
521             }
522
523         if (action == IA_CONNECT)
524             {
525             action = IA_NONE;
526             NetSend(CONN_SYN_N);
527             phase = 2;
528             phaseTime = GetTickCount();
529             }
530
531         break;
532     }
533 Sleep(20);
534 return;
535 }
536 //---------------------------------------------------------------------------
537 void IA_CLIENT_PROT::GetStat(LOADSTAT * ls)
538 {
539 memcpy(ls, &stat, sizeof(stat));
540 }
541 //---------------------------------------------------------------------------
542 void IA_CLIENT_PROT::SetServer(const string & sn, unsigned short p)
543 {
544 serverName = sn;
545 port = p;
546 PrepareNet();
547 }
548 //---------------------------------------------------------------------------
549 void IA_CLIENT_PROT::SetLogin(const string & l)
550 {
551 login = l;
552 }
553 //---------------------------------------------------------------------------
554 void IA_CLIENT_PROT::SetPassword(const string & p)
555 {
556 password = p;
557
558 unsigned char keyL[IA_PASSWD_LEN];
559 memset(keyL, 0, IA_PASSWD_LEN);
560 strncpy((char *)keyL, password.c_str(), IA_PASSWD_LEN);
561 Blowfish_Init(&ctxPass, keyL, IA_PASSWD_LEN);
562 }
563 //---------------------------------------------------------------------------
564 void IA_CLIENT_PROT::SetEnabledDirs(const bool * selectedDirs)
565 {
566 memcpy(IA_CLIENT_PROT::selectedDirs, selectedDirs, sizeof(bool) * DIR_NUM);
567 }
568 //---------------------------------------------------------------------------
569 int IA_CLIENT_PROT::Connect()
570 {
571 action = IA_CONNECT;
572 return 0;
573 }
574 //---------------------------------------------------------------------------
575 int IA_CLIENT_PROT::Disconnect()
576 {
577 firstConnect = true;
578 action = IA_DISCONNECT;
579 return 0;
580 }
581 //---------------------------------------------------------------------------
582 int IA_CLIENT_PROT::GetStrError(string * error) const
583 {
584 int ret = codeError;
585 *error = strError;
586 strError = "";
587 codeError = 0;
588 return ret;
589 }
590 //---------------------------------------------------------------------------
591 int IA_CLIENT_PROT::Process_CONN_SYN_ACK_8(const char * buffer)
592 {
593 vector<string> dirNames;
594 connSynAck8 = (CONN_SYN_ACK_8*)buffer;
595
596 #ifdef ARCH_BE
597 SwapBytes(connSynAck8->len);
598 SwapBytes(connSynAck8->rnd);
599 SwapBytes(connSynAck8->userTimeOut);
600 SwapBytes(connSynAck8->aliveDelay);
601 #endif
602
603 rnd = connSynAck8->rnd;
604 userTimeout = connSynAck8->userTimeOut;
605 aliveTimeout = connSynAck8->aliveDelay;
606
607 for (int i = 0; i < DIR_NUM; i++)
608     {
609     dirNames.push_back((const char*)connSynAck8->dirName[i]);
610     }
611
612 if (pDirNameCb != NULL)
613     pDirNameCb(dirNames, dirNameCbData);
614
615 NetSend(CONN_ACK_N);
616 phase = 3;
617 phaseTime = GetTickCount();
618
619 return CONN_SYN_ACK_N;
620 }
621 //---------------------------------------------------------------------------
622 int IA_CLIENT_PROT::Process_ALIVE_SYN_8(const char * buffer)
623 {
624 aliveSyn8 = (ALIVE_SYN_8*)buffer;
625
626 #ifdef ARCH_BE
627 SwapBytes(aliveSyn8->len);
628 SwapBytes(aliveSyn8->rnd);
629 SwapBytes(aliveSyn8->cash);
630 SwapBytes(aliveSyn8->status);
631 for (int i = 0; i < DIR_NUM; ++i)
632     {
633     SwapBytes(aliveSyn8->mu[i]);
634     SwapBytes(aliveSyn8->md[i]);
635     SwapBytes(aliveSyn8->su[i]);
636     SwapBytes(aliveSyn8->sd[i]);
637     }
638 #endif
639
640 rnd = aliveSyn8->rnd;
641 memcpy(&stat, (char*)aliveSyn8->mu, sizeof(stat));
642
643 if (pStatChangedCb != NULL)
644     pStatChangedCb(stat, statChangedCbData);
645
646 if (pStatusChangedCb != NULL)
647     pStatusChangedCb(1, statusChangedCbData);
648 NetSend(ALIVE_ACK_N);
649 phaseTime = GetTickCount();
650
651 return ALIVE_SYN_N;
652 }
653 //---------------------------------------------------------------------------
654 int IA_CLIENT_PROT::Process_DISCONN_SYN_ACK_8(const char * buffer)
655 {
656 disconnSynAck8 = (DISCONN_SYN_ACK_8*)buffer;
657
658 #ifdef ARCH_BE
659 SwapBytes(disconnSynAck8->len);
660 SwapBytes(disconnSynAck8->rnd);
661 #endif
662
663 rnd = disconnSynAck8->rnd;
664
665 NetSend(DISCONN_ACK_N);
666 phase = 5;
667 phaseTime = GetTickCount();
668
669 return DISCONN_SYN_ACK_N;
670 }
671 //---------------------------------------------------------------------------
672 int IA_CLIENT_PROT::Process_FIN_8(const char *)
673 {
674 phase = 1;
675 phaseTime = GetTickCount();
676 if (pStatusChangedCb != NULL)
677     pStatusChangedCb(0, statusChangedCbData);
678
679 return FIN_N;
680 }
681 //---------------------------------------------------------------------------
682 int IA_CLIENT_PROT::Process_INFO_8(const char * buffer)
683 {
684 info = (INFO_8*)buffer;
685
686 #ifdef ARCH_BE
687 SwapBytes(info->len);
688 SwapBytes(info->sendTime);
689 #endif
690
691 if (pInfoCb != NULL)
692     pInfoCb((char*)info->text, info->infoType, info->showTime, info->sendTime, infoCbData);
693 return INFO_8_N;
694 }
695 //---------------------------------------------------------------------------
696 int IA_CLIENT_PROT::Process_ERROR(const char * buffer)
697 {
698 ERR_8 err;
699 memcpy(&err, buffer, sizeof(err));
700
701 #ifdef ARCH_BE
702 SwapBytes(err.len);
703 #endif
704
705 KOIToWin((const char*)err.text, &messageText);
706 if (pErrorCb != NULL)
707     pErrorCb(messageText, IA_SERVER_ERROR, errorCbData);
708 phase = 1;
709 phaseTime = GetTickCount();
710 codeError = IA_SERVER_ERROR;
711
712 return ERROR_N;
713 }
714 //---------------------------------------------------------------------------
715 int IA_CLIENT_PROT::Prepare_CONN_SYN_8(char * buffer)
716 {
717 connSyn8 = (CONN_SYN_8*)buffer;
718
719 #ifdef ARCH_BE
720 SwapBytes(connSyn8->len);
721 #endif
722
723 assert(sizeof(CONN_SYN_8) == Min8(sizeof(CONN_SYN_8)) && "CONN_SYN_8 is not aligned to 8 bytes");
724
725 connSyn8->len = sizeof(CONN_SYN_8);
726 strncpy((char*)connSyn8->type, "CONN_SYN", IA_MAX_TYPE_LEN);
727 strncpy((char*)connSyn8->login, login.c_str(), IA_LOGIN_LEN);
728 connSyn8->dirs = 0;
729 for (int i = 0; i < DIR_NUM; i++)
730     {
731     connSyn8->dirs |= (selectedDirs[i] << i);
732     }
733 return connSyn8->len;
734 }
735 //---------------------------------------------------------------------------
736 int IA_CLIENT_PROT::Prepare_CONN_ACK_8(char * buffer)
737 {
738 connAck8 = (CONN_ACK_8*)buffer;
739
740 #ifdef ARCH_BE
741 SwapBytes(connAck8->len);
742 SwapBytes(connAck8->rnd);
743 #endif
744
745 assert(sizeof(CONN_ACK_8) == Min8(sizeof(CONN_ACK_8)) && "CONN_ACK_8 is not aligned to 8 bytes");
746
747 connAck8->len = sizeof(CONN_ACK_8);
748 strncpy((char*)connAck8->loginS, login.c_str(), IA_LOGIN_LEN);
749 strncpy((char*)connAck8->type, "CONN_ACK", IA_MAX_TYPE_LEN);
750 rnd++;
751 connAck8->rnd = rnd;
752
753 return connAck8->len;
754 }
755 //---------------------------------------------------------------------------
756 int IA_CLIENT_PROT::Prepare_ALIVE_ACK_8(char * buffer)
757 {
758 aliveAck8 = (ALIVE_ACK_8*)buffer;
759
760 #ifdef ARCH_BE
761 SwapBytes(aliveAck8->len);
762 SwapBytes(aliveAck8->rnd);
763 #endif
764
765 assert(Min8(sizeof(ALIVE_ACK_8)) == sizeof(ALIVE_ACK_8) && "ALIVE_ACK_8 is not aligned to 8 bytes");
766
767 aliveAck8 = (ALIVE_ACK_8*)buffer;
768 aliveAck8->len = sizeof(ALIVE_ACK_8);
769 strncpy((char*)aliveAck8->loginS, login.c_str(), IA_LOGIN_LEN);
770 strncpy((char*)aliveAck8->type, "ALIVE_ACK", IA_MAX_TYPE_LEN);
771 aliveAck8->rnd = ++rnd;
772 return aliveAck8->len;
773 }
774 //---------------------------------------------------------------------------
775 int IA_CLIENT_PROT::Prepare_DISCONN_SYN_8(char * buffer)
776 {
777 disconnSyn8 = (DISCONN_SYN_8*)buffer;
778
779 #ifdef ARCH_BE
780 SwapBytes(disconnSyn8->len);
781 #endif
782
783 assert(Min8(sizeof(DISCONN_SYN_8)) == sizeof(DISCONN_SYN_8) && "DISCONN_SYN_8 is not aligned to 8 bytes");
784
785 disconnSyn8->len = sizeof(DISCONN_SYN_8);
786 strncpy((char*)disconnSyn8->loginS, login.c_str(), IA_LOGIN_LEN);
787 strncpy((char*)disconnSyn8->type, "DISCONN_SYN", IA_MAX_TYPE_LEN);
788 strncpy((char*)disconnSyn8->login, login.c_str(), IA_LOGIN_LEN);
789 return disconnSyn8->len;
790 }
791 //---------------------------------------------------------------------------
792 int IA_CLIENT_PROT::Prepare_DISCONN_ACK_8(char * buffer)
793 {
794 disconnAck8 = (DISCONN_ACK_8*)buffer;
795
796 #ifdef ARCH_BE
797 SwapBytes(disconnAck8->len);
798 SwapBytes(disconnAck8->rnd);
799 #endif
800
801 assert(Min8(sizeof(DISCONN_ACK_8)) == sizeof(DISCONN_ACK_8) && "DISCONN_ACK_8 is not aligned to 8 bytes");
802
803 disconnAck8->len = Min8(sizeof(DISCONN_ACK_8));
804 disconnAck8->rnd = rnd + 1;
805 strncpy((char*)disconnAck8->loginS, login.c_str(), IA_LOGIN_LEN);
806 strncpy((char*)disconnAck8->type, "DISCONN_ACK", IA_MAX_TYPE_LEN);
807 return disconnAck8->len;
808 }
809 //---------------------------------------------------------------------------
810 void IA_CLIENT_PROT::SetStatusChangedCb(tpStatusChangedCb p, void * data)
811 {
812 pStatusChangedCb = p;
813 statusChangedCbData = data;
814 }
815 //---------------------------------------------------------------------------
816 void IA_CLIENT_PROT::SetStatChangedCb(tpStatChangedCb p, void * data)
817 {
818 pStatChangedCb = p;
819 statChangedCbData = data;
820 }
821 //---------------------------------------------------------------------------
822 void IA_CLIENT_PROT::SetInfoCb(tpCallBackInfoFn p, void * data)
823 {
824 pInfoCb = p;
825 infoCbData = data;
826 }
827 //---------------------------------------------------------------------------
828 void IA_CLIENT_PROT::SetDirNameCb(tpCallBackDirNameFn p, void * data)
829 {
830 pDirNameCb = p;
831 dirNameCbData = data;
832 }
833 //---------------------------------------------------------------------------
834 void IA_CLIENT_PROT::SetErrorCb(tpCallBackErrorFn p, void * data)
835 {
836 pErrorCb = p;
837 errorCbData = data;
838 }
839 //---------------------------------------------------------------------------