]> git.stg.codes - stg.git/blob - stglibs/ia_auth_c.lib/ia_auth_c.cpp
Добавляю экспериментальный плагин конфигуратора. Проект полумертв, но
[stg.git] / stglibs / ia_auth_c.lib / ia_auth_c.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 * Andrey Rakhmanov <andrey_rakhmanov@yahoo.com> - èñïðàâëåíèå äâóõ áàãîâ.
27 */
28
29 //---------------------------------------------------------------------------
30
31 #include <stdio.h>
32 #include <stdlib.h>
33
34 #include <string.h>
35
36 #ifdef WIN32
37     #include <winsock2.h>
38     #include <windows.h>
39     #include <winbase.h>
40     #include <winnt.h>
41 #else
42     #include <fcntl.h>
43     #include <sys/types.h>
44     #include <sys/socket.h>
45     #include <netdb.h>
46     #include <netinet/in.h>
47     #include <arpa/inet.h>
48     #include <unistd.h>
49 #endif
50
51 #include "common.h"
52 #include "ia_auth_c.h"
53
54 #define IA_NONE            (0)
55 #define IA_CONNECT         (1)
56 #define IA_DISCONNECT      (2)
57
58 #define IA_DEBUGPROTO   1
59
60 #define IA_ID "00100"
61 //---------------------------------------------------------------------------
62 //---------------------------------------------------------------------------
63 //---------------------------------------------------------------------------
64 #ifndef WIN32
65 #include <sys/time.h>
66 void * RunL(void * data)
67 {
68
69 IA_CLIENT_PROT * c = (IA_CLIENT_PROT *)data;
70 static int a = 0;
71
72 if (a == 0)
73     {
74     usleep(50000);
75     a = 1;
76     }
77
78 while (c->GetNonstop())
79     {
80     c->Run();
81     }
82 return NULL;
83 }
84 //---------------------------------------------------------------------------
85 void Sleep(int ms)
86 {
87 usleep(ms * 1000);
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     : stat(),
112       action(IA_NONE),
113       phase(1),
114       phaseTime(0),
115       messageText(),
116       infoText(),
117       strError(),
118       codeError(0),
119       nonstop(true),
120       isNetPrepared(false),
121       proxyMode(false),
122       password(),
123       login(),
124       serverName(sn),
125       port(p),
126       ip(0),
127       localPort(localPort),
128       firstConnect(true),
129       reconnect(0),
130       sockr(0),
131       protNum(0),
132       userTimeout(60),
133       aliveTimeout(5),
134       rnd(0),
135       pStatusChangedCb(NULL),
136       pStatChangedCb(NULL),
137       pInfoCb(NULL),
138       pErrorCb(NULL),
139       pDirNameCb(NULL),
140       statusChangedCbData(NULL),
141       statChangedCbData(NULL),
142       infoCbData(NULL),
143       errorCbData(NULL),
144       dirNameCbData(NULL),
145       packetTypes(),
146       connSyn8(NULL),
147       connSynAck8(NULL),
148       connAck8(NULL),
149       aliveSyn8(NULL),
150       aliveAck8(NULL),
151       disconnSyn8(NULL),
152       disconnSynAck8(NULL),
153       disconnAck8(NULL),
154       err(),
155       info(NULL)
156 {
157 memset(&stat, 0, sizeof(stat));
158
159 #ifdef WIN32
160 WSAStartup(MAKEWORD(2, 0), &wsaData);
161 #endif
162
163 packetTypes["CONN_SYN"] = CONN_SYN_N;
164 packetTypes["CONN_SYN_ACK"] = CONN_SYN_ACK_N;
165 packetTypes["CONN_ACK"] = CONN_ACK_N;
166 packetTypes["ALIVE_SYN"] = ALIVE_SYN_N;
167 packetTypes["ALIVE_ACK"] = ALIVE_ACK_N;
168 packetTypes["DISCONN_SYN"] = DISCONN_SYN_N;
169 packetTypes["DISCONN_SYN_ACK"] = DISCONN_SYN_ACK_N;
170 packetTypes["DISCONN_ACK"] = DISCONN_ACK_N;
171 packetTypes["FIN"] = FIN_N;
172 packetTypes["ERR"] = ERROR_N;
173 packetTypes["INFO"] = INFO_N;
174 packetTypes["INFO_7"] = INFO_7_N;
175 packetTypes["INFO_8"] = INFO_8_N;
176
177 unsigned char key[IA_PASSWD_LEN];
178 memset(key, 0, IA_LOGIN_LEN);
179 strncpy((char *)key, "pr7Hhen", 8);
180 Blowfish_Init(&ctxHdr, key, IA_PASSWD_LEN);
181 }
182 //---------------------------------------------------------------------------
183 void IA_CLIENT_PROT::PrepareNet()
184 {
185 struct hostent * phe;
186 unsigned long ip;
187
188 ip = inet_addr(serverName.c_str());
189 if (ip == INADDR_NONE)
190     {
191     phe = gethostbyname(serverName.c_str());
192     if (phe)
193         {
194         ip = *((unsigned long*)phe->h_addr_list[0]);
195         }
196     else
197         {
198         strError = string("Unknown host ") + "\'" + serverName + "\'";
199         codeError = IA_GETHOSTBYNAME_ERROR;
200         if (pErrorCb != NULL)
201             pErrorCb(messageText, IA_GETHOSTBYNAME_ERROR, errorCbData);
202         }
203     }
204
205 #ifndef WIN32
206 close(sockr);
207 #else
208 closesocket(sockr);
209 #endif
210
211 sockr = socket(AF_INET, SOCK_DGRAM, 0);  // Cîêåò ÷åðåç êîòîðûé øëåì è ïðèíèìàåì
212
213 localAddrS.sin_family = AF_INET;
214 localAddrS.sin_port = htons(port);
215 localAddrS.sin_addr.s_addr = inet_addr("0.0.0.0");
216
217 localAddrR.sin_family = AF_INET;
218
219 if (localPort)
220     localAddrR.sin_port = htons(localPort);
221 else
222     localAddrR.sin_port = htons(port);
223 localAddrR.sin_addr.s_addr = inet_addr("0.0.0.0");
224
225 servAddr.sin_family = AF_INET;
226 servAddr.sin_port = htons(port);
227 servAddr.sin_addr.s_addr = ip;
228
229 int res = bind(sockr, (struct sockaddr*)&localAddrR, sizeof(localAddrR));
230 if (res == -1)
231     {
232     strError = "bind error";
233     codeError = IA_BIND_ERROR;
234     if (pErrorCb != NULL)
235         pErrorCb(messageText, IA_BIND_ERROR, errorCbData);
236     return;
237     }
238
239 #ifdef WIN32
240 unsigned long arg = 1;
241 res = ioctlsocket(sockr, FIONBIO, &arg);
242 #else
243 if (0 != fcntl(sockr, F_SETFL, O_NONBLOCK))
244     {
245     strError = "fcntl error";
246     codeError = IA_FCNTL_ERROR;
247     if (pErrorCb != NULL)
248         pErrorCb(messageText, IA_FCNTL_ERROR, errorCbData);
249     }
250 #endif
251
252 }
253 //---------------------------------------------------------------------------
254 IA_CLIENT_PROT::~IA_CLIENT_PROT()
255 {
256 #ifndef WIN32
257 close(sockr);
258 #else
259 closesocket(sockr);
260 WSACleanup();
261 #endif
262 }
263 //---------------------------------------------------------------------------
264 int IA_CLIENT_PROT::DeterminatePacketType(const char * buffer)
265 {
266 map<string, int>::iterator pi;
267 pi = packetTypes.find(buffer);
268 if (pi == packetTypes.end())
269     {
270     return -1;
271     }
272 else
273     {
274     return pi->second;
275     }
276 }
277 //---------------------------------------------------------------------------
278 void IA_CLIENT_PROT::FillHdr8(char * buffer, unsigned long)
279 {
280 strncpy(buffer, IA_ID, 6);
281 buffer[IA_MAGIC_LEN] = 0;
282 buffer[IA_MAGIC_LEN + 1] = IA_PROTO_VER;
283 strncpy(buffer + sizeof(HDR_8), login.c_str(), IA_LOGIN_LEN);
284 }
285 //---------------------------------------------------------------------------
286 int IA_CLIENT_PROT::Send(char * buffer, int len)
287 {
288 if (!isNetPrepared)
289     {
290     PrepareNet();
291     isNetPrepared = true;
292     }
293
294 // Øèôðóåì LoginS
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 // Øèôðóåì âñ¸ îñòàëüíîå
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 #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 memcpy(&err, buffer, sizeof(err));
699
700 #ifdef ARCH_BE
701 SwapBytes(err.len);
702 #endif
703
704 KOIToWin((const char*)err.text, &messageText);
705 if (pErrorCb != NULL)
706     pErrorCb(messageText, IA_SERVER_ERROR, errorCbData);
707 phase = 1;
708 phaseTime = GetTickCount();
709 codeError = IA_SERVER_ERROR;
710
711 return ERROR_N;
712 }
713 //---------------------------------------------------------------------------
714 int IA_CLIENT_PROT::Prepare_CONN_SYN_8(char * buffer)
715 {
716 connSyn8 = (CONN_SYN_8*)buffer;
717
718 #ifdef ARCH_BE
719 SwapBytes(connSyn8->len);
720 #endif
721
722 connSyn8->len = sizeof(CONN_SYN_8);
723 #ifdef IA_DEBUGPROTO
724 if (sizeof(CONN_SYN_8) != Min8(sizeof(CONN_SYN_8)))
725     {
726     int * a = NULL;
727     *a = 0;
728     }
729 #endif
730
731 strncpy((char*)connSyn8->type, "CONN_SYN", IA_MAX_TYPE_LEN);
732 strncpy((char*)connSyn8->login, login.c_str(), IA_LOGIN_LEN);
733 connSyn8->dirs = 0;
734 for (int i = 0; i < DIR_NUM; i++)
735     {
736     connSyn8->dirs |= (selectedDirs[i] << i);
737     }
738 return connSyn8->len;
739 }
740 //---------------------------------------------------------------------------
741 int IA_CLIENT_PROT::Prepare_CONN_ACK_8(char * buffer)
742 {
743 connAck8 = (CONN_ACK_8*)buffer;
744
745 #ifdef ARCH_BE
746 SwapBytes(connAck8->len);
747 SwapBytes(connAck8->rnd);
748 #endif
749
750 #ifdef IA_DEBUGPROTO
751 if (sizeof(CONN_ACK_8) != Min8(sizeof(CONN_ACK_8)))
752     {
753     int * a = NULL;
754     *a = 0;
755     }
756 #endif
757
758 connAck8->len = sizeof(CONN_ACK_8);
759 strncpy((char*)connAck8->loginS, login.c_str(), IA_LOGIN_LEN);
760 strncpy((char*)connAck8->type, "CONN_ACK", IA_MAX_TYPE_LEN);
761 rnd++;
762 connAck8->rnd = rnd;
763
764 return connAck8->len;
765 }
766 //---------------------------------------------------------------------------
767 int IA_CLIENT_PROT::Prepare_ALIVE_ACK_8(char * buffer)
768 {
769 aliveAck8 = (ALIVE_ACK_8*)buffer;
770
771 #ifdef ARCH_BE
772 SwapBytes(aliveAck8->len);
773 SwapBytes(aliveAck8->rnd);
774 #endif
775
776 #ifdef IA_DEBUGPROTO
777 if (Min8(sizeof(ALIVE_ACK_8)) != sizeof(ALIVE_ACK_8))
778     {
779     int * a = NULL;
780     *a = 0;
781     }
782 #endif
783
784 aliveAck8 = (ALIVE_ACK_8*)buffer;
785 aliveAck8->len = sizeof(ALIVE_ACK_8);
786 strncpy((char*)aliveAck8->loginS, login.c_str(), IA_LOGIN_LEN);
787 strncpy((char*)aliveAck8->type, "ALIVE_ACK", IA_MAX_TYPE_LEN);
788 aliveAck8->rnd = ++rnd;
789 return aliveAck8->len;
790 }
791 //---------------------------------------------------------------------------
792 int IA_CLIENT_PROT::Prepare_DISCONN_SYN_8(char * buffer)
793 {
794 disconnSyn8 = (DISCONN_SYN_8*)buffer;
795
796 #ifdef ARCH_BE
797 SwapBytes(disconnSyn8->len);
798 #endif
799
800 #ifdef IA_DEBUGPROTO
801 if (Min8(sizeof(DISCONN_SYN_8)) != sizeof(DISCONN_SYN_8))
802     {
803     int * a = NULL;
804     *a = 0;
805     }
806 #endif
807
808 disconnSyn8->len = sizeof(DISCONN_SYN_8);
809 strncpy((char*)disconnSyn8->loginS, login.c_str(), IA_LOGIN_LEN);
810 strncpy((char*)disconnSyn8->type, "DISCONN_SYN", IA_MAX_TYPE_LEN);
811 strncpy((char*)disconnSyn8->login, login.c_str(), IA_LOGIN_LEN);
812 return disconnSyn8->len;
813 }
814 //---------------------------------------------------------------------------
815 int IA_CLIENT_PROT::Prepare_DISCONN_ACK_8(char * buffer)
816 {
817 disconnAck8 = (DISCONN_ACK_8*)buffer;
818
819 #ifdef ARCH_BE
820 SwapBytes(disconnAck8->len);
821 SwapBytes(disconnAck8->rnd);
822 #endif
823
824 #ifdef IA_DEBUGPROTO
825 if (Min8(sizeof(DISCONN_ACK_8)) != sizeof(DISCONN_ACK_8))
826     {
827     int * a = NULL;
828     *a = 0;
829     }
830 #endif
831
832 disconnAck8->len = Min8(sizeof(DISCONN_ACK_8));
833 disconnAck8->rnd = rnd + 1;
834 strncpy((char*)disconnAck8->loginS, login.c_str(), IA_LOGIN_LEN);
835 strncpy((char*)disconnAck8->type, "DISCONN_ACK", IA_MAX_TYPE_LEN);
836 return disconnAck8->len;
837 }
838 //---------------------------------------------------------------------------
839 void IA_CLIENT_PROT::SetStatusChangedCb(tpStatusChangedCb p, void * data)
840 {
841 pStatusChangedCb = p;
842 statusChangedCbData = data;
843 }
844 //---------------------------------------------------------------------------
845 void IA_CLIENT_PROT::SetStatChangedCb(tpStatChangedCb p, void * data)
846 {
847 pStatChangedCb = p;
848 statChangedCbData = data;
849 }
850 //---------------------------------------------------------------------------
851 void IA_CLIENT_PROT::SetInfoCb(tpCallBackInfoFn p, void * data)
852 {
853 pInfoCb = p;
854 infoCbData = data;
855 }
856 //---------------------------------------------------------------------------
857 void IA_CLIENT_PROT::SetDirNameCb(tpCallBackDirNameFn p, void * data)
858 {
859 pDirNameCb = p;
860 dirNameCbData = data;
861 }
862 //---------------------------------------------------------------------------
863 void IA_CLIENT_PROT::SetErrorCb(tpCallBackErrorFn p, void * data)
864 {
865 pErrorCb = p;
866 errorCbData = data;
867 }
868 //---------------------------------------------------------------------------