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