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