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