home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 13 / AACD13.ISO / AACD / Online / StrICQ / Src / stricq.c < prev    next >
C/C++ Source or Header  |  2000-08-21  |  252KB  |  9,542 lines

  1. /*
  2.  
  3. STRICQ - An Amiga, MUI Based, ICQ Clone.
  4. Copyright (C) 1998-2000 Douglas F. McLaughlin
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20. Douglas F. McLaughlin - stricq@owlnet.net
  21.  
  22. */
  23.  
  24. #include <sys/types.h>
  25.  
  26. #include <ctype.h>
  27. #include <math.h>
  28. #include <netdb.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <stdarg.h>
  32. #include <string.h>
  33. #include <time.h>
  34. #include <unistd.h>
  35.  
  36. #include <exec/types.h>
  37. #include <exec/memory.h>
  38.  
  39. #include <devices/timer.h>
  40.  
  41. #include <intuition/screens.h>
  42.  
  43. #include <libraries/asl.h>
  44. #include <libraries/asyncio.h>
  45. #include <libraries/icq.h>
  46. #include <libraries/openurl.h>
  47.  
  48. #include <bsdsocket/socketbasetags.h>
  49.  
  50. #include <rexx/storage.h>
  51.  
  52. #include <sys/dir.h>
  53. #include <sys/errno.h>
  54. #include <sys/ioctl.h>
  55. #include <sys/socket.h>
  56. #include <sys/time.h>
  57.  
  58. #include <utility/date.h>
  59.  
  60. #include <proto/asyncio.h>
  61. #include <proto/dos.h>
  62. #include <proto/exec.h>
  63. #include <proto/intuition.h>
  64. #include <proto/miami.h>
  65. #include <proto/openurl.h>
  66. #include <proto/utility.h>
  67.  
  68. #include "STRICQMUI.h"
  69. #include "STRICQ_Cat.h"
  70. #include "cmd_codes.h"
  71. #include "countries.h"
  72. #include "codes.h"
  73.  
  74. #include <proto/socket.h>
  75.  
  76. APTR __asm AddOffline(REG(a2) APTR, REG(a1) struct Contact *);
  77. void __asm RemOffline(REG(a2) APTR, REG(a1) struct Contact *);
  78. LONG __asm CmpOffline(REG(a1) struct Contact *, REG(a2) struct Contact *);
  79. void __asm DisplayOffline(REG(a2) char **, REG(a1) struct Contact *);
  80.  
  81. APTR __asm AddLog(REG(a2) APTR, REG(a1) struct ICQLog *);
  82. void __asm RemLog(REG(a2) APTR, REG(a1) struct ICQLog *);
  83. LONG __asm CmpLog(REG(a1) struct ICQLog *, REG(a2) struct ICQLog *);
  84. void __asm DisplayLog(REG(a2) char **, REG(a1) struct ICQLog *);
  85.  
  86. APTR __asm AddMsg(REG(a2) APTR, REG(a1) struct ICQMessage *);
  87. void __asm RemMsg(REG(a2) APTR, REG(a1) struct ICQMessage *);
  88. LONG __asm CmpMsg(REG(a1) struct ICQMessage *, REG(a2) struct ICQMessage *);
  89. void __asm DisplayMsg(REG(a2) char **, REG(a1) struct ICQMessage *);
  90.  
  91. APTR __asm AddActy(REG(a2) APTR, REG(a1) struct Activity *);
  92. void __asm RemActy(REG(a2) APTR, REG(a1) struct Activity *);
  93. LONG __asm CmpActy(REG(a1) struct Activity *, REG(a2) struct Activity *);
  94. void __asm DisplayActy(REG(a2) char **, REG(a1) struct Activity *);
  95.  
  96. APTR __asm AddSock(REG(a2) APTR, REG(a1) struct Sockets *);
  97. void __asm RemSock(REG(a2) APTR, REG(a1) struct Sockets *);
  98. LONG __asm CmpSock(REG(a1) struct Sockets *, REG(a2) struct Sockets *);
  99. void __asm DisplaySock(REG(a2) char **, REG(a1) struct Sockets *);
  100.  
  101. APTR __asm AddCols(REG(a2) APTR, REG(a1) struct Column *);
  102. void __asm RemCols(REG(a2) APTR, REG(a1) struct Column *);
  103. LONG __asm CmpCols(REG(a1) struct Column *, REG(a2) struct Column *);
  104. void __asm DisplayCols(REG(a2) char **, REG(a1) struct Column *);
  105.  
  106. APTR __asm AddIgnore(REG(a2) APTR, REG(a1) struct IgnoreUIN *);
  107. void __asm RemIgnore(REG(a2) APTR, REG(a1) struct IgnoreUIN *);
  108. LONG __asm CmpIgnore(REG(a1) struct IgnoreUIN *, REG(a2) struct IgnoreUIN *);
  109. void __asm DisplayIgnore(REG(a2) char **, REG(a1) struct IgnoreUIN *);
  110.  
  111. APTR __asm AddAddUIN(REG(a2) APTR, REG(a1) struct MSG_AddUIN *);
  112. void __asm RemAddUIN(REG(a2) APTR, REG(a1) struct MSG_AddUIN *);
  113. LONG __asm CmpAddUIN(REG(a1) struct MSG_AddUIN *, REG(a2) struct MSG_AddUIN *);
  114. void __asm DisplayAddUIN(REG(a2) char **, REG(a1) struct MSG_AddUIN *);
  115.  
  116. APTR __asm AddErr(REG(a2) APTR, REG(a1) struct ErrorMsgs *);
  117. void __asm RemErr(REG(a2) APTR, REG(a1) struct ErrorMsgs *);
  118. LONG __asm CmpErr(REG(a1) struct ErrorMsgs *, REG(a2) struct ErrorMsgs *);
  119. void __asm DisplayErr(REG(a2) char **, REG(a1) struct ErrorMsgs *);
  120.  
  121. extern APTR __asm AddFile(REG(a2) APTR, REG(a1) struct FileList *);
  122. extern void __asm RemFile(REG(a2) APTR, REG(a1) struct FileList *);
  123. extern LONG __asm CmpFile(REG(a1) struct FileList *, REG(a2) struct FileList *);
  124. extern void __asm DisplayFile(REG(a2) char **, REG(a1) struct FileList *);
  125.  
  126. void __asm GetUINInfo(REG(a2) APTR);
  127. void __asm AddContact(REG(a2) APTR);
  128. void __asm ConnectICQ(REG(a2) APTR);
  129. void __asm DisconnectICQ(REG(a2) APTR);
  130. void __asm ChangePW(REG(a2) APTR);
  131. void __asm SendMessage(REG(a2) APTR);
  132. void __asm SendMsg2ICQ(REG(a2) APTR);
  133. void __asm SendMsg2ICQa(REG(a2) APTR);
  134. void __asm AddUpdate(REG(a2) APTR);
  135. void __asm SetQuickTo(REG(a2) APTR);
  136. void __asm ChangeMyStatus(REG(a2) APTR);
  137. void __asm SavePrefs(REG(a2) APTR);
  138. void __asm LoadPrefs(REG(a2) APTR);
  139. void __asm GoURL(REG(a2) APTR);
  140. void __asm AddServer(REG(a2) APTR);
  141. void __asm OpenWin(REG(a2) APTR);
  142. void __asm ViewHistory(REG(a2) APTR);
  143. void __asm SendUInfo1(REG(a2) APTR);
  144. void __asm SendUInfo2(REG(a2) APTR);
  145. void __asm NewUIN(REG(a2) APTR);
  146. void __asm MakeFilenames(REG(a2) APTR);
  147. void __asm ChangeMyUIN(REG(a2) APTR);
  148. void __asm SaveMsgWin(REG(a2) APTR);
  149. void __asm PrepFunctionWin(REG(a2) APTR);
  150. void __asm NewUserWin(REG(a2) APTR);
  151. void __asm SaveContactJump(REG(a2) APTR);
  152. void __asm LoadContactJump(REG(a2) APTR);
  153. void __asm LoadHistory(REG(a2) APTR);
  154. void __asm SaveHistory(REG(a2) APTR);
  155. void __asm DeleteHistory(REG(a2) APTR);
  156. void __asm RemoveContact(REG(a2) APTR);
  157. void __asm SendChatReq(REG(a2) APTR);
  158. void __asm Accept(REG(a2) APTR);
  159. void __asm Refuse(REG(a2) APTR);
  160. void __asm OpenChatReqWin(REG(a2) APTR);
  161. void __asm EndChat(REG(a2) APTR);
  162. void __asm Add2Ignore(REG(a2) APTR);
  163. void __asm ForwardMsg(REG(a2) APTR);
  164. void __asm SetCountry(REG(a2) APTR);
  165. void __asm GetAddUINInfo(REG(a2) APTR);
  166. void __asm ShareContacts(REG(a2) APTR);
  167. void __asm SaveErrors(REG(a2) APTR);
  168. void __asm SetUserVisPrefs(REG(a2) APTR);
  169. void __asm OpenEditIgnore(REG(a2) APTR);
  170. void __asm SetIgnoreEdits(REG(a2) APTR);
  171. void __asm ChangeZodiac(REG(a2) APTR);
  172. void __asm ResetSockets(REG(a2) APTR);
  173.  
  174. extern void __asm OpenFileDirectWin(REG(a2) APTR);
  175.  
  176. void fail(struct ObjApp *, char *);
  177.  
  178. ULONG __asm MyDispatcher(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg);
  179. ULONG __asm TimeDispatcher(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg);
  180. ULONG __asm ColorDispatcher(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg);
  181. ULONG __asm ColsDispatcher(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg);
  182.  
  183. ULONG PORT_NewUDP(struct IClass *, Object *, Msg);
  184. ULONG PORT_Dispose(struct IClass *, Object *, Msg);
  185. ULONG PORT_Setup(struct IClass *, Object *, Msg);
  186. ULONG PORT_Cleanup(struct IClass *, Object *, Msg);
  187. ULONG PORT_Trigger_cl(struct IClass *, Object *, Msg);
  188.  
  189. ULONG TIME_New(struct IClass *, Object *, Msg);
  190. ULONG TIME_Set(struct IClass *, Object *, Msg);
  191. ULONG TIME_Dispose(struct IClass *, Object *, Msg);
  192. ULONG TIME_Setup(struct IClass *, Object *, Msg);
  193. ULONG TIME_Cleanup(struct IClass *, Object *, Msg);
  194. ULONG TIME_Trigger_cl(struct IClass *, Object *, Msg);
  195. ULONG TIME_Trigger_cl1(struct IClass *, Object *, Msg);
  196. ULONG SendAFile(struct IClass *cl, Object *obj, Msg msg);
  197. ULONG ParseUDPCommands(struct IClass *cl, Object *obj, Msg msg);
  198.  
  199. ULONG COLOR_Set(struct IClass *, Object *, Msg);
  200. ULONG COLOR_Setup(struct IClass *, Object *, Msg);
  201. ULONG COLOR_Cleanup(struct IClass *, Object *, Msg);
  202. ULONG COLOR_Draw(struct IClass *, Object *, struct MUIP_Draw *);
  203.  
  204. ULONG COLS_mDragQuery(struct IClass *, Object *, struct MUIP_DragDrop *msg);
  205. ULONG COLS_mDragDrop(struct IClass *, Object *, struct MUIP_DragDrop *msg);
  206.  
  207. int send_udp_pkt(void *, int, ULONG);
  208. int recv_udp_pkt(void *, int, struct Sockets *);
  209. void revmemcpy(char *, char *, int);
  210. void ParseCmd(UWORD, UWORD, char *, int);
  211. void SendContacts(ULONG, UWORD);
  212. void ParseMessage(UWORD, char *, ULONG, UWORD);
  213. char *ParseMsgHdr(char *, struct Contact *);
  214. void SendAMessage(APTR, ULONG, char *, UWORD, UBYTE, int);
  215. char *GetNick(ULONG);
  216. void ContactsOffline(void);
  217. BOOL OpenICQSocket(void);
  218. void StoreMessage(struct ICQMessage *, ULONG, UWORD);
  219. BOOL MyCreateDir(char *);
  220. BOOL CreateUserWin(ULONG);
  221. struct Contact *GetContact(ULONG);
  222. struct Sockets *GetSocketFmSocket(UWORD);
  223. struct Sockets *GetSocketFmPort(UWORD);
  224. void UpdateUserWin(struct Contact *);
  225. struct ColorText *GetStatus(ULONG);
  226. void SaveContact(ULONG);
  227. BOOL LoadContact(ULONG);
  228. void SaveAllContacts(void);
  229. int  recv_tcp_pkt(char *, struct Sockets *);
  230. int  recv_chat(char *, UWORD);
  231. void ParseTCPCmd(char *, int, UWORD);
  232. BOOL SendTCPMessage(ULONG, char *, UWORD, UWORD, UWORD, ULONG, char *, ULONG, UWORD, ULONG);
  233. LONG OpenTCPSocket(struct Contact *, UBYTE, ULONG, ULONG);
  234. void SendTCPInit(UWORD, struct Contact *, ULONG);
  235. void PrepNewContact(struct Contact *);
  236. void DelSockets(UWORD);
  237. struct Sockets *GetSocketFmContact(struct Contact *, UBYTE);
  238. char *FindCountryName(UWORD);
  239. void SendMessage2Script(char *, ULONG, UWORD);
  240. void SendPing(void);
  241. void AddUser2CList(struct Contact *);
  242. void CFWinOpen(ULONG, char *, UWORD, LONG, UWORD);
  243. ULONG OpenTCPListen(UBYTE);
  244. void SendChatInit(UWORD);
  245. void ParseChatPkt(char *, int, UWORD);
  246. void DoChatMode(char *, int, UWORD);
  247. void ReDrawCList(void);
  248. BOOL CheckIgnore(ULONG);
  249. void Add2Log(UBYTE, struct UDP_Header *, BOOL, UWORD, char *);
  250. char *PreParseMsg(ULONG, UWORD, char *);
  251. UWORD MakeBeats(time_t);
  252. void HandleError(UBYTE, char *, ...);
  253. void PrepTCPMessage(struct TCP_Message *, ULONG);
  254. LONG SendTCPPacket(ULONG, UWORD, char *, UWORD, UWORD);
  255. void SendTCPMsgViaUDP(ULONG);
  256. void SendDelayedTCP(struct Sockets *);
  257. void HandleACK(char *, UWORD);
  258. void InfoView(APTR, UBYTE);
  259. void InfoRefresh(APTR, UBYTE);
  260. void InfoGrabMe(APTR, UBYTE);
  261. void ChangeZodiacPic(struct Contact *, BOOL);
  262. void FreeUser(struct Contact *);
  263. BOOL RefreshUInfo(char **, char *);
  264. void DeleteUIN(ULONG);
  265.  
  266. extern void ParseFilePkt(char *, int, UWORD);
  267. extern BOOL StartFileXFer(struct Contact *, BOOL);
  268. extern void EndFile(struct Contact *);
  269. extern ULONG GetSize(struct FileList *files);
  270. extern void SendFileInit(UWORD, struct Contact *);
  271.  
  272.  
  273. struct ICQLog {
  274.   ULONG UIN;
  275.   ULONG Seq;
  276.   UWORD Se2;
  277.   UWORD Cmd;
  278.   BOOL  Ack;
  279.   UWORD Len;
  280.   UBYTE Resend;
  281.   time_t Timehack;
  282.   UBYTE *Pkt;
  283. };
  284.  
  285. struct ICQMessage {
  286.   ULONG  UIN;
  287.   time_t Timehack;
  288.   UWORD Type;
  289.   char  *Msg;
  290. };
  291.  
  292. struct Activity {
  293.   ULONG UIN;
  294.   ULONG Status;
  295.   time_t Timehack;
  296. };
  297.  
  298. struct MUIP_PT_AddApp {
  299.   ULONG MethodID;
  300.   Object *App;
  301. };
  302.  
  303. struct Column {
  304.   char *Name;
  305.   char *COL;
  306. };
  307.  
  308.  
  309. struct Colors Pens;
  310.  
  311. struct Library *MUIMasterBase, *SocketBase, *AsyncIOBase, *MiamiBase, *OpenURLBase;
  312.  
  313. struct ObjApp *app;
  314.  
  315. BOOL Online, TryAgain, SocketOpen, FirstLogin, NewUser, GrabMyStats, OpenURL, ARexx, Reconnecting, OldPrefsFmt;
  316.  
  317. /* Fonctions necessary for Localization of the Menus&Arrays... */
  318. extern void localise_array(char *array[])
  319. {
  320.     char **x;
  321.  
  322.     for(x=array;*x;x++)
  323.         *x = (char *)((struct FC_String *)(*x))->msg;
  324. }
  325.  
  326. char version_string[] = "$VER: STRICQ (68020) 0.1732 (20.08.00)\n\nCopyright © 1998-2000 Douglas F. McLaughlin&Nogfx\nICQ Protocol Copyright © 1996 Mirabilis LTD.\n\nAll Rights Reserved.";
  327.  
  328. extern char *UPages[] = {
  329.     (char*)_msgUPDialogue,
  330.     (char*)_msgUPSend,
  331.     (char*)_msgUPUsrInfo,
  332.     (char*)_msgUPHistory,
  333. NULL
  334. };
  335.  
  336. // char *UPages[]   = {"Dialogue", "Send URL", "User Info", "History", NULL};
  337.  
  338.  
  339. extern char *UPagesUI[] = {
  340.     (char*)_msgUPUIBasic,
  341.     (char*)_msgUPUIExtended,
  342.     (char*)_msgUPUIPrefs,
  343. NULL
  344. };
  345.  
  346. // char *UPagesUI[] = {"Basic Info", "Extended Info", "Prefs", NULL};
  347.  
  348.  
  349. extern char *InfoPages[] = {
  350.     (char*)_msgInfoMain,
  351.     (char*)_msgInfoHome,
  352.     (char*)_msgInfoMore,
  353.     (char*)_msgInfoAbout,
  354.     (char*)_msgInfoPrefs,
  355. NULL
  356. };
  357.  
  358.  
  359. // char *InfoPages[] = {"Main", "Home", "More", "Info/About", "Prefs", NULL};
  360.  
  361. /*
  362. extern char *Columns[][2] = {
  363.     {(char*)_msgColLamp1, (char*)_msgColLamp2},
  364.     {(char*)_msgColUIN1, (char*)_msgColUIN2},
  365.     {(char*)_msgColStatus1, (char*)_msgColStatus2},
  366.     {(char*)_msgColNick1, (char*)_msgColNick2},
  367.     {(char*)_msgColName1, (char*)_msgColName2},
  368.     {(char*)_msgColEMail1, (char*)_msgColEMail2},
  369.     {(char*)_msgColAuth1, (char*)_msgColAuth2},
  370.     {(char*)_msgColIP1, (char*)_msgColIP2},
  371.     {(char*)_msgColPort1, (char*)_msgColPort2},
  372.     {NULL,NULL}
  373. };*/
  374.  
  375.   char *Columns[][2] = {
  376.   {"Message Lamp", "COL=0"},
  377.   {"UIN", "COL=1"},
  378.   {"Statut", "COL=2"},
  379.   {"Surnom", "COL=3"},
  380.   {"Nom", "COL=4"},
  381.   {"Adresse Electronique", "COL=5"},
  382.   {"Autorisation", "COL=6"},
  383.   {"IP", "COL=8"},
  384.   {"Port", "COL=9"},
  385.   {NULL, NULL}
  386. };
  387.  
  388. UBYTE ChatColors[16][3] = {
  389.   {0x00, 0x00, 0x00}, // Black
  390.   {0x80, 0x00, 0x00}, // Maroon
  391.   {0x00, 0x80, 0x00}, // Green
  392.   {0x80, 0x80, 0x00}, // Olive
  393.   {0x00, 0x00, 0x80}, // Navy
  394.   {0x80, 0x00, 0x80}, // Purple
  395.   {0x00, 0x80, 0x80}, // Teal
  396.   {0x80, 0x80, 0x80}, // Gray
  397.   {0xc0, 0xc0, 0xc0}, // Silver
  398.   {0xff, 0x00, 0x00}, // Red
  399.   {0x00, 0xff, 0x00}, // Lime
  400.   {0xff, 0xff, 0x00}, // Yellow
  401.   {0x00, 0x00, 0xff}, // Blue
  402.   {0xff, 0x00, 0xff}, // Fuchsia
  403.   {0x00, 0xff, 0xff}, // Aqua
  404.   {0xff, 0xff, 0xff}, // White
  405. };
  406.  
  407. extern char *ChatColorNames[] = {
  408.     (char*)_msgChatColor1,
  409.     (char*)_msgChatColor2,
  410.     (char*)_msgChatColor3,
  411.     (char*)_msgChatColor4,
  412.     (char*)_msgChatColor5,
  413.     (char*)_msgChatColor6,
  414.     (char*)_msgChatColor7,
  415.     (char*)_msgChatColor8,
  416.     (char*)_msgChatColor9,
  417.     (char*)_msgChatColor10,
  418.     (char*)_msgChatColor11,
  419.     (char*)_msgChatColor12,
  420.     (char*)_msgChatColor13,
  421.     (char*)_msgChatColor14,
  422.     (char*)_msgChatColor15,
  423.     (char*)_msgChatColor16,
  424. NULL
  425. };
  426.  
  427. // char *ChatColorNames[] = {"Black", "Maroon", "Green", "Olive", "Navy", "Purple", "Teal", "Gray",
  428. //                          "Silver", "Red", "Lime", "Yellow", "Blue", "Fuchsia", "Aqua", "White", NULL};
  429.  
  430. char contact_fl[MAXNAMLEN], config_fl[MAXNAMLEN], colors_fl[MAXNAMLEN], currentdir[MAXNAMLEN], sbuf[UDPBUFLEN], rbuf[UDPBUFLEN];
  431. char server_fl[MAXNAMLEN], logdir_fl[MAXNAMLEN], lastuser_fl[MAXNAMLEN], uin_fl[MAXNAMLEN], userstat_fl[MAXNAMLEN];
  432. char userdir_fl[MAXNAMLEN], tbuf[TCPBUFLEN], maintitle[50], tmpmsg_fl[MAXNAMLEN], UDP_Buf[UDPBUFLEN], err_buf[128];
  433.  
  434. extern char splash[];
  435.  
  436. enum {CHAT_NO=1, CHAT_REQUESTING, CHAT_MODE};
  437.  
  438. enum {INFO_VIEW=1, INFO_REFRESH, INFO_GRABME, INFO_BASIC, INFO_EXTENDED, INFO_META_HOME, INFO_META_WORK, INFO_META_MORE,
  439.       INFO_META_ABOUT, INFO_META_INTERESTS, INFO_META_AFFILIATIONS, INFO_META_URLCATEGORY};
  440.  
  441. int found, online_cnt, offmsg_cnt, contacts_cnt;
  442. int maxfd = -1;
  443.  
  444. fd_set rset, wset;
  445.  
  446. LONG PORT_signal, PORT_mask, __stack = 32768, WhichLamp, cmap[NUM_CHAT_COLORS];
  447.  
  448. time_t LastSend = 0;
  449.  
  450. UWORD info_seq = 1, extinfo_seq = 1, metainfo_seq = 1, srch_seq = 1, pw_seq = 1, login_seq = 2, chguinfo_seq = 1;
  451.  
  452. ULONG TCP_Seq = 0xfffffffe, UserInfoReqID[3];
  453.  
  454. ULONG AsyncBuf = 0x0900, httpbuf = 2048, mask, events, URLMsg_cnt = 0, SrvrMsg_cnt = 0, FileListen = 0;
  455.  
  456. ULONG Codes[] = {STATUS_ONLINE, STATUS_ONLINE|STATUSF_INVISIBLE, STATUS_NA, STATUS_ONLINE|STATUSF_CHAT, STATUS_ONLINE|STATUSF_HIGH, STATUS_AWAY, STATUS_DND, STATUS_OFFLINE};
  457.  
  458. UWORD TCPCodes[] = {TCP_STATUS_ONLINE, TCP_STATUS_ONLINE, TCP_STATUS_NA, TCP_STATUS_ONLINE, TCP_STATUS_OCCUPIED, TCP_STATUS_AWAY, TCP_STATUS_DND};
  459.  
  460. struct hostent *nameinfo;
  461.  
  462. struct UDP_Header Header;
  463.  
  464. int main(int argc, char *argv[])
  465.  
  466. {
  467.  
  468. struct AsyncFile *loadfh;
  469. struct Column   Col;
  470. struct Process *pr;
  471. struct Sockets *socks;
  472. struct Window  *mywin = NULL;
  473.  
  474. APTR oldwinptr;
  475.  
  476. BOOL *auto_ch = NULL;
  477.  
  478. BPTR olddir;
  479.  
  480. char line[1024], *cmd;
  481.  
  482. int i;
  483.  
  484. LONG index = 0;
  485.  
  486. ULONG sigs = 0, uin = 0, total = 0, total2 = 0, red, grn, blu;
  487.  
  488. Header.Version = 0x0002;
  489. Header.Sequence2 = 0;
  490.  
  491. online_cnt = offmsg_cnt = contacts_cnt = 0;
  492.  
  493. ARexx = GrabMyStats = TryAgain = Online = SocketOpen = NewUser = Reconnecting = OldPrefsFmt = FALSE;
  494.  
  495. PORT_signal = PORT_mask = 0;
  496.  
  497. OpenURL = FirstLogin = TRUE;
  498.  
  499. localise_array(UPages);
  500. localise_array(InfoPages);
  501. localise_array(UPagesUI);
  502. localise_array(ChatColorNames);
  503.  
  504. if (!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN))) fail(NULL,"Failed to open "MUIMASTER_NAME".");
  505. if (!(AsyncIOBase   = OpenLibrary("asyncio.library",39)))  fail(NULL,"Could not open asyncio.library v39.");
  506. if (!(SocketBase    = OpenLibrary("bsdsocket.library",3))) fail(NULL,"Could not open bsdsocket.library v3.");
  507. if (!(OpenURLBase   = OpenLibrary("openurl.library",0))) OpenURL = FALSE;
  508.  
  509. if ((olddir = GetProgramDir())) if (!NameFromLock(olddir,currentdir,MAXNAMLEN)) strcpy(currentdir,"PROGDIR:");
  510.  
  511. if (LASTCHAR(currentdir) != ':') strcat(currentdir,"/");
  512.  
  513. if (!(app = (struct ObjApp *)CreateApp(currentdir))) fail(NULL,"Failed to create application.");
  514.  
  515. if (strlen(splash)) set(app->WI_Splash,MUIA_Window_Open,TRUE);
  516.  
  517. // set(app->WI_Progress,MUIA_Window_Open,TRUE);
  518.  
  519. DoMethod(app->TX_Port  ,PORT_AddApp,app->App);
  520. DoMethod(app->TX_Timer ,TIME_AddApp,app->App);
  521. DoMethod(app->TX_Timer1,TIME_AddApp,app->App);
  522. DoMethod(app->CC_Parse ,TIME_AddApp,app->App);
  523.  
  524. for(i = 0; i < NUM_STATUS_COLORS; i++) DoMethod(app->PP_StatusColors[i],MUIM_Pendisplay_SetMUIPen,MPEN_SHINE);
  525.  
  526. for(i = 0; i < NUM_CHAT_COLORS; i++) {
  527.   red = ChatColors[i][0]<<24;
  528.   grn = ChatColors[i][1]<<24;
  529.   blu = ChatColors[i][2]<<24;
  530.   DoMethod(app->PP_ChatColors[i],MUIM_Pendisplay_SetRGB,red,grn,blu);
  531. }
  532.  
  533. sprintf(uin_fl,"%sUsers/",currentdir);
  534.  
  535. set(app->DL_UINList,MUIA_Dirlist_Directory,uin_fl);
  536.  
  537. if (argc < 2) {
  538.   sprintf(lastuser_fl,"%sLastUser",currentdir);
  539.   if (loadfh = OpenAsync(lastuser_fl,MODE_READ,AsyncBuf)) {
  540.     ReadAsync(loadfh,line,sizeof(line));
  541.     sscanf(line,"%ld",&uin);
  542.     CloseAsync(loadfh);
  543.   }
  544. }
  545. else StrToLong(argv[1],(LONG *)&uin);
  546.  
  547. set(app->STR_ICQUIN,MUIA_String_Integer,uin);
  548.  
  549. Header.UIN = uin;
  550.  
  551. LoadPrefs(NULL);
  552.  
  553. //ChangeZodiacPic(NULL,TRUE);
  554.  
  555. get(app->LV_ColsStore,MUIA_NList_Entries,&total);
  556. get(app->LV_ColsUse,MUIA_NList_Entries,&total2);
  557.  
  558. if (total == 0 && total2 == 0) {
  559.   for(i = 0; Columns[i][0]; i++) {
  560.     Col.Name = Columns[i][0];
  561.     Col.COL = Columns[i][1];
  562.     DoMethod(app->LV_ColsUse,MUIM_NList_InsertSingle,&Col,MUIV_NList_Insert_Bottom);
  563.   }
  564. }
  565.  
  566. ReDrawCList();
  567.  
  568. set(app->TX_About,MUIA_Text_Contents,version_string+6);
  569.  
  570. get(app->CH_MsgTime,MUIA_Selected,&auto_ch);
  571. if (!auto_ch) set(app->LV_Msgs,MUIA_NList_Format,"COL=0 BAR,COL=2");
  572.  
  573. get(app->CH_OpenMsg,MUIA_Selected,&auto_ch);
  574. if (auto_ch) set(app->WI_Message,MUIA_Window_Open,TRUE);
  575.  
  576. set(app->TX_Color,MUIA_Text_Contents,"Offline");
  577.  
  578. set(app->TX_LoadProgress,MUIA_Text_Contents,"Open Main Window");
  579.  
  580. set(app->WI_Main,MUIA_Window_Open,TRUE);
  581.  
  582. get(app->WI_Main,MUIA_Window_Window,&mywin);
  583. if (mywin) {
  584.   pr = (struct Process *)FindTask(NULL);
  585.   oldwinptr = pr->pr_WindowPtr;
  586.   pr->pr_WindowPtr = mywin;
  587.   SetTaskPri((struct Task *)pr,1);
  588. }
  589.  
  590. get(app->CY_MyStatus,MUIA_Cycle_Active,&index);
  591. if (Codes[index] != STATUS_OFFLINE) ConnectICQ(NULL);
  592.  
  593. get(app->CH_OpenLog,MUIA_Selected,&auto_ch);
  594. if (auto_ch) set(app->WI_Log,MUIA_Window_Open,TRUE);
  595.  
  596. for(i = 0; i < NUM_AFFILIATIONS; i++) {
  597.   get(app->OB_Affiliations[i][0],MUIA_Selected,&auto_ch);
  598.   if (!BOOLP(auto_ch)) DoMethod(app->WI_ICQPrefs,MUIM_MultiSet,MUIA_Disabled,TRUE,app->OB_Affiliations[i][1],app->OB_Affiliations[i][2],NULL);
  599. }
  600.  
  601. for(i = 0; i < NUM_PASTS; i++) {
  602.   get(app->OB_Pasts[i][0],MUIA_Selected,&auto_ch);
  603.   if (!BOOLP(auto_ch)) DoMethod(app->WI_ICQPrefs,MUIM_MultiSet,MUIA_Disabled,TRUE,app->OB_Pasts[i][1],app->OB_Pasts[i][2],NULL);
  604. }
  605.  
  606. for(i = 0; i < NUM_INTERESTS; i++) {
  607.   get(app->OB_Interests[i][0],MUIA_Selected,&auto_ch);
  608.   if (!BOOLP(auto_ch)) DoMethod(app->WI_ICQPrefs,MUIM_MultiSet,MUIA_Disabled,TRUE,app->OB_Interests[i][1],app->OB_Interests[i][2],NULL);
  609. }
  610.  
  611. get(app->CH_PicPrivacy,MUIA_Selected,&auto_ch);
  612. set(app->RD_PicPrivacies,MUIA_Disabled,BOOLP(auto_ch));
  613.  
  614. // set(app->WI_Progress,MUIA_Window_Open,FALSE);
  615. set(app->WI_Splash,MUIA_Window_Open,FALSE);
  616.  
  617. get(app->STR_OnStartup,MUIA_String_Contents,&cmd);
  618. if (strlen(cmd) > 0) System(cmd,NULL);
  619.  
  620. while(DoMethod(app->App,MUIM_Application_NewInput,&sigs) != MUIV_Application_ReturnID_Quit) {
  621.   if (sigs) {
  622.     sigs = Wait(sigs|SIGBREAKF_CTRL_C);
  623.     if (sigs & SIGBREAKF_CTRL_C) break;
  624.   }
  625. }
  626.  
  627. get(app->STR_OnShutdown,MUIA_String_Contents,&cmd);
  628. if (strlen(cmd) > 0) System(cmd,NULL);
  629.  
  630. DoMethod(app->LV_OfflineList,MUIM_NList_UseImage,NULL,-1,0);
  631.  
  632. get(app->LV_SockList,MUIA_NList_Entries,&total);
  633.  
  634. for(i = (total-1); i>-1; i--) {
  635.   DoMethod(app->LV_SockList,MUIM_NList_GetEntry,i,&socks);
  636.   CloseSocket(socks->Socket);
  637. }
  638.  
  639. DoMethod(app->TX_Port  ,PORT_RemApp,app->App);
  640. DoMethod(app->TX_Timer ,TIME_RemApp,app->App);
  641. DoMethod(app->TX_Timer1,TIME_RemApp,app->App);
  642. DoMethod(app->CC_Parse ,TIME_RemApp,app->App);
  643.  
  644. SavePrefs(NULL);
  645.  
  646. if (mywin) pr->pr_WindowPtr = oldwinptr;
  647.  
  648. set(app->WI_Main,MUIA_Window_Open,FALSE);
  649.  
  650. fail(NULL,NULL);
  651.  
  652. }
  653.  
  654.  
  655. void fail(struct ObjApp *garbage, char *str)
  656.  
  657. {
  658.  
  659. if (app) {
  660.   if (app->DO_IconifyIcon) FreeDiskObject(app->DO_IconifyIcon);
  661.   if (app->NM_MsgMenu) MUI_DisposeObject(app->NM_MsgMenu);
  662.   if (app->TX_Port) MUI_DisposeObject(app->TX_Port);
  663.   if (app->TX_Timer) MUI_DisposeObject(app->TX_Timer);
  664.   if (app->TX_Timer1) MUI_DisposeObject(app->TX_Timer1);
  665.   if (app->CC_Parse) MUI_DisposeObject(app->CC_Parse);
  666.   if (app->App) MUI_DisposeObject(app->App);
  667.   if (mcc_Port) MUI_DeleteCustomClass(mcc_Port);
  668.   if (mcc_Time) MUI_DeleteCustomClass(mcc_Time);
  669.   if (mcc_Color) MUI_DeleteCustomClass(mcc_Color);
  670.   if (mcc_Chat) MUI_DeleteCustomClass(mcc_Chat);
  671.   FreeVec(app);
  672. }
  673.  
  674. if (OpenURLBase)   CloseLibrary(OpenURLBase);
  675. if (SocketBase)    CloseLibrary(SocketBase);
  676. if (AsyncIOBase)   CloseLibrary(AsyncIOBase);
  677. if (MUIMasterBase) CloseLibrary(MUIMasterBase);
  678.  
  679. if (str) {
  680.   puts(str);
  681.   exit(20);
  682. }
  683.  
  684. exit(0);
  685.  
  686. }
  687.  
  688.  
  689. APTR __asm AddOffline(REG(a2) APTR pool, REG(a1) struct Contact *user)
  690.  
  691. {
  692.  
  693. struct Contact *newuser = NULL;
  694.  
  695. if (!(newuser = AllocVec(sizeof(struct Contact),MEMF_CLEAR))) return(NULL);
  696.  
  697. newuser->UIN = user->UIN;
  698.  
  699. RefreshUInfo(&newuser->Nick,user->Nick);
  700. RefreshUInfo(&newuser->First,user->First);
  701. RefreshUInfo(&newuser->Last,user->Last);
  702. RefreshUInfo(&newuser->EMail,user->EMail);
  703. RefreshUInfo(&newuser->EMail_Secondary,user->EMail_Secondary);
  704. RefreshUInfo(&newuser->EMail_Old,user->EMail_Old);
  705. RefreshUInfo(&newuser->Street,user->Street);
  706. RefreshUInfo(&newuser->City,user->City);
  707. RefreshUInfo(&newuser->State,user->State);
  708. RefreshUInfo(&newuser->ZipCode,user->ZipCode);
  709. RefreshUInfo(&newuser->Phone,user->Phone);
  710. RefreshUInfo(&newuser->FAX,user->FAX);
  711. RefreshUInfo(&newuser->Cellular,user->Cellular);
  712. RefreshUInfo(&newuser->HomePage,user->HomePage);
  713. RefreshUInfo(&newuser->About,user->About);
  714. RefreshUInfo(&newuser->Comment,user->Comment);
  715.  
  716. strcpy(newuser->LampTxt,user->LampTxt);
  717.  
  718. newuser->LampObj = user->LampObj;
  719. newuser->LampNum = user->LampNum;
  720. newuser->Occupation = user->Occupation;
  721. newuser->Country = user->Country;
  722. newuser->TimeZone = user->TimeZone;
  723. newuser->Age = user->Age;
  724. newuser->Sex = user->Sex;
  725. newuser->BDay_Year = user->BDay_Year;
  726. newuser->BDay_Month = user->BDay_Month;
  727. newuser->BDay_Day = user->BDay_Day;
  728. newuser->Language1 = user->Language1;
  729. newuser->Language2 = user->Language2;
  730. newuser->Language3 = user->Language3;
  731. newuser->Authorize = user->Authorize;
  732. newuser->IP = user->IP;
  733. newuser->Port = user->Port;
  734. newuser->RealIP = user->RealIP;
  735. newuser->Type = user->Type;
  736. newuser->CanTCP = user->CanTCP;
  737. newuser->Status = user->Status;
  738. newuser->SeeInvis = user->SeeInvis;
  739. newuser->BeInvis = user->BeInvis;
  740. newuser->EditEMail = user->EditEMail;
  741. newuser->NewMsg = user->NewMsg;
  742. newuser->UWin = user->UWin;
  743. newuser->CFWin = user->CFWin;
  744. newuser->FWin = user->FWin;
  745. newuser->Changed = user->Changed;
  746. newuser->ConnectMe = user->ConnectMe;
  747. newuser->ChatListen = user->ChatListen;
  748. newuser->LastOnline = user->LastOnline;
  749. newuser->LastMessageFm = user->LastMessageFm;
  750. newuser->LastMessageTo = user->LastMessageTo;
  751.  
  752. return(newuser);
  753.  
  754. }
  755.  
  756.  
  757. void __asm RemOffline(REG(a2) APTR pool, REG(a1) struct Contact *newuser)
  758.  
  759. {
  760.  
  761. FreeUser(newuser);
  762.  
  763. if (newuser->LampObj) {
  764.   DoMethod(app->LV_OfflineList,MUIM_NList_UseImage,NULL,newuser->LampNum,0L);
  765.   MUI_DisposeObject(newuser->LampObj);
  766. }
  767.  
  768. if (newuser->UWin) {
  769.   if (!newuser->UWin->DoNotDelete) {
  770.     if (newuser->UWin->WI_UserWindow) {
  771.       set(newuser->UWin->WI_UserWindow,MUIA_Window_Open,FALSE);
  772.       DoMethod(app->App,OM_REMMEMBER,newuser->UWin->WI_UserWindow);
  773.       MUI_DisposeObject(newuser->UWin->WI_UserWindow);
  774.     }
  775.     FreeVec(newuser->UWin);
  776.   }
  777.   else newuser->UWin->DoNotDelete = FALSE;
  778. }
  779.  
  780. if (newuser->CFWin) {
  781.   if (newuser->CFWin->WI_ChatFileInWin) {
  782.     set(newuser->CFWin->WI_ChatFileInWin,MUIA_Window_Open,FALSE);
  783.     DoMethod(app->App,OM_REMMEMBER,newuser->CFWin->WI_ChatFileInWin);
  784.     MUI_DisposeObject(newuser->CFWin->WI_ChatFileInWin);
  785.   }
  786.   FreeVec(newuser->CFWin);
  787. }
  788.  
  789. if (newuser->FWin) {
  790.   if (!newuser->FWin->DoNotDelete) {
  791.     if (newuser->FWin->WI_FileWin) {
  792.       set(newuser->FWin->WI_FileWin,MUIA_Window_Open,FALSE);
  793.       DoMethod(app->App,OM_REMMEMBER,newuser->FWin->WI_FileWin);
  794.       MUI_DisposeObject(newuser->FWin->WI_FileWin);
  795.     }
  796.     if (newuser->FWin->File) CloseAsync(newuser->FWin->File);
  797.     FreeVec(newuser->FWin);
  798.   }
  799.   else newuser->FWin->DoNotDelete = FALSE;
  800. }
  801.  
  802. FreeVec(newuser);
  803.  
  804. return;
  805.  
  806. }
  807.  
  808.  
  809. LONG __asm CmpOffline(REG(a1) struct Contact *u1, REG(a2) struct Contact *u2)
  810.  
  811. {
  812.  
  813. ULONG s1, s2;
  814.  
  815. s1 = u1->Status & 0x000000ff;
  816. s2 = u2->Status & 0x000000ff;
  817.  
  818. if (s1 < s2) return(-1);
  819. if (s1 > s2) return(1);
  820.  
  821. if (u1->NewMsg < u2->NewMsg) return(1);
  822. if (u1->NewMsg > u2->NewMsg) return(-1);
  823.  
  824. return(stricmp(u1->Nick,u2->Nick));
  825.  
  826. }
  827.  
  828.  
  829. void __asm DisplayOffline(REG(a2) char **array, REG(a1) struct Contact *user)
  830.  
  831. {
  832.  
  833. static char uin[50], nick[100], name[100], email[100], auth[20], status[30], ip[30], port[20], cinvis[10];
  834.  
  835. ULONG pen = 2;
  836.  
  837. struct ColorText *ct;
  838.  
  839. name[0] = '\0';
  840.  
  841. if (user) {
  842.   ct = GetStatus(user->Status);
  843.   pen = MUIPEN(ct->Pen);
  844.   sprintf(status,"\033P[%ld]%s",pen,ct->Status);
  845.   sprintf(uin,"\033P[%ld]%ld",pen,user->UIN);
  846.   if (user->Nick) sprintf(nick,"\033P[%ld]%s",pen,user->Nick);
  847.   else strcpy(nick," ");
  848.   if (user->First && user->Last) sprintf(name,"\033P[%ld]%s %s",pen,user->First,user->Last);
  849.   else {
  850.     if (user->First) sprintf(name,"\033P[%ld]%s",pen,user->First);
  851.     if (user->Last) sprintf(name,"\033P[%ld]%s",pen,user->Last);
  852.   }
  853.   if (user->EMail) sprintf(email,"\033P[%ld]%s",pen,user->EMail);
  854.   else strcpy(email," ");
  855.   if (user->Authorize) sprintf(auth,"\033P[%ld]No",pen);
  856.   else sprintf(auth,"\033P[%ld]Yes",pen);
  857.  if (user->Status & STATUSF_HIDEIP) sprintf(ip,"\033P[%ld]Hidden",pen);
  858.   sprintf(ip,"\033P[%ld]%s",pen,Inet_NtoA(user->IP));
  859.   if (user->Status & STATUSF_HIDEIP) sprintf(port,"\033P[%ld]Hidden",pen);
  860.   sprintf(port,"\033P[%ld]%ld",pen,user->Port);
  861.   if (user->SeeInvis) sprintf(cinvis,"\033P[%ld]Yes",pen);
  862.   else sprintf(cinvis,"\033P[%ld]No",pen);
  863.   *array++ = user->LampTxt;
  864.   *array++ = uin;
  865.   *array++ = status;
  866.   *array++ = nick;
  867.   *array++ = name;
  868.   *array++ = email;
  869.   *array++ = auth;
  870.   *array++ = cinvis;
  871.   *array++ = ip;
  872.   *array   = port;
  873. }
  874. else {
  875.   *array++ = " ";
  876.   *array++ = "User ID";
  877.   *array++ = "Status";
  878.   *array++ = "Nick";
  879.   *array++ = "Name";
  880.   *array++ = "EMail";
  881.   *array++ = "Auth.";
  882.   *array++ = "See Invis";
  883.   *array++ = "IP";
  884.   *array   = "Port";
  885. }
  886.  
  887. return;
  888.  
  889. }
  890.  
  891.  
  892. void FreeUser(struct Contact *newuser)
  893.  
  894. {
  895.  
  896. if (newuser->Nick) FreeVec(newuser->Nick);
  897. if (newuser->First) FreeVec(newuser->First);
  898. if (newuser->Last) FreeVec(newuser->Last);
  899. if (newuser->EMail) FreeVec(newuser->EMail);
  900. if (newuser->EMail_Secondary) FreeVec(newuser->EMail_Secondary);
  901. if (newuser->EMail_Old) FreeVec(newuser->EMail_Old);
  902. if (newuser->Street) FreeVec(newuser->Street);
  903. if (newuser->City) FreeVec(newuser->City);
  904. if (newuser->State) FreeVec(newuser->State);
  905. if (newuser->ZipCode) FreeVec(newuser->ZipCode);
  906. if (newuser->Phone) FreeVec(newuser->Phone);
  907. if (newuser->FAX) FreeVec(newuser->FAX);
  908. if (newuser->Cellular) FreeVec(newuser->Cellular);
  909. if (newuser->HomePage) FreeVec(newuser->HomePage);
  910. if (newuser->About) FreeVec(newuser->About);
  911. if (newuser->Comment) FreeVec(newuser->Comment);
  912. if (newuser->Work_City) FreeVec(newuser->Work_City);
  913. if (newuser->Work_State) FreeVec(newuser->Work_State);
  914. if (newuser->Work_Phone) FreeVec(newuser->Work_Phone);
  915. if (newuser->Work_FAX) FreeVec(newuser->Work_FAX);
  916. if (newuser->Work_Address) FreeVec(newuser->Work_Address);
  917. if (newuser->Work_ZipCode) FreeVec(newuser->Work_ZipCode);
  918. if (newuser->Work_Company) FreeVec(newuser->Work_Company);
  919. if (newuser->Work_Department) FreeVec(newuser->Work_Department);
  920. if (newuser->Work_Position) FreeVec(newuser->Work_Position);
  921. if (newuser->Work_URL) FreeVec(newuser->Work_URL);
  922.  
  923. return;
  924.  
  925. }
  926.  
  927.  
  928. ULONG __asm MyDispatcher(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg)
  929.  
  930. {
  931.  
  932. switch(msg->MethodID) {
  933.   case OM_NEW:
  934.     return(PORT_NewUDP(cl,obj,(APTR)msg));
  935.   case OM_DISPOSE:
  936.     return(PORT_Dispose(cl,obj,(APTR)msg));
  937.   case PORT_AddApp:
  938.     return(PORT_Setup(cl,obj,(APTR)msg));
  939.   case PORT_RemApp:
  940.     return(PORT_Cleanup(cl,obj,(APTR)msg));
  941.   case PORT_Trigger:
  942.     return(PORT_Trigger_cl(cl,obj,(APTR)msg));
  943. }
  944.  
  945. return(DoSuperMethodA(cl,obj,msg));
  946.  
  947. }
  948.  
  949.  
  950. ULONG PORT_NewUDP(struct IClass *cl, Object *obj, Msg msg)
  951.  
  952. {
  953.  
  954. struct SigData *data;
  955.  
  956. #ifdef DEBUG
  957. HandleError(DBG_OTH_INFO,"In PORT_NewUDP");
  958. #endif
  959.  
  960. if (!(obj = (Object *)DoSuperMethodA(cl,obj,msg))) return(FALSE);
  961.  
  962. data = INST_DATA(cl,obj);
  963.  
  964. if ((PORT_signal = AllocSignal(-1)) == -1) {
  965.   HandleError(DBG_OTH_INFO,"No signal bit allocated.");
  966.   CoerceMethod(cl,obj,OM_DISPOSE);
  967.   return(FALSE);
  968. }
  969.  
  970. PORT_mask = 1L<<PORT_signal;
  971.  
  972. if (PORT_mask) {
  973.   data->ihnode.ihn_Object  = obj;
  974.   data->ihnode.ihn_Signals = PORT_mask;
  975.   data->ihnode.ihn_Method  = PORT_Trigger;
  976.   data->ihnode.ihn_Flags   = 0;
  977.   return((ULONG)obj);
  978. }
  979.  
  980.  
  981. CoerceMethod(cl,obj,OM_DISPOSE);
  982.  
  983. return(FALSE);
  984.  
  985. }
  986.  
  987.  
  988. ULONG PORT_Dispose(struct IClass *cl, Object *obj, Msg msg)
  989.  
  990. {
  991.  
  992. #ifdef DEBUG
  993. HandleError(DBG_OTH_INFO,"In PORT_Dispose");
  994. #endif
  995.  
  996. if (PORT_signal > -1) FreeSignal(PORT_signal);
  997.  
  998. return(DoSuperMethodA(cl,obj,msg));
  999.  
  1000. }
  1001.  
  1002.  
  1003. ULONG PORT_Setup(struct IClass *cl, Object *obj, Msg msg)
  1004.  
  1005. {
  1006.  
  1007. struct SigData *data = INST_DATA(cl,obj);
  1008.  
  1009. #ifdef DEBUG
  1010. HandleError(DBG_OTH_INFO,"In PORT_Setup");
  1011. #endif
  1012.  
  1013. data->App = ((struct MUIP_PT_AddApp *)msg)->App;
  1014.  
  1015. DoMethod(data->App,MUIM_Application_AddInputHandler,&data->ihnode);
  1016.  
  1017. return(TRUE);
  1018.  
  1019. }
  1020.  
  1021.  
  1022. ULONG PORT_Cleanup(struct IClass *cl, Object *obj, Msg msg)
  1023.  
  1024. {
  1025.  
  1026. struct SigData *data = INST_DATA(cl,obj);
  1027.  
  1028. #ifdef DEBUG
  1029. HandleError(DBG_OTH_INFO,"In PORT_Cleanup");
  1030. #endif
  1031.  
  1032. DoMethod(data->App,MUIM_Application_RemInputHandler,&data->ihnode);
  1033.  
  1034. return(DoSuperMethodA(cl,obj,msg));
  1035.  
  1036. }
  1037.  
  1038.  
  1039. ULONG PORT_Trigger_cl(struct IClass *cl, Object *obj, Msg msg)
  1040.  
  1041. {
  1042.  
  1043. BOOL flag = FALSE, flg2 = FALSE;
  1044.  
  1045. fd_set rs, ws;
  1046.  
  1047. int data_len, len = 0, acklen = 0, i;
  1048.  
  1049. LONG s, total, user_len, n, size;
  1050.  
  1051. UWORD ver, cmd, seq;
  1052.  
  1053. ULONG err;
  1054.  
  1055. struct Contact *user;
  1056. struct ICQLog *Logged = NULL;
  1057. struct Sockets Socks, *socks;
  1058. struct timeval tv;
  1059. struct UDP_Header ACKHeader;
  1060.  
  1061. //struct SigData *data = INST_DATA(cl,obj);
  1062.  
  1063. if (maxfd < 0 || !SocketBase) return(flag);
  1064.  
  1065. ver = cmd = seq = 0;
  1066.  
  1067. /*
  1068. printf("rset: ");
  1069.  
  1070. for(i = 0; i<(maxfd+1); i++) if (FD_ISSET(i,&rset)) printf("%d ",i);
  1071.  
  1072. printf("\nwset: ");
  1073.  
  1074. for(i = 0; i<(maxfd+1); i++) if (FD_ISSET(i,&wset)) printf("%d ",i);
  1075.  
  1076. printf("\n");
  1077. */
  1078.  
  1079. rs = rset;
  1080. ws = wset;
  1081.  
  1082. tv.tv_sec = 0;
  1083. tv.tv_usec = 0;
  1084.  
  1085. //printf("maxfd = %d\n",maxfd);
  1086.  
  1087. if ((n = WaitSelect(maxfd+1,&rs,&ws,NULL,&tv,NULL)) == 0) return(flag);
  1088.  
  1089. #ifdef DEBUG
  1090. HandleError(DBG_OTH_INFO,"In PORT_Trigger");
  1091. #endif
  1092.  
  1093. for(s = 0; s<(maxfd+1); s++) {
  1094.   if (!FD_ISSET(s,&rs) && !FD_ISSET(s,&ws)) continue;
  1095.   socks = GetSocketFmSocket(s);
  1096.   if (socks) {
  1097.     if ((socks->Type == SOCK_UDP) && FD_ISSET(s,&rs)) {
  1098.       n = sizeof(err);
  1099.       if (getsockopt(s,SOL_SOCKET,SO_ERROR,&err,&n) < 0 || err != 0) {
  1100.         switch(err) {
  1101.           case ECONNRESET:
  1102.           case ECONNREFUSED:
  1103.           case EHOSTUNREACH:
  1104.           case ETIMEDOUT:
  1105.             break;
  1106.           default:
  1107.             SocketBaseTags(SBTM_GETREF(SBTC_ERRNOSTRPTR),&err,TAG_DONE);
  1108.             HandleError(DBG_UDP_ERRS,"Error on UDP socket: %s",(char *)err);
  1109.         }
  1110.         DisconnectICQ(NULL);
  1111.         continue;
  1112.       }
  1113.       flag = TRUE;
  1114.       while((data_len = recv_udp_pkt(rbuf,sizeof(rbuf),socks)) > 0) {
  1115.         len = 0;
  1116.         UDP_ParseHeader(rbuf,&Header);
  1117.         sprintf(err_buf,"Incoming %s packet",ICQ_CmdToText(Header.Command));
  1118.         PrintHex(DBG_UDP_PKTS,err_buf,rbuf,data_len);
  1119.         if (Header.Version == 2 || Header.Version == 5) {
  1120. //        HandleError(DBG_UDP_DBUG," ver = %d",Header.Version);
  1121. //        HandleError(DBG_UDP_DBUG," cmd = 0x%04x",Header.Command);
  1122. //        HandleError(DBG_UDP_DBUG," seq = %d",Header.Sequence);
  1123. //        HandleError(DBG_UDP_DBUG," se2 = %d",Header.Sequence2);
  1124.           if (Header.Command != S_ACK) {
  1125.             memcpy(&ACKHeader,&Header,sizeof(struct UDP_Header));
  1126.             ACKHeader.Command = C_ACK;
  1127.             acklen = UDP_CreatePacket(&ACKHeader,NULL,UDP_Buf);
  1128.             send_udp_pkt(UDP_Buf,acklen,socks->UIN);
  1129.             if (Header.Command == S_NEW_USER_UIN) Header.Sequence = 0xffff;
  1130.             get(app->LV_ICQSrvLog,MUIA_NList_Entries,&total);
  1131.             for(i = total-1; i>-1; i--) {
  1132.               DoMethod(app->LV_ICQSrvLog,MUIM_NList_GetEntry,i,&Logged);
  1133.               if (Logged) {
  1134.                 switch(Header.Version) {
  1135.                   case 0x0002:
  1136.                     if (Logged->Seq == Header.Sequence) {
  1137.                       Logged->Resend++;
  1138.                       flg2 = TRUE;
  1139.                     }
  1140.                     break;
  1141.                   case 0x0005:
  1142. //                  HandleError(DBG_UDP_DBUG,"Data Logged->Seq = %04lx, Header.Sequence = %04x, Logged->Se2 = %04x, Header.Sequence2 = %04x",Logged->Seq,Header.Sequence,Logged->Se2,Header.Sequence2);
  1143.                     if (Logged->Seq == Header.Sequence && Logged->Se2 == Header.Sequence2) {
  1144.                       Logged->Resend++;
  1145.                       flg2 = TRUE;
  1146.                     }
  1147.                     break;
  1148.                 }
  1149.                 if (flg2) break;
  1150.               }
  1151.             }
  1152.             if (!flg2) {
  1153.               if (Header.Command == S_MULTI) {
  1154.                 struct S_Multi Multi;
  1155.                 struct UDP_Header MHdr;
  1156.                 UDP_ParseHeader(rbuf,&MHdr);
  1157.                 UDP_ParsePacket(&Multi,rbuf,data_len,&MHdr);
  1158.                 while(Multi.Size && Multi.Packet) {
  1159.                   UDP_ParseHeader(Multi.Packet,&MHdr);
  1160.                   sprintf(err_buf,"MultiPacket contains a %s packet (%d remain)",ICQ_CmdToText(MHdr.Command),Multi.Count-1);
  1161.                   PrintHex(DBG_UDP_PKTS,err_buf,Multi.Packet,Multi.Size);
  1162.                   if (MHdr.Command == S_ACK) HandleACK(Multi.Packet,Multi.Size);
  1163.                   else Add2Log(LOG_SERVER,&MHdr,TRUE,Multi.Size,Multi.Packet);
  1164.                   UDP_NextMulti(&Multi);
  1165.                 }
  1166.               }
  1167.               else Add2Log(LOG_SERVER,&Header,TRUE,data_len,rbuf);
  1168.             }
  1169.           }
  1170.           else HandleACK(rbuf,data_len);
  1171.         }
  1172.         else PrintHex(DBG_UDP_ERRS,"Bad UDP version, its not v2 or v5",rbuf,data_len);
  1173.       }
  1174.       continue;
  1175.     }
  1176.   }
  1177.   if (socks) {
  1178.     if (socks->Type == SOCK_UDP) continue;
  1179.     if ((socks->Dir == TCP_DIR_LISTEN) && FD_ISSET(s,&rs)) {
  1180.       HandleError(DBG_TCP_DBUG,"incoming connection request on socket %d",s);
  1181.       user_len = sizeof(Socks.Address);
  1182.       if ((Socks.Socket = accept(s,(struct sockaddr *)&Socks.Address,&user_len)) < 0) HandleError(DBG_OTH_INFO,"Error return from accept().");
  1183.       else {
  1184.         HandleError(DBG_TCP_DBUG,"New socket is %d",Socks.Socket);
  1185.         Socks.UIN = 0;
  1186.         Socks.Dir = TCP_DIR_IN;
  1187.         Socks.TCPLen = 0;
  1188.         Socks.LastTCP = NULL;
  1189.         Socks.ChatMode = Socks.FileMode = NULL;
  1190.         Socks.CWin = NULL;
  1191.         Socks.RCObj = NULL;
  1192.         Socks.Timehack = time(NULL);
  1193.         Socks.Connecting = Socks.HadInit = Socks.Hidden = Socks.Backward = Socks.Closing = FALSE;
  1194.         Socks.Type = socks->Type;
  1195.         Socks.PktLen[0] = Socks.PktLen[1] = '\0';
  1196.         Socks.ConnectPort = socks->Port;
  1197.         Socks.CWin = NULL;
  1198.         if (Socks.Socket > maxfd) maxfd = Socks.Socket;
  1199.         FD_SET(Socks.Socket,&rset);
  1200.         FD_SET(Socks.Socket,&wset);
  1201.         tv.tv_sec = 30;
  1202.         tv.tv_usec = 0;
  1203.         size = 1;
  1204.         memset(&Socks.Address,0,user_len);
  1205.         if (IoctlSocket(Socks.Socket,FIOASYNC,(char *)&size) == -1) {
  1206.           HandleError(DBG_TCP_ERRS,"Error in IoctlSocket FIOASYNC for incoming TCP socket.");
  1207.         }
  1208.         if (IoctlSocket(Socks.Socket,FIONBIO,(char *)&size) == -1) {
  1209.           HandleError(DBG_TCP_ERRS,"Error in IoctlSocket FIONBIO for incoming TCP socket.");
  1210.         }
  1211.         if (setsockopt(Socks.Socket,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv)) == -1) {
  1212.           HandleError(DBG_TCP_ERRS,"Could not setsockopt SO_SNDTIMEO for incoming TCP socket.");
  1213.         }
  1214.         size = FILE_PKT_SIZE*2;
  1215.         if (setsockopt(Socks.Socket,SOL_SOCKET,SO_SNDLOWAT,&size,sizeof(size)) == -1) {
  1216.           HandleError(DBG_TCP_ERRS,"Could not setsockopt SO_SNDLOWAT for incoming TCP socket.");
  1217.         }
  1218.         getpeername(Socks.Socket,(struct sockaddr *)&Socks.Address,&user_len);
  1219.         Socks.IP = Socks.Address.sin_addr.s_addr;
  1220.         Socks.Port = Socks.Address.sin_port;
  1221.         memset(&Socks.LocalAddr,0,user_len);
  1222.         getsockname(Socks.Socket,(struct sockaddr *)&Socks.LocalAddr,&user_len);
  1223.         DoMethod(app->LV_SockList,MUIM_NList_InsertSingle,&Socks,MUIV_NList_Insert_Sorted);
  1224.       }
  1225.       continue;
  1226.     }
  1227.   }
  1228.   if (socks) user = GetContact(socks->UIN);
  1229.   if (socks) {
  1230.     if (socks->Connecting && (FD_ISSET(s,&rs) || FD_ISSET(s,&ws))) {
  1231.       n = sizeof(err);
  1232.       if (getsockopt(s,SOL_SOCKET,SO_ERROR,&err,&n) < 0 || err != 0) {
  1233.         switch(err) {
  1234.           case ECONNRESET:
  1235.           case ECONNREFUSED:
  1236.           case EHOSTUNREACH:
  1237.           case ETIMEDOUT:
  1238.             break;
  1239.           default:
  1240.             SocketBaseTags(SBTM_GETREF(SBTC_ERRNOSTRPTR),&err,TAG_DONE);
  1241.             HandleError(DBG_TCP_ERRS,"non-blocking connect for %s failed: %s.",user->Nick,(char *)err);
  1242.         }
  1243.         if (socks->IP != user->RealIP && user->RealIP != 0) {
  1244.           HandleError(DBG_TCP_DBUG,"Attempting RealIP.");
  1245.           if (!OpenTCPSocket(user,socks->Type,user->RealIP,socks->Port)) {
  1246.             user->CanTCP = 6;
  1247.             user->IP = user->Port = 0;
  1248.             if (socks->Type == SOCK_CHAT && user->ChatListen) DelSockets(user->ChatListen);
  1249. //          if (socks->Type == SOCK_FILE && user->FileListen) DelSockets(user->FileListen);
  1250.             user->ChatListen = /* user->FileListen = */ 0;
  1251.             DelSockets(s);
  1252.             if (s == maxfd) maxfd--;
  1253.             continue;
  1254.           }
  1255.         }
  1256.         else {
  1257.           user->CanTCP = 6;
  1258.           user->IP = user->Port = 0;
  1259.           if (socks->Type == SOCK_CHAT && user->ChatListen) DelSockets(user->ChatListen);
  1260. //        if (socks->Type == SOCK_FILE && user->FileListen) DelSockets(user->FileListen);
  1261.           user->ChatListen = /* user->FileListen = */ 0;
  1262.           DelSockets(s);
  1263.           if (s == maxfd) maxfd--;
  1264.           SendTCPMsgViaUDP(user->UIN);
  1265.           continue;
  1266.         }
  1267.         DelSockets(s);
  1268.         if (s == maxfd) maxfd--;
  1269.         continue;
  1270.       }
  1271.       HandleError(DBG_TCP_DBUG,"completed connection on %s's socket %d",user->Nick,s);
  1272.       socks->Connecting = FALSE;
  1273.       user_len = sizeof(socks->Address);
  1274.       if (getpeername(s,(struct sockaddr *)&socks->Address,&user_len) == -1) {
  1275.         HandleError(DBG_TCP_ERRS,"Error in getpeername for non-blocking TCP connect.");
  1276.         continue;
  1277.       }
  1278.       socks->IP = socks->Address.sin_addr.s_addr;
  1279.       socks->Port = socks->Address.sin_port;
  1280.       if (user->Status & STATUSF_HIDEIP) socks->Hidden = TRUE;
  1281.       user_len = sizeof(socks->LocalAddr);
  1282.       memset(&socks->LocalAddr,0,user_len);
  1283.       getsockname(socks->Socket,(struct sockaddr *)&socks->LocalAddr,&user_len);
  1284.       user->Type = TCP_MSG_MSG;
  1285.       switch(socks->Type) {
  1286.         case SOCK_MESSAGE:
  1287.           SendTCPInit(s,user,0);
  1288.           SendDelayedTCP(socks);
  1289.           break;
  1290.         case SOCK_CHAT:
  1291.           SendTCPInit(s,user,user->ChatListen);
  1292.           if (!socks->Backward) SendChatInit(s);
  1293.           break;
  1294.         case SOCK_FILE:
  1295.           SendTCPInit(s,user,FileListen);
  1296.           if (!socks->Backward) SendFileInit(s,user);
  1297.           break;
  1298.       }
  1299.       continue;
  1300.     }
  1301.   }
  1302. /*if (FD_ISSET(s,&ws)) {
  1303.     if (socks) {
  1304.       if (socks->Type == SOCK_FILE && socks->FileMode) {
  1305. //      HandleError(DBG_TCP_DBUG,"%s's FileDirect socket %d is writeable.",user->Nick,s);
  1306.         n = sizeof(err);
  1307.         if (getsockopt(s,SOL_SOCKET,SO_ERROR,&err,&n) < 0 || err != 0) {
  1308.           switch(err) {
  1309.             case ECONNRESET:
  1310.             case ECONNREFUSED:
  1311.             case EHOSTUNREACH:
  1312.             case ETIMEDOUT:
  1313.               break;
  1314.             default:
  1315.               SocketBaseTags(SBTM_GETREF(SBTC_ERRNOSTRPTR),&err,TAG_DONE);
  1316.               HandleError(DBG_TCP_ERRS,"Error on writeable TCP socket:  %s",(char *)err);
  1317.           }
  1318.           user->CanTCP = 6;
  1319.           user->IP = user->Port = 0;
  1320.           if (socks->Type == SOCK_FILE) EndFile(user);
  1321.           DelSockets(s);
  1322.           if (s == maxfd) maxfd--;
  1323.           continue;
  1324.         }
  1325. //      SendAFile(s,user);
  1326.       }
  1327.     }
  1328.   }  */
  1329.   if (FD_ISSET(s,&rs)) {
  1330.     if (socks) {
  1331. //    HandleError(DBG_TCP_DBUG,"incoming data on socket %d",s);
  1332.       n = sizeof(err);
  1333.       if (getsockopt(s,SOL_SOCKET,SO_ERROR,&err,&n) < 0 || err != 0) {
  1334.         switch(err) {
  1335.           case ECONNRESET:
  1336.           case ECONNREFUSED:
  1337.           case EHOSTUNREACH:
  1338.           case ETIMEDOUT:
  1339.             break;
  1340.           default:
  1341.             SocketBaseTags(SBTM_GETREF(SBTC_ERRNOSTRPTR),&err,TAG_DONE);
  1342.             HandleError(DBG_TCP_ERRS,"Error on readable TCP socket:  %s",(char *)err);
  1343.         }
  1344.         if (user) {
  1345.           user->CanTCP = 6;
  1346.           user->IP = user->Port = 0;
  1347.           if (socks->Type == SOCK_CHAT) EndChat(socks->RCObj->GP_RemoteObj);
  1348.           if (socks->Type == SOCK_FILE) EndFile(user);
  1349.         }
  1350.         DelSockets(s);
  1351.         if (s == maxfd) maxfd--;
  1352.         continue;
  1353.       }
  1354.       while ((socks->ChatMode?(len = recv_chat(tbuf,s)):(len = recv_tcp_pkt(tbuf,socks))) > 0) {
  1355.         switch(socks->Type) {
  1356.           case SOCK_MESSAGE:
  1357.             ParseTCPCmd(tbuf,len,s);
  1358.             break;
  1359.           case SOCK_CHAT:
  1360.             if (socks->ChatMode) DoChatMode(tbuf,len,s);
  1361.             else ParseChatPkt(tbuf,len,s);
  1362.             break;
  1363.           case SOCK_FILE:
  1364.             ParseFilePkt(tbuf,len,s);
  1365.             break;
  1366.         }
  1367.       }
  1368.       if (len < 0) {
  1369.         switch(socks->Type) {
  1370.           case SOCK_CHAT:
  1371.             if (socks->RCObj) EndChat(socks->RCObj->GP_RemoteObj);
  1372.             break;
  1373.           case SOCK_FILE:
  1374.             if (user) EndFile(user);
  1375.             break;
  1376.           default:
  1377.             DelSockets(s);
  1378.         }
  1379.         if (s == maxfd) maxfd--;
  1380.       }
  1381.     }
  1382.   }
  1383. }
  1384.  
  1385. return(flag);
  1386.  
  1387. }
  1388.  
  1389.  
  1390. void HandleACK(char *rbuf, UWORD data_len)
  1391.  
  1392. {
  1393.  
  1394. int i;
  1395.  
  1396. ULONG total;
  1397.  
  1398. struct ICQLog *Logged;
  1399.  
  1400. if (NewUser) {
  1401.   Add2Log(LOG_SERVER,&Header,TRUE,data_len,rbuf);
  1402. }
  1403. get(app->LV_ICQCliLog,MUIA_NList_Entries,&total);
  1404. for(i = total-1; i>-1; i--) {
  1405.   DoMethod(app->LV_ICQCliLog,MUIM_NList_GetEntry,i,&Logged);
  1406.   if (Logged) {
  1407.     switch(Header.Version) {
  1408.       case 0x0002:
  1409.         if (Logged->Seq == Header.Sequence) Logged->Ack = TRUE;
  1410.         break;
  1411.       case 0x0005:
  1412. //      HandleError(DBG_UDP_DBUG,"ACK Logged->Seq = %04lx, Header.Sequence = %04x, Logged->Se2 = %04x, Header.Sequence2 = %04x",Logged->Seq,Header.Sequence,Logged->Se2,Header.Sequence2);
  1413.         if (Logged->Seq == Header.Sequence && Logged->Se2 == Header.Sequence2) Logged->Ack = TRUE;
  1414.         break;
  1415.     }
  1416.     if (Logged->Ack && Logged->Len) {
  1417.       Logged->Len = 0;
  1418.       FreeVec(Logged->Pkt);
  1419.       Logged->Pkt = NULL;
  1420.       DoMethod(app->LV_ICQCliLog,MUIM_NList_Redraw,i);
  1421.       break;
  1422.     }
  1423.   }
  1424. }
  1425.  
  1426. return;
  1427.  
  1428. }
  1429.  
  1430.  
  1431. void __asm ConnectICQ(REG(a2) APTR obj)
  1432.  
  1433. {
  1434.  
  1435. BOOL *opts;
  1436.  
  1437. char *pass;
  1438.  
  1439. int i, len;
  1440.  
  1441. ULONG port, addr, stat, uin, index, total, udp_ver;
  1442.  
  1443. struct C_LogOn LogOn;
  1444. struct Sockets *socks;
  1445.  
  1446. if (Online) return;
  1447.  
  1448. if (!(SocketOpen = OpenICQSocket())) {
  1449.   HandleError(DBG_OTH_FATL,"Could not connect to ICQ.");
  1450.   return;
  1451. }
  1452.  
  1453. get(app->STR_ICQUIN ,MUIA_String_Integer ,&uin);
  1454. get(app->STR_ICQPass,MUIA_String_Contents,&pass);
  1455. get(app->CY_MyStatus,MUIA_Cycle_Active   ,&index);
  1456. get(app->LV_SockList,MUIA_NList_Entries  ,&total);
  1457. get(app->CY_UDPVersion,MUIA_Cycle_Active ,&udp_ver);
  1458.  
  1459. for(i = 0; i<total; i++) {
  1460.   DoMethod(app->LV_SockList,MUIM_NList_GetEntry,i,&socks);
  1461.   if (socks) if (socks->Type == SOCK_MESSAGE && socks->Dir == TCP_DIR_LISTEN && socks->UIN == uin) break;
  1462. }
  1463.  
  1464. port = socks->Port;
  1465. addr = socks->IP;
  1466. stat = Codes[index];
  1467.  
  1468. get(app->CH_WebPresence,MUIA_Selected,&opts);
  1469.  
  1470. if (opts) stat |= STATUSF_WEBPRESENCE;
  1471.  
  1472. get(app->CH_HideIP,MUIA_Selected,&opts);
  1473.  
  1474. if (opts) stat |= STATUSF_HIDEIP;
  1475.  
  1476. //HandleError(DBG_TCP_DBUG,"Status is 0x%08x",stat);
  1477.  
  1478. switch(udp_ver) {
  1479.   case 0:
  1480.     Header.Version = 0x0002;
  1481.     Header.Sequence2 = 0x0000;
  1482.     set(app->BT_ChangePW,MUIA_Disabled,TRUE);
  1483.     break;
  1484.   case 1:
  1485.     Header.Version = 0x0005;
  1486.     set(app->BT_ChangePW,MUIA_Disabled,FALSE);
  1487.     break;
  1488. }
  1489.  
  1490. Header.Command = C_LOGIN;
  1491.  
  1492. LogOn.Time = time(NULL);
  1493. LogOn.TCP_MsgPort = port;
  1494. strcpy(LogOn.Password,pass);
  1495. LogOn.TCP_MsgIP = addr;
  1496. LogOn.TCP_Flag = 0x04;
  1497. LogOn.Status = stat;
  1498. LogOn.Seq_Login = login_seq;
  1499.  
  1500. switch(Header.Version) {
  1501.   case 0x0002:
  1502.     LogOn.X1 = 0x00000000;
  1503.     LogOn.X3 = 0x00000002;
  1504.     LogOn.X4 = 0x00000000;
  1505.     LogOn.X5 = 0x007300D9;
  1506.     break;
  1507.   case 0x0005:
  1508.     LogOn.X1 = 0x000000D6;
  1509.     LogOn.X3 = 0x00000002; // TCP Version (Should be v6, but...)
  1510.     LogOn.X4 = 0x00000000;
  1511.     LogOn.X5 = 0x00D60000; // This changes
  1512.     LogOn.X6 = 0x00000050;
  1513.     LogOn.X7 = 0x00000003;
  1514.     LogOn.X8 = rand() & 0x3FFFFFFF;
  1515.     break;
  1516. }
  1517.  
  1518. len = UDP_CreatePacket(&Header,&LogOn,UDP_Buf);
  1519.  
  1520. if (FirstLogin) login_seq += 8;
  1521. else login_seq += 6;
  1522.  
  1523. if (send_udp_pkt(UDP_Buf,len,uin) < len) return;
  1524.  
  1525. TryAgain = FALSE;
  1526.  
  1527. if (!NewUser && !Reconnecting) {
  1528.   DoMethod(app->LV_ICQCliLog,MUIM_NList_Clear);
  1529.   DoMethod(app->LV_ICQSrvLog,MUIM_NList_Clear);
  1530. }
  1531.  
  1532. if (!Reconnecting) set(app->TX_Color,MUIA_Text_Contents,"Logging in...");
  1533. else Reconnecting = FALSE;
  1534.  
  1535. Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  1536.  
  1537. return;
  1538.  
  1539. }
  1540.  
  1541.  
  1542. void __asm DisconnectICQ(REG(a2) APTR obj)
  1543.  
  1544. {
  1545.  
  1546. int len = 0;
  1547.  
  1548. ULONG uin;
  1549.  
  1550. struct C_LogOff LogOff;
  1551.  
  1552. if (!Online) return;
  1553.  
  1554. //HandleError(DBG_UDP_DBUG,"DisconnectICQ()");
  1555.  
  1556. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  1557.  
  1558. Header.Command = C_SEND_TEXT_CODE;
  1559.  
  1560. LogOff.Text = "B_USER_DISCONNECTED";
  1561. LogOff.X1 = 0x0005;
  1562.  
  1563. len = UDP_CreatePacket(&Header,&LogOff,UDP_Buf);
  1564.  
  1565. send_udp_pkt(UDP_Buf,len,uin);
  1566.  
  1567. Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  1568.  
  1569. Online = FALSE;
  1570.  
  1571. if (obj == NULL) set(app->CY_MyStatus,MUIA_Cycle_Active,NUM_STATUS);
  1572.  
  1573. ContactsOffline();
  1574.  
  1575. LastSend = 0;
  1576.  
  1577. return;
  1578.  
  1579. }
  1580.  
  1581.  
  1582. int send_udp_pkt(void *packet, int length, ULONG uin)
  1583.  
  1584. {
  1585.  
  1586. BOOL *reconnect = NULL;
  1587.  
  1588. char *pkt;
  1589.  
  1590. int i, sent;
  1591.  
  1592. LONG total;
  1593.  
  1594. struct Sockets *socks;
  1595.  
  1596. get(app->LV_SockList,MUIA_NList_Entries,&total);
  1597.  
  1598. for(i = 0; i<total; i++) {
  1599.   DoMethod(app->LV_SockList,MUIM_NList_GetEntry,i,&socks);
  1600.   if (socks) if (socks->Type == SOCK_UDP && socks->UIN == uin) break;
  1601. }
  1602.  
  1603. switch(Header.Version) {
  1604.   case 0x0002:
  1605.     pkt = packet;
  1606.     sprintf(err_buf,"Outgoing %s packet",ICQ_CmdToText(Header.Command));
  1607.     break;
  1608.   case 0x0005:
  1609.     sprintf(err_buf,"Outgoing unencrypted %s packet",ICQ_CmdToText(Header.Command));
  1610.     PrintHex(DBG_UDP_PKTS,err_buf,packet,length);
  1611.     if (!(pkt = AllocVec(length+3,MEMF_CLEAR))) {
  1612.       HandleError(DBG_UDP_ERRS,"send_udp_pkt() - Could not allocate %d bytes!",length);
  1613.       return(0);
  1614.     }
  1615.     if (!UDP_EncryptPacket(pkt,packet,length)) return(0);
  1616.     sprintf(err_buf,"Outgoing encrypted %s packet",ICQ_CmdToText(Header.Command));
  1617.     break;
  1618. }
  1619.  
  1620. PrintHex(DBG_UDP_PKTS,err_buf,pkt,length);
  1621.  
  1622. sent = sendto(socks->Socket,pkt,length,0,(struct sockaddr *)&socks->Address,sizeof(socks->Address));
  1623.  
  1624. switch(Header.Version) {
  1625.   case 0x0005:
  1626.     FreeVec(pkt);
  1627.     break;
  1628. }
  1629.  
  1630. if (sent < length && !TryAgain) {
  1631.   HandleError(DBG_OTH_INFO,"Return from sendto (%d) less than length (%d).",sent,length);
  1632.   Online = FALSE;
  1633.   ContactsOffline();
  1634.   get(app->CH_Reconnect,MUIA_Selected,&reconnect);
  1635.   set(app->CY_MyStatus,MUIA_Cycle_Active,NUM_STATUS);
  1636.   if (reconnect) TryAgain = TRUE;
  1637. }
  1638.  
  1639. return(sent);
  1640.  
  1641. }
  1642.  
  1643.  
  1644. int recv_udp_pkt(void *packet, int length, struct Sockets *socks)
  1645.  
  1646. {
  1647.  
  1648. int recvd;
  1649.  
  1650. LONG structlength = sizeof(socks->Address);
  1651.  
  1652. recvd = recvfrom(socks->Socket,packet,length,0,(struct sockaddr *)&socks->Address,&structlength);
  1653.  
  1654. if (recvd < 0 && Errno() != EWOULDBLOCK) { /*HandleError(DBG_OTH_INFO,"There was a recvfrom error.");*/ }
  1655.  
  1656. return(recvd);
  1657.  
  1658. }
  1659.  
  1660.  
  1661. void revmemcpy(char *mem, char *dat, int len)
  1662.  
  1663. {
  1664.  
  1665. int i, j;
  1666.  
  1667. for(i = 0, j = len-1; i<len; i++, j--) *(mem+j) = *(dat+i);
  1668.  
  1669. return;
  1670.  
  1671. }
  1672.  
  1673.  
  1674. APTR __asm AddLog(REG(a2) APTR pool, REG(a1) struct ICQLog *log)
  1675.  
  1676. {
  1677.  
  1678. struct ICQLog *newlog = NULL;
  1679.  
  1680. if (!(newlog = AllocPooled(pool,sizeof(struct ICQLog)))) return(NULL);
  1681.  
  1682. if (log->Pkt && log->Len > 0) {
  1683.   if (!(newlog->Pkt = AllocVec(log->Len,MEMF_CLEAR))) {
  1684.     FreePooled(pool,newlog,sizeof(struct ICQLog));
  1685.     return(NULL);
  1686.   }
  1687.   memcpy(newlog->Pkt,log->Pkt,log->Len);
  1688. }
  1689. else newlog->Pkt = NULL;
  1690.  
  1691. newlog->UIN = log->UIN;
  1692. newlog->Seq = log->Seq;
  1693. newlog->Se2 = log->Se2;
  1694. newlog->Cmd = log->Cmd;
  1695. newlog->Ack = log->Ack;
  1696. newlog->Len = log->Len;
  1697. newlog->Resend = log->Resend;
  1698. newlog->Timehack = log->Timehack;
  1699.  
  1700. return(newlog);
  1701.  
  1702. }
  1703.  
  1704.  
  1705. void __asm RemLog(REG(a2) APTR pool, REG(a1) struct ICQLog *newlog)
  1706.  
  1707. {
  1708.  
  1709. if (newlog->Pkt) FreeVec(newlog->Pkt);
  1710.  
  1711. FreePooled(pool,newlog,sizeof(struct ICQLog));
  1712.  
  1713. return;
  1714.  
  1715. }
  1716.  
  1717.  
  1718. LONG __asm CmpLog(REG(a1) struct ICQLog *l1, REG(a2) struct ICQLog *l2)
  1719.  
  1720. {
  1721.  
  1722. if (l1->Seq < l2->Seq) return(-1);
  1723. if (l1->Seq > l2->Seq) return(1);
  1724.  
  1725. return(0);
  1726.  
  1727. }
  1728.  
  1729.  
  1730. void __asm DisplayLog(REG(a2) char **array, REG(a1) struct ICQLog *log)
  1731.  
  1732. {
  1733.  
  1734. static char seq[30], *cmd, pkt[10], ack[10], resend[10];
  1735.  
  1736. if (log) {
  1737.   if (log->Se2) sprintf(seq,"%d/%ld",log->Se2,log->Seq);
  1738.   else sprintf(seq,"%ld",log->Seq);
  1739.   cmd = ICQ_CmdToText(log->Cmd);
  1740.   if (log->Pkt) strcpy(pkt,"Yes");
  1741.   else strcpy(pkt,"No");
  1742.   if (log->Ack) strcpy(ack,"Yes");
  1743.   else strcpy(ack,"No");
  1744.   sprintf(resend,"%d",log->Resend);
  1745.   *array++ = seq;
  1746.   *array++ = cmd;
  1747.   *array++ = pkt;
  1748.   *array++ = resend;
  1749.   *array   = ack;
  1750. }
  1751. else {
  1752.   *array++ = "Seq";
  1753.   *array++ = "Command";
  1754.   *array++ = "Packet";
  1755.   *array++ = "Resend";
  1756.   *array   = "ACK";
  1757. }
  1758.  
  1759. return;
  1760.  
  1761. }
  1762.  
  1763.  
  1764. ULONG ParseUDPCommands(struct IClass *cl, Object *obj, Msg msg)
  1765.  
  1766. {
  1767.  
  1768. int i;
  1769.  
  1770. static int last = 0;
  1771.  
  1772. ULONG total;
  1773.  
  1774. UWORD cmd;
  1775.  
  1776. struct ICQLog *log;
  1777. struct TimeData *data = INST_DATA(cl,obj);
  1778.  
  1779. if (CheckIO((struct IORequest *)data->req_hbeat)) {
  1780. //HandleError(DBG_UDP_DBUG,"In ParseUDPCommands.");
  1781.   WaitIO((struct IORequest *)data->req_hbeat);
  1782.   data->req_hbeat->tr_node.io_Command = TR_ADDREQUEST;
  1783.   data->req_hbeat->tr_time.tv_secs = data->Seconds;
  1784.   data->req_hbeat->tr_time.tv_micro = data->Micros;
  1785.   get(app->LV_ICQSrvLog,MUIA_NList_Entries,&total);
  1786.   if (total < last) last = 0;
  1787.   if (last < total) {
  1788.     for(i = last; i < total; i++) {
  1789.       DoMethod(app->LV_ICQSrvLog,MUIM_NList_GetEntry,i,&log);
  1790.       if (log) {
  1791.         if (log->Pkt) {
  1792.           cmd = log->Cmd;
  1793.           ParseCmd(log->Cmd,log->Seq,log->Pkt,log->Len);
  1794.           if (cmd == 0x00F0 || cmd == S_TOO_BUSY || cmd == S_GO_AWAY) break;
  1795.           FreeVec(log->Pkt);
  1796.           log->Pkt = NULL;
  1797.           log->Len = 0;
  1798.           DoMethod(app->LV_ICQSrvLog,MUIM_NList_Redraw,i);
  1799.           last = i;
  1800.           break;
  1801.         }
  1802.       }
  1803.     }
  1804.   }
  1805.   SendIO((struct IORequest *)data->req_hbeat);
  1806.   return(TRUE);
  1807. }
  1808.  
  1809. return(FALSE);
  1810.  
  1811. }
  1812.  
  1813.  
  1814. void ParseCmd(UWORD cmd, UWORD seq, char *buf, int data_len)
  1815.  
  1816. {
  1817.  
  1818. int len = 0;
  1819.  
  1820. ULONG localin;
  1821.  
  1822. struct UDP_Header PHdr;
  1823.  
  1824. get(app->STR_ICQUIN,MUIA_String_Integer,&localin);
  1825.  
  1826. UDP_ParseHeader(buf,&PHdr);
  1827.  
  1828. switch(cmd) {
  1829. /*
  1830.   case S_ACK: {
  1831.     char *pw;
  1832.     UBYTE X1 = 0;
  1833.     ULONG uin = 0;
  1834.     UWORD ack = 0;
  1835.     struct C_NewUser NewUIN;
  1836.     switch(seq) {
  1837.       case 0x0001:
  1838.         revmemcpy((char *)&ack,buf+len,2); len += 2;
  1839.         revmemcpy((char *)&uin,buf+len,4); len += 4;
  1840.         revmemcpy((char *)&X1,buf+len,1); len++;
  1841.         if (ack == 0x000a) {
  1842.           get(app->STR_ICQPass,MUIA_String_Contents,&pw);
  1843.           Header.Command = C_NEW_USER_REG;
  1844.           NewUIN.X1 = 0x000c;
  1845.           strcpy(NewUIN.Password,pw);
  1846.           NewUIN.Random = (UWORD)rand();
  1847.           NewUIN.Pad = 0x0000;
  1848.           switch(Header.Version) {
  1849.             case 0x0002:
  1850.               NewUIN.X2 = 0x00000073;
  1851.               break;
  1852.             case 0x0005:
  1853.               NewUIN.X2 = 0x000000A0;
  1854.               NewUIN.X3 = 0x00A00000;
  1855.               NewUIN.X4 = 0x00000000;
  1856.               break;
  1857.           }
  1858.           len = UDP_CreatePacket(&Header,&NewUIN,UDP_Buf);
  1859.           send_udp_pkt(UDP_Buf,len,uin);
  1860.           Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  1861.         }
  1862.         break;
  1863.     }
  1864.     break;
  1865.   }
  1866. */
  1867.   case S_LOGIN_REPLY: {
  1868.     static char mesg[20];
  1869.     ULONG uin = 0;
  1870. //  struct C_LogOn_2 LogOn2;
  1871.     struct S_Login_Reply Reply;
  1872.     set(app->TX_Color,MUIA_Text_Contents,"Connected...");
  1873.     get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  1874.  
  1875.     UDP_ParsePacket(&Reply,buf,data_len,&PHdr);
  1876.  
  1877.     set(app->TX_CurrentIP,MUIA_Text_Contents,Inet_NtoA(Reply.IP));
  1878.  
  1879.     Header.Command = C_LOGIN_1;
  1880.     len = UDP_CreatePacket(&Header,NULL,UDP_Buf);
  1881.     send_udp_pkt(UDP_Buf,len,uin);
  1882.     Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  1883. /*
  1884.     if (FirstLogin && !NewUser) {
  1885.       struct C_SendURLMsg URLMsg;
  1886.       Header.Command = C_SEND_URL_MESSAGE;
  1887.       URLMsg.Index = URLMsg_cnt;
  1888.       len = UDP_CreatePacket(&Header,&URLMsg,UDP_Buf);
  1889.       send_udp_pkt(UDP_Buf,len,uin);
  1890.       Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  1891.     }
  1892.  
  1893.     if (!NewUser) {
  1894.       struct C_LogOn_3 LogOn3;
  1895.       Header.Command = C_LOGIN_3;
  1896.       LogOn3.X1 = 0x00000000;
  1897.       len = UDP_CreatePacket(&Header,&LogOn3,UDP_Buf);
  1898.       send_udp_pkt(UDP_Buf,len,uin);
  1899.       Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  1900.     }
  1901. */
  1902. //  if (FirstLogin && !NewUser) {
  1903. //    struct C_ServerStat SrvrStat;
  1904. //    Header.Command = C_QUERY_STATUS;
  1905. //    SrvrStat.Index = SrvrMsg_cnt;
  1906. //    len = UDP_CreatePacket(&Header,&SrvrStat,UDP_Buf);
  1907. //    send_udp_pkt(UDP_Buf,len,uin);
  1908. //    Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  1909. //  }
  1910. /*
  1911.     Header.Command = C_LOGIN_2;
  1912.     LogOn2.X1 = 0x00;
  1913.     len = UDP_CreatePacket(&Header,&LogOn2,UDP_Buf);
  1914.     send_udp_pkt(UDP_Buf,len,uin);
  1915.     Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  1916. */
  1917.     if (NewUser) SendUInfo1(NULL);
  1918.  
  1919.     SendContacts(uin,C_CONTACT_LIST);
  1920.     SendContacts(uin,C_VIS_LIST);
  1921.     SendContacts(uin,C_INVIS_LIST);
  1922.  
  1923.     if (NewUser) SendUInfo2(NULL);
  1924.  
  1925.     sprintf(mesg,"%s (%ld)",GetNick(uin),uin);
  1926.     set(app->TX_Color,MUIA_Text_Contents,mesg);
  1927.     Online = TRUE;
  1928.     FirstLogin = NewUser = FALSE;
  1929.     break;
  1930.   }
  1931.   case S_BAD_PASSWORD:
  1932.     set(app->TX_Color,MUIA_Text_Contents,"Bad Password");
  1933.     break;
  1934.   case S_RECEIVE_MESSAGE: {
  1935.     BOOL flag = TRUE;
  1936.     char tmp[80];
  1937.     struct Contact *user;
  1938.     struct ICQMessage msg;
  1939.     struct S_Receive_Message Offline;
  1940.     UDP_ParsePacket(&Offline,buf,data_len,&PHdr);
  1941.     if (CheckIgnore(Offline.UIN)) break;
  1942.     sprintf(tmp,"Message Sent %02d/%02d/%04d at %02d:%02d",Offline.Day,Offline.Month,Offline.Year,Offline.Hour,Offline.Minute);
  1943.     msg.Msg = tmp;
  1944.     msg.Timehack = time(NULL);
  1945.     msg.Type = Offline.Type;
  1946.     msg.UIN = Offline.UIN;
  1947.     DoMethod(app->LV_Msgs,MUIM_NList_InsertSingleWrap,&msg,MUIV_NList_Insert_Bottom,WRAPCOL2,ALIGN_LEFT);
  1948.     if (user = GetContact(Offline.UIN)) {
  1949.       if (!user->UWin) flag = CreateUserWin(Offline.UIN);
  1950.       if (flag) DoMethod(user->UWin->LV_Msgs,MUIM_NList_InsertSingleWrap,&msg,MUIV_NList_Insert_Bottom,WRAPCOL2,ALIGN_LEFT);
  1951.     }
  1952.     ParseMessage(PHdr.Command,Offline.MessageBuf,Offline.UIN,Offline.Type);
  1953.     break;
  1954.   }
  1955.   case S_GET_MESSAGE: {
  1956.     BOOL *useaway = NULL;
  1957.     char *awaymsg;
  1958.     LONG index;
  1959.     time_t temp;
  1960.     struct S_Get_Message Message;
  1961.     UDP_ParsePacket(&Message,buf,data_len,&PHdr);
  1962.     if (CheckIgnore(Message.UIN)) break;
  1963.     ParseMessage(PHdr.Command,Message.MessageBuf,Message.UIN,Message.Type);
  1964.     get(app->STR_ICQUIN,MUIA_String_Integer,&localin);
  1965.     get(app->CY_MyStatus,MUIA_Cycle_Active,&index);
  1966.     get(app->CH_UseMessages[index],MUIA_Selected,&useaway);
  1967.     if (useaway) {
  1968.       get(app->STR_Messages[index],MUIA_String_Contents,&awaymsg);
  1969.       if (strlen(awaymsg) && Message.UIN != localin) {
  1970.         temp = LastSend;
  1971.         SendAMessage(NULL,Message.UIN,awaymsg,0x0001,MSG_BOTH,MSG_VIA_BEST);
  1972.         LastSend = temp;
  1973.       }
  1974.     }
  1975.     if (!GetContact(Message.UIN) && Message.UIN != 10) set(app->WI_Message,MUIA_Window_Open,TRUE);
  1976.     break;
  1977.   }
  1978.   case S_STATUS_UPDATE : {
  1979.     int i;
  1980.     ULONG total = 0;
  1981.     struct ColorText *ct;
  1982.     struct Contact *user;
  1983.     struct Activity Acty;
  1984.     struct S_Status_Update Status;
  1985.     UDP_ParsePacket(&Status,buf,data_len,&PHdr);
  1986. //  HandleError(DBG_TCP_DBUG,"%s update to 0x%08lx",GetNick(Status.UIN),Status.Status);
  1987.     get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  1988.     for(i = 0; i<total; i++) {
  1989.       DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  1990.       if (user) {
  1991.         if (user->UIN == Status.UIN) {
  1992.           user->Status = Status.Status;
  1993. //        DoMethod(app->LV_OfflineList,MUIM_NList_Redraw,i);
  1994.           DoMethod(app->LV_OfflineList,MUIM_NList_Sort);
  1995.           if (user->UWin) {
  1996.             ct = GetStatus(user->Status);
  1997.             sprintf(user->UWin->Status,ct->Status);
  1998.             sprintf(user->UWin->Title,"%ld %s (%s)",user->UIN,user->Nick,user->UWin->Status);
  1999.             set(user->UWin->WI_UserWindow,MUIA_Window_Title,user->UWin->Title);
  2000.           }
  2001.           Acty.UIN = Status.UIN;
  2002.           Acty.Timehack = time(NULL);
  2003.           Acty.Status = user->Status;
  2004.           DoMethod(app->LV_Activity,MUIM_NList_InsertSingle,&Acty,MUIV_NList_Insert_Sorted);
  2005.           break;
  2006.         }
  2007.       }
  2008.     }
  2009.     break;
  2010.   }
  2011.   case S_USER_OFFLINE: {
  2012.     char *notifycmd, cmdln[MAXNAMLEN];
  2013.     int i;
  2014.     ULONG total = 0;
  2015.     struct Activity Acty;
  2016.     struct ColorText *ct;
  2017.     struct Contact *user;
  2018.     struct S_User_Offline Offline;
  2019.     UDP_ParsePacket(&Offline,buf,data_len,&PHdr);
  2020.     get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  2021.     for(i = 0; i<total; i++) {
  2022.       DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  2023.       if (user) {
  2024.         if (user->UIN == Offline.UIN) {
  2025.           user->IP = user->Port = 0;
  2026.           user->Status = STATUS_OFFLINE;
  2027. //        DoMethod(app->LV_OfflineList,MUIM_NList_Redraw,i);
  2028.           DoMethod(app->LV_OfflineList,MUIM_NList_Sort);
  2029.           if (user->UWin) {
  2030.             ct = GetStatus(user->Status);
  2031.             sprintf(user->UWin->Status,ct->Status);
  2032.             sprintf(user->UWin->Title,"%ld %s (%s)",user->UIN,user->Nick,user->UWin->Status);
  2033.             set(user->UWin->WI_UserWindow,MUIA_Window_Title,user->UWin->Title);
  2034.           }
  2035.           Acty.UIN = Offline.UIN;
  2036.           Acty.Timehack = time(NULL);
  2037.           Acty.Status = STATUS_OFFLINE;
  2038.           DoMethod(app->LV_Activity,MUIM_NList_InsertSingle,&Acty,MUIV_NList_Insert_Sorted);
  2039.           get(app->STR_OfflineNotify,MUIA_String_Contents,¬ifycmd);
  2040.           if (strlen(notifycmd) > 0) {
  2041.             sprintf(cmdln,notifycmd,Offline.UIN);
  2042.             System(cmdln,NULL);
  2043.           }
  2044.           break;
  2045.         }
  2046.       }
  2047.     }
  2048.     break;
  2049.   }
  2050.   case S_USER_ONLINE: {
  2051.     char *notifycmd, cmdln[MAXNAMLEN];
  2052.     int i;
  2053.     ULONG total = 0;
  2054.     struct Activity Acty;
  2055.     struct ColorText *ct;
  2056.     struct Contact *user;
  2057.     struct S_User_Online Online;
  2058.     UDP_ParsePacket(&Online,buf,data_len,&PHdr);
  2059.     get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  2060.     for(i = 0; i<total; i++) {
  2061.       DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  2062.       if (user) {
  2063.         if (user->UIN == Online.UIN) {
  2064.           user->IP = Online.IP;
  2065.           user->Port = Online.TCP_MsgPort;
  2066.           user->RealIP = Online.RealIP;
  2067.           user->CanTCP = Online.TCP_Flag;
  2068.           user->Status = Online.Status;
  2069.           user->LastOnline = time(NULL);
  2070.           user->Changed = TRUE;
  2071. //        HandleError(DBG_UDP_DBUG,"%s online as 0x%08lx",GetNick(Online.UIN),user->Status);
  2072. //        sprintf(err_buf,"%s IP = %s, ",GetNick(Online.UIN),Inet_NtoA(user->IP));
  2073. //        sprintf(cmdln,"RealIP = %s",Inet_NtoA(user->RealIP));
  2074. //        strcat(err_buf,cmdln);
  2075. //        HandleError(DBG_UDP_DBUG,err_buf);
  2076. //        DoMethod(app->LV_OfflineList,MUIM_NList_Redraw,i);
  2077.           DoMethod(app->LV_OfflineList,MUIM_NList_Sort);
  2078. //        HandleError(DBG_UDP_DBUG,"%s %d",user->Nick,user->CanTCP);
  2079.           if (user->UWin) {
  2080.             ct = GetStatus(user->Status);
  2081.             sprintf(user->UWin->IP,"%s:%ld",Inet_NtoA(user->IP),user->Port);
  2082.             strcpy(user->UWin->Status,ct->Status);
  2083.             set(user->UWin->TX_IP,MUIA_Text_Contents,user->UWin->IP);
  2084.             sprintf(user->UWin->Title,"%ld %s (%s)",user->UIN,user->Nick,user->UWin->Status);
  2085.             set(user->UWin->WI_UserWindow,MUIA_Window_Title,user->UWin->Title);
  2086.           }
  2087.           Acty.UIN = Online.UIN;
  2088.           Acty.Timehack = time(NULL);
  2089.           Acty.Status = user->Status;
  2090.           DoMethod(app->LV_Activity,MUIM_NList_InsertSingle,&Acty,MUIV_NList_Insert_Sorted);
  2091.           get(app->STR_OnlineNotify,MUIA_String_Contents,¬ifycmd);
  2092.           if (strlen(notifycmd) > 0 && ((user->Status & 0x000000ff) == STATUS_ONLINE)) {
  2093.             sprintf(cmdln,notifycmd,Online.UIN);
  2094.             System(cmdln,NULL);
  2095.           }
  2096.           break;
  2097.         }
  2098.       }
  2099.     }
  2100.     break;
  2101.   }
  2102.   case S_END_OFFLINE_MSGS: {
  2103.     ULONG uin = 0;
  2104.     get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  2105.     Header.Command = C_ACK_MSG;
  2106.     len = UDP_CreatePacket(&Header,NULL,UDP_Buf);
  2107.     send_udp_pkt(UDP_Buf,len,uin);
  2108.     Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  2109.     break;
  2110.   }
  2111.   case S_USER_FOUND: {
  2112.     char msg[50];
  2113.     struct Contact User;
  2114.     struct S_Basic_Info BasicInfo;
  2115.     UDP_ParsePacket(&BasicInfo,buf,data_len,&PHdr);
  2116.     PrepNewContact(&User);
  2117.     User.UIN = BasicInfo.UIN;
  2118.     User.Nick = BasicInfo.Nick;
  2119.     User.First = BasicInfo.First;
  2120.     User.Last = BasicInfo.Last;
  2121.     User.EMail = BasicInfo.EMail;
  2122.     User.Authorize = BasicInfo.Authorize;
  2123.     DoMethod(app->LV_SearchList,MUIM_NList_InsertSingle,&User,MUIV_NList_Insert_Sorted);
  2124.     sprintf(msg,"Found %d Search Hits",++found);
  2125.     set(app->TX_SearchStat,MUIA_Text_Contents,msg);
  2126.     break;
  2127.   }
  2128.   case S_INFO_REPLY: {
  2129.     struct S_Basic_Info BasicInfo;
  2130.     UDP_ParsePacket(&BasicInfo,buf,data_len,&PHdr);
  2131.     switch(UserInfoReqID[0]) {
  2132.       case INFO_VIEW:
  2133.         InfoView(&BasicInfo,INFO_BASIC);
  2134.         break;
  2135.       case INFO_REFRESH:
  2136.         InfoRefresh(&BasicInfo,INFO_BASIC);
  2137.         break;
  2138.       case INFO_GRABME:
  2139.         InfoGrabMe(&BasicInfo,INFO_BASIC);
  2140.         break;
  2141.     }
  2142.     break;
  2143.   }
  2144.   case S_EXT_INFO_REPLY: {
  2145.     struct S_Ext_Info ExtInfo;
  2146.     UDP_ParsePacket(&ExtInfo,buf,data_len,&PHdr);
  2147.     switch(UserInfoReqID[0]) {
  2148.       case INFO_VIEW:
  2149.         InfoView(&ExtInfo,INFO_EXTENDED);
  2150.         break;
  2151.       case INFO_REFRESH:
  2152.         InfoRefresh(&ExtInfo,INFO_EXTENDED);
  2153.         break;
  2154.       case INFO_GRABME:
  2155.         InfoGrabMe(&ExtInfo,INFO_EXTENDED);
  2156.         break;
  2157.     }
  2158.     break;
  2159.   }
  2160.   case S_META: {
  2161.     struct S_Meta Meta;
  2162.     UDP_ParsePacket(&Meta,buf,data_len,&PHdr);
  2163.     if (Meta.Success != META_SUCCESS) break;
  2164. //  HandleError(DBG_UDP_DBUG,"UserInfoReqID[2] = %d, PHdr.Sequence = %d",UserInfoReqID[2],PHdr.Sequence);
  2165.     if (UserInfoReqID[2] != PHdr.Sequence) break;
  2166.     switch(Meta.Subcommand) {
  2167.       case META_INFO_HOME: {
  2168.         struct Meta_Info_Home Home;
  2169.         UDP_ParseMeta(&Home,&Meta);
  2170.         switch(UserInfoReqID[0]) {
  2171.           case INFO_GRABME:
  2172.             InfoGrabMe(&Home,INFO_META_HOME);
  2173.             break;
  2174.           case INFO_REFRESH:
  2175.             InfoRefresh(&Home,INFO_META_HOME);
  2176.             break;
  2177.         }
  2178.         break;
  2179.       }
  2180.       case META_INFO_WORK: {
  2181.         struct Meta_Info_Work Work;
  2182.         UDP_ParseMeta(&Work,&Meta);
  2183.         switch(UserInfoReqID[0]) {
  2184.           case INFO_GRABME:
  2185.             InfoGrabMe(&Work,INFO_META_WORK);
  2186.             break;
  2187.         }
  2188.         break;
  2189.       }
  2190.       case META_INFO_MORE: {
  2191.         struct Meta_Info_More More;
  2192.         UDP_ParseMeta(&More,&Meta);
  2193.         switch(UserInfoReqID[0]) {
  2194.           case INFO_GRABME:
  2195.             InfoGrabMe(&More,INFO_META_MORE);
  2196.             break;
  2197.           case INFO_REFRESH:
  2198.             InfoRefresh(&More,INFO_META_MORE);
  2199.             break;
  2200.         }
  2201.         break;
  2202.       }
  2203.       case META_INFO_ABOUT: {
  2204.         struct Meta_Info_About About;
  2205.         UDP_ParseMeta(&About,&Meta);
  2206.         switch(UserInfoReqID[0]) {
  2207.           case INFO_GRABME:
  2208.             InfoGrabMe(&About,INFO_META_ABOUT);
  2209.             break;
  2210.           case INFO_REFRESH:
  2211.             InfoRefresh(&About,INFO_META_ABOUT);
  2212.             break;
  2213.         }
  2214.         break;
  2215.       }
  2216.     }
  2217.     break;
  2218.   }
  2219.   case S_END_OF_SEARCH: {
  2220.     char msg[50];
  2221.     struct S_End_Of_Search Search;
  2222.     UDP_ParsePacket(&Search,buf,data_len,&PHdr);
  2223.     if (Search.Sequence == srch_seq-1) {
  2224.       sprintf(msg,"Search Complete, Found %d Hits",found);
  2225.       set(app->TX_SearchStat,MUIA_Text_Contents,msg);
  2226.     }
  2227.     break;
  2228.   }
  2229.   case 0x00f0:
  2230.   case S_TOO_BUSY:
  2231.   case S_GO_AWAY: {
  2232. //  BOOL *reconnect = NULL;
  2233. //  LONG index;
  2234. //  get(app->CY_MyStatus,MUIA_Cycle_Active,&index);
  2235. //  get(app->CH_Reconnect,MUIA_Selected,&reconnect);
  2236. //  if (reconnect && index != NUM_STATUS) {
  2237. //    Reconnecting = TRUE;
  2238. //    Delay(500);
  2239. //    ConnectICQ(NULL);
  2240. //  }
  2241. //  else DisconnectICQ(NULL);
  2242.     break;
  2243.   }
  2244.   case S_SYSTEM_MESSAGE: {
  2245.     char *notifycmd;
  2246.     struct S_System_Message SysMsg;
  2247.     UDP_ParsePacket(&SysMsg,buf,data_len,&PHdr);
  2248.     URLMsg_cnt = SysMsg.Index;
  2249.     DoMethod(app->LV_AdText,MUIM_NList_Clear);
  2250.     DoMethod(app->LV_AdText,MUIM_NList_InsertWrap,SysMsg.Ad,-2,MUIV_NList_Insert_Bottom,WRAPCOL0,ALIGN_CENTER);
  2251.     set(app->TX_AdURL,MUIA_Text_Contents,SysMsg.URL);
  2252.     set(app->BT_AdGoURL,MUIA_Text_Contents,SysMsg.Button);
  2253.     DoMethod(app->App,MUIM_Application_PushMethod,app->WI_URLMessage,3,MUIM_Set,MUIA_Window_Open,TRUE);
  2254.     get(app->STR_SysMsg,MUIA_String_Contents,¬ifycmd);
  2255.     if (strlen(notifycmd) > 0) System(notifycmd,NULL);
  2256.     break;
  2257.   }
  2258. /*
  2259.   case S_NEW_USER_UIN: {
  2260.     UWORD X1 = 0;
  2261.     ULONG uin = 0, rnd = 0;
  2262.     revmemcpy((char *)&X1,buf+len,2); len += 2;
  2263.     revmemcpy((char *)&uin,buf+len,4); len += 4;
  2264.     revmemcpy((char *)&rnd,buf+len,4); len += 4;
  2265.     set(app->STR_ICQUIN,MUIA_String_Integer,uin);
  2266.     ConnectICQ(NULL);
  2267.     break;
  2268.   }
  2269. */
  2270.   case S_REPLY_X1:
  2271.     break;
  2272.   case S_TCP_REQUEST: {
  2273.     UBYTE type = SOCK_MESSAGE;
  2274.     struct Contact *user;
  2275.     struct Sockets *socks;
  2276.     struct S_TCP_Request Req;
  2277.     UDP_ParsePacket(&Req,buf,data_len,&PHdr);
  2278.     user = GetContact(Req.Remote_UIN);
  2279.     if (user->Type == TCP_MSG_CHAT) {
  2280.       type = SOCK_CHAT;
  2281.       if (!user->ChatListen) user->ChatListen = OpenTCPListen(type);
  2282.     }
  2283.     if (user->Type == TCP_MSG_FILE) {
  2284.       type = SOCK_FILE;
  2285.       if (!FileListen) FileListen = OpenTCPListen(type);
  2286.     }
  2287.     if (Req.IP == 0) Req.IP = user->IP;
  2288.     HandleError(DBG_TCP_DBUG,"Attempting reverse connect to %s %s:%ld",user->Nick,Inet_NtoA(Req.IP),Req.Port);
  2289.     if (!OpenTCPSocket(user,type,Req.IP,Req.Port)) {
  2290.       if (!OpenTCPSocket(user,type,user->RealIP,Req.Port)) {
  2291.         HandleError(DBG_TCP_ERRS,"Could not open a reverse TCP connection to %s.",user->Nick);
  2292.         HandleError(DBG_OTH_INFO,"Reverse connect failed!");
  2293.       }
  2294.     }
  2295.     if (socks = GetSocketFmContact(user,type)) {
  2296.       socks->Backward = TRUE;
  2297.       HandleError(DBG_OTH_INFO,"  Reverse connect succeded!");
  2298.     }
  2299.     user->Type = TCP_MSG_MSG;
  2300.     break;
  2301.   }
  2302.   case S_UPDATE_REPLY:
  2303.   case S_UPDATE_EXT_REPLY:
  2304.   case S_UPDATE_AUTH_REPLY:
  2305.   case S_INFO_NOT_FOUND:
  2306.   case S_EXT_INFO_NOT_FOUND:
  2307.   case S_MULTI:
  2308.     break;
  2309.   default:
  2310.     PrintHex(DBG_UDP_DBUG,"Unprocessed UDP Packet",buf,data_len);
  2311. }
  2312.  
  2313. return;
  2314.  
  2315. }
  2316.  
  2317.  
  2318. APTR __asm AddMsg(REG(a2) APTR pool, REG(a1) struct ICQMessage *msg)
  2319.  
  2320. {
  2321.  
  2322. struct ICQMessage *newmsg = NULL;
  2323.  
  2324. if (!(newmsg = AllocPooled(pool,sizeof(struct ICQMessage)))) return(NULL);
  2325.  
  2326. newmsg->UIN = msg->UIN;
  2327. newmsg->Timehack = msg->Timehack;
  2328. newmsg->Type = msg->Type;
  2329.  
  2330. if (!(newmsg->Msg = AllocPooled(pool,strlen(msg->Msg)+1))) {
  2331.   FreePooled(pool,newmsg,sizeof(struct ICQMessage));
  2332.   return(NULL);
  2333. }
  2334. strcpy(newmsg->Msg,msg->Msg);
  2335.  
  2336. return(newmsg);
  2337.  
  2338. }
  2339.  
  2340.  
  2341. void __asm RemMsg(REG(a2) APTR pool, REG(a1) struct ICQMessage *newmsg)
  2342.  
  2343. {
  2344.  
  2345. FreePooled(pool,newmsg->Msg,strlen(newmsg->Msg)+1);
  2346. FreePooled(pool,newmsg,sizeof(struct ICQMessage));
  2347.  
  2348. return;
  2349.  
  2350. }
  2351.  
  2352.  
  2353. LONG __asm CmpMsg(REG(a1) struct ICQMessage *m1, REG(a2) struct ICQMessage *m2)
  2354.  
  2355. {
  2356.  
  2357. if (m1->UIN < m2->UIN) return(-1);
  2358. if (m1->UIN > m2->UIN) return(1);
  2359.  
  2360. return(0);
  2361.  
  2362. }
  2363.  
  2364.  
  2365. void __asm DisplayMsg(REG(a2) char **array, REG(a1) struct ICQMessage *msg)
  2366.  
  2367. {
  2368.  
  2369. BOOL *usebeats;
  2370.  
  2371. static char uin[100], tme[15];
  2372.  
  2373. get(app->CH_UseBeats,MUIA_Selected,&usebeats);
  2374.  
  2375. if (msg) {
  2376.   switch(msg->UIN) {
  2377.     case 0x00000000:
  2378.       strcpy(uin," ");
  2379.       break;
  2380.     case 0x00000019:
  2381.     case 0x0000000a:
  2382.       switch(msg->Type) {
  2383.         case 0x0004:
  2384.           strcpy(uin,"Web Message");
  2385.           break;
  2386.         case 0x000a:
  2387.           strcpy(uin,"Query Reply");
  2388.           break;
  2389.         case 0x0019:
  2390.           strcpy(uin,"ICQ Hint");
  2391.           break;
  2392.       }
  2393.       break;
  2394.     default:
  2395.       if (msg->Type == 0x004) strcpy(uin," ");
  2396.       else strcpy(uin,GetNick(msg->UIN));
  2397.   }
  2398.   if (msg->UIN) {
  2399.     if (usebeats) sprintf(tme,"@ %d",MakeBeats(msg->Timehack));
  2400.     else strncpy(tme,ctime(&msg->Timehack)+11,8);
  2401.   }
  2402.   else strcpy(tme," ");
  2403.   *array++ = uin;
  2404.   *array++ = tme;
  2405.   *array   = msg->Msg;
  2406. }
  2407. else {
  2408.   *array++ = "Sender";
  2409.   *array++ = "Time";
  2410.   *array   = "Message";
  2411. }
  2412.  
  2413. return;
  2414.  
  2415. }
  2416.  
  2417.  
  2418. ULONG __asm TimeDispatcher(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg)
  2419.  
  2420. {
  2421.  
  2422. switch(msg->MethodID) {
  2423.   case OM_NEW:
  2424.     return(TIME_New(cl,obj,(APTR)msg));
  2425.   case OM_SET:
  2426.     return(TIME_Set(cl,obj,(APTR)msg));
  2427.   case OM_DISPOSE:
  2428.     return(TIME_Dispose(cl,obj,(APTR)msg));
  2429.   case TIME_AddApp:
  2430.     return(TIME_Setup(cl,obj,(APTR)msg));
  2431.   case TIME_RemApp:
  2432.     return(TIME_Cleanup(cl,obj,(APTR)msg));
  2433.   case TIME_Trigger:
  2434.     return(TIME_Trigger_cl(cl,obj,(APTR)msg));
  2435.   case TIME_Trigger1:
  2436.     return(TIME_Trigger_cl1(cl,obj,(APTR)msg));
  2437.   case TIME_Trigger2:
  2438.     return(SendAFile(cl,obj,(APTR)msg));
  2439.   case TIME_Trigger_Parse:
  2440.     return(ParseUDPCommands (cl,obj,(APTR)msg));
  2441. }
  2442.  
  2443. return(DoSuperMethodA(cl,obj,msg));
  2444.  
  2445. }
  2446.  
  2447.  
  2448. ULONG TIME_New(struct IClass *cl, Object *obj, Msg msg)
  2449.  
  2450. {
  2451.  
  2452. struct TimeData *data;
  2453. struct TagItem *tags, *tag;
  2454.  
  2455. //HandleError(DBG_OTH_INFO,"In TIME_New");
  2456.  
  2457. if (!(obj = (Object *)DoSuperMethodA(cl,obj,msg))) return(FALSE);
  2458.  
  2459. data = INST_DATA(cl,obj);
  2460.  
  2461. data->Socket = 0;
  2462.  
  2463. for(tags = ((struct opSet *)msg)->ops_AttrList; tag = NextTagItem(&tags); ) {
  2464.   switch(tag->ti_Tag) {
  2465.     case TIME_SetSecs:
  2466.       data->Seconds = tag->ti_Data;
  2467.       break;
  2468.     case TIME_SetMicro:
  2469.       data->Micros = tag->ti_Data;
  2470.       break;
  2471.     case TIME_SetTrg:
  2472.       data->Trigger = tag->ti_Data;
  2473.       break;
  2474.     case TIME_SetSock:
  2475.       data->Socket = tag->ti_Data;
  2476.       break;
  2477.   }
  2478. }
  2479.  
  2480. if (data->port = CreateMsgPort()) {
  2481.   if (data->req_hbeat = CreateIORequest(data->port,sizeof(struct timerequest))) {
  2482.     if (!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)data->req_hbeat,0)) {
  2483.       data->ihnode.ihn_Object = obj;
  2484.       data->ihnode.ihn_Signals = 1<<data->port->mp_SigBit;
  2485.       data->ihnode.ihn_Method = data->Trigger;
  2486.       data->ihnode.ihn_Flags = 0;
  2487.       return((ULONG)obj);
  2488.     }
  2489.   }
  2490. }
  2491.  
  2492. CoerceMethod(cl,obj,OM_DISPOSE);
  2493.  
  2494. return(FALSE);
  2495.  
  2496. }
  2497.  
  2498.  
  2499. ULONG TIME_Set(struct IClass *cl, Object *obj, Msg msg)
  2500.  
  2501. {
  2502.  
  2503. struct TimeData *data = INST_DATA(cl,obj);
  2504. struct TagItem *tags, *tag;
  2505.  
  2506. //HandleError(DBG_OTH_INFO,"In TIME_Set.");
  2507.  
  2508. for(tags = ((struct opSet *)msg)->ops_AttrList; tag = NextTagItem(&tags); ) {
  2509.   switch(tag->ti_Tag) {
  2510.     case TIME_SetSecs:
  2511.       data->Seconds = tag->ti_Data;
  2512.       break;
  2513.     case TIME_SetMicro:
  2514.       data->Micros = tag->ti_Data;
  2515.       break;
  2516.     case TIME_SetTrg:
  2517.       data->Trigger = tag->ti_Data;
  2518.       break;
  2519.     case TIME_SetSock:
  2520.       data->Socket = tag->ti_Data;
  2521.       break;
  2522.   }
  2523. }
  2524.  
  2525. return(DoSuperMethodA(cl,obj,msg));
  2526.  
  2527. }
  2528.  
  2529.  
  2530. ULONG TIME_Dispose(struct IClass *cl, Object *obj, Msg msg)
  2531.  
  2532. {
  2533.  
  2534. struct TimeData *data = INST_DATA(cl,obj);
  2535.  
  2536. //HandleError(DBG_OTH_INFO,"In TIME_Dispose");
  2537.  
  2538. if (data->req_hbeat) {
  2539.   if (data->req_hbeat->tr_node.io_Device) {
  2540.     CloseDevice((struct IORequest *)data->req_hbeat);
  2541.   }
  2542.   DeleteIORequest(data->req_hbeat);
  2543. }
  2544.  
  2545. if (data->port) DeleteMsgPort(data->port);
  2546.  
  2547. return(DoSuperMethodA(cl,obj,msg));
  2548.  
  2549. }
  2550.  
  2551.  
  2552. ULONG TIME_Setup(struct IClass *cl, Object *obj, Msg msg)
  2553.  
  2554. {
  2555.  
  2556. struct TimeData *data = INST_DATA(cl,obj);
  2557.  
  2558. //HandleError(DBG_OTH_INFO,"In TIME_Setup");
  2559.  
  2560. data->App = ((struct MUIP_PT_AddApp *)msg)->App;
  2561.  
  2562. data->req_hbeat->tr_node.io_Command = TR_ADDREQUEST;
  2563. data->req_hbeat->tr_time.tv_secs = data->Seconds;
  2564. data->req_hbeat->tr_time.tv_micro = data->Micros;
  2565.  
  2566. SendIO((struct IORequest *)data->req_hbeat);
  2567.  
  2568. DoMethod(data->App,MUIM_Application_AddInputHandler,&data->ihnode);
  2569.  
  2570. return(TRUE);
  2571.  
  2572. }
  2573.  
  2574.  
  2575. ULONG TIME_Cleanup(struct IClass *cl, Object *obj, Msg msg)
  2576.  
  2577. {
  2578.  
  2579. struct TimeData *data = INST_DATA(cl,obj);
  2580.  
  2581. //HandleError(DBG_OTH_INFO,"In TIME_Cleanup");
  2582.  
  2583. DoMethod(data->App,MUIM_Application_RemInputHandler,&data->ihnode);
  2584.  
  2585. if (!CheckIO((struct IORequest *)data->req_hbeat)) AbortIO((struct IORequest *)data->req_hbeat);
  2586. WaitIO((struct IORequest *)data->req_hbeat);
  2587.  
  2588. return(DoSuperMethodA(cl,obj,msg));
  2589.  
  2590. }
  2591.  
  2592.  
  2593. ULONG TIME_Trigger_cl(struct IClass *cl, Object *obj, Msg msg)
  2594.  
  2595. {
  2596.  
  2597. int i;
  2598.  
  2599. ULONG total;
  2600.  
  2601. struct Sockets *socks;
  2602. struct TimeData *data = INST_DATA(cl,obj);
  2603.  
  2604. //HandleError(DBG_OTH_INFO,"In TIME_Trigger");
  2605.  
  2606. if (CheckIO((struct IORequest *)data->req_hbeat)) {
  2607. //HandleError(DBG_OTH_INFO,"In Timer heartbeat.");
  2608.   WaitIO((struct IORequest *)data->req_hbeat);
  2609.   data->req_hbeat->tr_node.io_Command = TR_ADDREQUEST;
  2610.   data->req_hbeat->tr_time.tv_secs = data->Seconds;
  2611.   data->req_hbeat->tr_time.tv_micro = data->Micros;
  2612.   SendIO((struct IORequest *)data->req_hbeat);
  2613.   if (Online) SendPing();
  2614.   get(app->LV_SockList,MUIA_NList_Entries,&total);
  2615.   for(i = 0; i < total; i++) {
  2616.     DoMethod(app->LV_SockList,MUIM_NList_GetEntry,i,&socks);
  2617.     if (socks) {
  2618.       if (socks->Dir == TCP_DIR_OUT && socks->Type != SOCK_UDP) {
  2619.         if (time(NULL)-(socks->Timehack) > 360) {
  2620.           DelSockets(socks->Socket);
  2621.           i--;
  2622.           total--;
  2623.         }
  2624.       }
  2625.       if (socks->Dir == TCP_DIR_IN && socks->Type != SOCK_UDP) {
  2626.         if (time(NULL)-(socks->Timehack) > 420) {
  2627.           DelSockets(socks->Socket);
  2628.           i--;
  2629.           total--;
  2630.         }
  2631.       }
  2632.     }
  2633.   }
  2634.   return(TRUE);
  2635. }
  2636.  
  2637. return(FALSE);
  2638.  
  2639. }
  2640.  
  2641.  
  2642. ULONG TIME_Trigger_cl1(struct IClass *cl, Object *obj, Msg msg)
  2643.  
  2644. {
  2645.  
  2646. BOOL flag = FALSE;
  2647.  
  2648. int i;
  2649.  
  2650. time_t temp;
  2651.  
  2652. ULONG total, uin, secs, index = 0;
  2653.  
  2654. struct ICQLog *log;
  2655. struct TimeData *data = INST_DATA(cl,obj);
  2656.  
  2657. //HandleError(DBG_UDP_DBUG,"In TIME_Trigger 1");
  2658.  
  2659. if (CheckIO((struct IORequest *)data->req_hbeat)) {
  2660. //HandleError(DBG_OTH_INFO,"In Timer command timeout.");
  2661.   WaitIO((struct IORequest *)data->req_hbeat);
  2662.   data->req_hbeat->tr_node.io_Command = TR_ADDREQUEST;
  2663.   data->req_hbeat->tr_time.tv_secs = data->Seconds;
  2664.   data->req_hbeat->tr_time.tv_micro = data->Micros;
  2665.   SendIO((struct IORequest *)data->req_hbeat);
  2666.   get(app->LV_ICQCliLog,MUIA_NList_Entries,&total);
  2667.   if ((total > 1 && Online) || (total == 1)) {
  2668.     for(i = 0; i < total; i++) {
  2669.       DoMethod(app->LV_ICQCliLog,MUIM_NList_GetEntry,i,&log);
  2670.       if (log) {
  2671.         if (log->Pkt) {
  2672. //        HandleError(DBG_UDP_DBUG,"log->Seq = %d, log->Resend = %d",log->Seq,log->Resend);
  2673.           if (log->Resend > 5) DisconnectICQ(NULL);
  2674.           else {
  2675.             if (time(NULL)-log->Timehack > 5 && log->Cmd != TCP_MESSAGE) {
  2676. //            HandleError(DBG_UDP_DBUG,"Found an unacknowledged packet seq %d.",log->Seq);
  2677.               get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  2678.               send_udp_pkt(log->Pkt,log->Len,uin);
  2679.               log->Resend++;
  2680.               log->Timehack = time(NULL);
  2681.             }
  2682.           }
  2683.         }
  2684.       }
  2685.     }
  2686.   }
  2687.   if (LastSend && Online) {
  2688.     for(i = 0; i < 5; i++) {
  2689.       get(app->STR_TimedStatus[i],MUIA_String_Integer,&secs);
  2690.       if (secs) {
  2691.         if (time(NULL)-LastSend > secs) {
  2692.           get(app->CY_SetStatus[i],MUIA_Cycle_Active,&index);
  2693.           flag = TRUE;
  2694.         }
  2695.       }
  2696.     }
  2697.   }
  2698.   if (flag) {
  2699.     temp = LastSend;
  2700.     set(app->CY_MyStatus,MUIA_Cycle_Active,index);
  2701.     LastSend = temp;
  2702.   }
  2703.   return(TRUE);
  2704. }
  2705.  
  2706. return(FALSE);
  2707.  
  2708. }
  2709.  
  2710.  
  2711. void SendPing(void)
  2712.  
  2713. {
  2714.  
  2715. char sbuf2[30];
  2716.  
  2717. int len;
  2718.  
  2719. ULONG uin = 0;
  2720.  
  2721. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  2722.  
  2723. Header.Command = C_KEEP_ALIVE;
  2724.  
  2725. len = UDP_CreatePacket(&Header,NULL,sbuf2);
  2726.  
  2727. send_udp_pkt(sbuf2,len,uin);
  2728.  
  2729. Add2Log(LOG_CLIENT,&Header,FALSE,len,sbuf2);
  2730.  
  2731. return;
  2732.  
  2733. }
  2734.  
  2735.  
  2736. void __asm SendMessage(REG(a2) APTR obj)
  2737.  
  2738. {
  2739.  
  2740. char sendto[100], nick[100];
  2741.  
  2742. ULONG localin = 0;
  2743.  
  2744. struct ICQMessage *msg;
  2745.  
  2746. if (!Online) {
  2747.   HandleError(DBG_OTH_INFO,"Connect to ICQ first.");
  2748.   return;
  2749. }
  2750.  
  2751. get(app->STR_ICQUIN,MUIA_String_Integer,&localin);
  2752.  
  2753. DoMethod(app->LV_Msgs,MUIM_NList_GetEntry,MUIV_NList_GetEntry_Active,&msg);
  2754. if (msg) {
  2755.   BOOL flag = FALSE;
  2756.   int i;
  2757.   ULONG total = 0;
  2758.   struct Contact *user;
  2759.   if (msg->UIN == 0 || msg->UIN == 10) return;
  2760.   get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  2761.   for(i = 0; i<total; i++) {
  2762.     DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  2763.     if (user) {
  2764.       if (user->UIN == msg->UIN) {
  2765.         strcpy(nick,user->Nick);
  2766.         sprintf(sendto,"%ld %s",user->UIN,nick);
  2767.         flag = TRUE;
  2768.       }
  2769.     }
  2770.   }
  2771.   if (!flag) sprintf(sendto,"%ld",msg->UIN);
  2772. }
  2773. else {
  2774.   HandleError(DBG_OTH_INFO,"Select a message in the Message Window first.");
  2775.   return;
  2776. }
  2777.  
  2778. if (obj == app->BT_OpenURLWin) {
  2779.   set(app->STR_Desc,MUIA_Textinput_Contents,NULL);
  2780.   set(app->STR_URL,MUIA_Textinput_Contents,NULL);
  2781.   set(app->TX_SendURLto,MUIA_Text_Contents,sendto);
  2782.   set(app->WI_SendURL,MUIA_Window_Open,TRUE);
  2783.   set(app->WI_SendURL,MUIA_Window_ActiveObject,app->STR_Desc);
  2784. }
  2785. else {
  2786.   if (obj) {
  2787.     set(app->TI_Message,MUIA_Textinput_Contents,NULL);
  2788.     set(app->TX_Sendto,MUIA_Text_Contents,sendto);
  2789.     set(app->WI_Send,MUIA_Window_Open,TRUE);
  2790.     set(app->WI_Send,MUIA_Window_ActiveObject,app->TI_Message);
  2791.   }
  2792. }
  2793.  
  2794. return;
  2795.  
  2796. }
  2797.  
  2798.  
  2799. void __asm SendMsg2ICQ(REG(a2) APTR obj)
  2800.  
  2801. {
  2802.  
  2803. char *sendto = NULL, *msg = NULL, url[1024], *p1, *p2;
  2804.  
  2805. UWORD type = 0x0001;
  2806.  
  2807. ULONG userid = 0, id = 0;
  2808.  
  2809. struct Contact *user;
  2810.  
  2811. if (!Online) return;
  2812.  
  2813. get(obj,MUIA_UserData,&id);
  2814.  
  2815. user = GetContact(id);
  2816.  
  2817. if (obj == app->BT_Sendit)  set(app->WI_Send,MUIA_Window_Open,FALSE);
  2818. if (obj == app->BT_URLSend) set(app->WI_SendURL,MUIA_Window_Open,FALSE);
  2819.  
  2820. if (obj == app->TI_QuickMsg || obj == app->BT_Auth) {
  2821.   get(app->TX_QuickTo,MUIA_Text_Contents,&sendto);
  2822.   get(app->TI_QuickMsg,MUIA_Textinput_Contents,&msg);
  2823.   if (obj == app->BT_Auth) type = 0x0008;
  2824. }
  2825. else {
  2826.   if (obj == app->BT_URLSend) {
  2827.     type = 0x0004;
  2828.     get(app->TX_SendURLto,MUIA_Text_Contents,&sendto);
  2829.     get(app->STR_Desc,MUIA_Textinput_Contents,&p1);
  2830.     get(app->STR_URL,MUIA_Textinput_Contents,&p2);
  2831.     sprintf(url,"%s\376%s",p1,p2);
  2832.     msg = url;
  2833.   }
  2834.   else {
  2835.     get(app->TX_Sendto,MUIA_Text_Contents,&sendto);
  2836.     get(app->TI_Message,MUIA_Textinput_Contents,&msg);
  2837.   }
  2838. }
  2839.  
  2840. StrToLong(sendto,(LONG *)&userid);
  2841.  
  2842. if (userid == 0) return;
  2843.  
  2844. SendAMessage(obj,userid,msg,type,MSG_BOTH,MSG_VIA_BEST);
  2845.  
  2846. return;
  2847.  
  2848. }
  2849.  
  2850.  
  2851. void __asm SendMsg2ICQa(REG(a2) APTR obj)
  2852.  
  2853. {
  2854.  
  2855. BOOL *multi = NULL;
  2856.  
  2857. char *msg = NULL, url[1024], *p1, *p2, msg2[512], *c, *d;
  2858.  
  2859. LONG sel = MUIV_NList_NextSelected_Start;
  2860.  
  2861. UWORD type = 0x0001;
  2862.  
  2863. ULONG id = 0;
  2864.  
  2865. struct Contact *user;
  2866.  
  2867. get(obj,MUIA_UserData,&id);
  2868.  
  2869. if (!(user = GetContact(id))) return;
  2870.  
  2871. if (!Online && user->CanTCP == 6) return;
  2872.  
  2873. if (obj == user->UWin->TI_QuickMsg) {
  2874.   get(user->UWin->TI_QuickMsg,MUIA_Textinput_Contents,&msg);
  2875. }
  2876. else {
  2877.   if (obj == user->UWin->BT_URLSend) {
  2878.     type = 0x0004;
  2879.     get(user->UWin->STR_Desc,MUIA_Textinput_Contents,&p1);
  2880.     get(user->UWin->STR_URL,MUIA_Textinput_Contents,&p2);
  2881.     sprintf(url,"%s\376%s",p1,p2);
  2882.     msg = url;
  2883.   }
  2884.   else {
  2885.     if (obj == user->UWin->BT_Auth) {
  2886.       type = 0x0008;
  2887.       msg = "auth";
  2888.       obj = app->BT_Auth;
  2889.     }
  2890.   }
  2891. }
  2892.  
  2893. for(c = msg, d = msg2; *c; c++, d++) {
  2894.   if (*c == '\n') *d++ = '\r';
  2895.   *d = *c;
  2896. }
  2897. *d = '\0';
  2898.  
  2899. SendAMessage(obj,id,msg2,type,MSG_BOTH,MSG_VIA_BEST);
  2900.  
  2901. get(user->UWin->CH_MultiSend,MUIA_Selected,&multi);
  2902.  
  2903. if ((type == 0x0001 || type == 0x0004) && multi) {
  2904.   DoMethod(app->LV_OfflineList,MUIM_NList_NextSelected,&sel);
  2905.   while(sel != MUIV_NList_NextSelected_End) {
  2906.     DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,sel,&user);
  2907.     if (user->UIN != id) SendAMessage(obj,user->UIN,msg2,type,MSG_BOTH,MSG_VIA_BEST);
  2908.     DoMethod(app->LV_OfflineList,MUIM_NList_NextSelected,&sel);
  2909.   }
  2910. }
  2911.  
  2912. set(user->UWin->WI_UserWindow,MUIA_Window_ActiveObject,user->UWin->TI_QuickMsg);
  2913.  
  2914. return;
  2915.  
  2916. }
  2917.  
  2918.  
  2919. void SendAMessage(APTR obj, ULONG to, char *msg, UWORD type, UBYTE both, int sendhow)
  2920.  
  2921. {
  2922.  
  2923. BOOL *auto_ch;
  2924.  
  2925. char tomsg[100], *c, url[1024], uinlog[MAXNAMLEN];
  2926.  
  2927. int len;
  2928.  
  2929. ULONG uin, index = 0;
  2930.  
  2931. UWORD length = 0;
  2932.  
  2933. UWORD status2;
  2934.  
  2935. struct AsyncFile *logfh = NULL;
  2936. struct Contact *user;
  2937. struct C_SendMessage SMsg;
  2938. struct ICQLog Log;
  2939. struct ICQMessage Msg;
  2940.  
  2941. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  2942. get(app->CY_MyStatus,MUIA_Cycle_Active,&index);
  2943.  
  2944. if (user = GetContact(to)) if (!user->UWin) if (!CreateUserWin(to)) user = NULL;
  2945.  
  2946. status2 = TCPCodes[index];
  2947.  
  2948. sprintf(tomsg,"Sent to: %s",GetNick(to));
  2949.  
  2950. if (!ARexx) msg = PreParseMsg(to,type,msg);
  2951.  
  2952. if (obj != app->BT_Auth) {
  2953.   if ((length = strlen(msg)+1) == 1) {
  2954.     if (user) set(user->UWin->TI_QuickMsg,MUIA_Textinput_Contents,NULL);
  2955.     set(app->TI_QuickMsg,MUIA_Textinput_Contents,NULL);
  2956.     return;
  2957.   }
  2958. //c = msg;
  2959. //while(c = strchr(c,'\n')) *c = ' ';
  2960. }
  2961. else length = 2;
  2962.  
  2963. if (both == MSG_BOTH || both == MSG_REMOTE) {
  2964.   SMsg.ToUIN = to;
  2965.   SMsg.Type = type;
  2966.   SMsg.Message = msg;
  2967.   Log.Cmd = Header.Command = C_SEND_MESSAGE;
  2968.   Log.Len = 0;
  2969.   Log.Pkt = NULL;
  2970.   if (sendhow == MSG_VIA_UDP || obj == app->BT_Auth) {
  2971.     len = UDP_CreatePacket(&Header,&SMsg,UDP_Buf);
  2972.     send_udp_pkt(UDP_Buf,len,uin);
  2973.     Log.Seq = Header.Sequence;
  2974.     Log.Se2 = Header.Sequence2;
  2975.     Log.Len = len;
  2976.     Log.Pkt = UDP_Buf;
  2977.   }
  2978.   else {
  2979.     if (SendTCPMessage(to,msg,TCP_MESSAGE,type,TCP_MSG_REAL,TCP_Seq,LINE,0x00000000,0x0000,0)) {
  2980.       Header.TCP_Sequence = Log.Seq = TCP_Seq;
  2981.       Header.Command = Log.Cmd = TCP_MESSAGE;
  2982.       Header.Sequence2 = 0;
  2983.       TCP_Seq--;
  2984.     }
  2985.     else {
  2986.       len = UDP_CreatePacket(&Header,&SMsg,UDP_Buf);
  2987.       send_udp_pkt(UDP_Buf,len,uin);
  2988.       Log.Seq = Header.Sequence;
  2989.       Log.Se2 = Header.Sequence2;
  2990.       Log.Len = len;
  2991.       Log.Pkt = UDP_Buf;
  2992.     }
  2993.   }
  2994.   Add2Log(LOG_CLIENT,&Header,FALSE,Log.Len,Log.Pkt);
  2995.   if (user) {
  2996.     user->LastMessageTo = time(NULL);
  2997.     user->Changed = TRUE;
  2998.   }
  2999. }
  3000.  
  3001. if (both == MSG_REMOTE) return;
  3002.  
  3003. Msg.Type = type;
  3004. Msg.Timehack = time(NULL);
  3005. Msg.UIN = uin;
  3006. Msg.Msg = msg;
  3007.  
  3008. sprintf(uinlog,"%sUsers/%ld/Logs/%ld",currentdir,uin,to);
  3009.  
  3010. get(app->CH_NoMsgLog,MUIA_Selected,&auto_ch);
  3011.  
  3012. if (!auto_ch) if (logfh = OpenAsync(uinlog,MODE_APPEND,AsyncBuf)) WriteLineAsync(logfh,ctime(&Msg.Timehack));
  3013.  
  3014. if (obj == app->BT_Auth || obj == user->UWin->BT_Auth) Msg.Msg = "Authorization to add to Contact List.";
  3015.  
  3016. if (type == 0x0004) {
  3017.   Msg.Type = 1;
  3018.   c = strchr(Msg.Msg,'\xFE');
  3019.   *c = '\0';
  3020.   DoMethod(app->LV_Msgs,MUIM_NList_InsertSingleWrap,&Msg,MUIV_NList_Insert_Bottom,WRAPCOL2,ALIGN_LEFT);
  3021.   if (user) DoMethod(user->UWin->LV_Msgs,MUIM_NList_InsertSingleWrap,&Msg,MUIV_NList_Insert_Bottom,WRAPCOL2,ALIGN_LEFT);
  3022.   if (logfh) {
  3023.     WriteLineAsync(logfh,"S: ");
  3024.     WriteLineAsync(logfh,Msg.Msg);
  3025.     WriteCharAsync(logfh,'\n');
  3026.   }
  3027.   Msg.Type = 4;
  3028.   sprintf(url,"\x1Bu%s",c+1);
  3029.   Msg.Msg = url;
  3030. }
  3031.  
  3032. DoMethod(app->LV_Msgs,MUIM_NList_InsertSingleWrap,&Msg,MUIV_NList_Insert_Bottom,WRAPCOL2,ALIGN_LEFT);
  3033. if (user) DoMethod(user->UWin->LV_Msgs,MUIM_NList_InsertSingleWrap,&Msg,MUIV_NList_Insert_Bottom,WRAPCOL2,ALIGN_LEFT);
  3034.  
  3035. if (logfh) {
  3036.   WriteLineAsync(logfh,"S: ");
  3037.   WriteLineAsync(logfh,Msg.Msg);
  3038.   WriteLineAsync(logfh,"\n\n");
  3039.   CloseAsync(logfh);
  3040.   SetComment(uinlog,GetNick(to));
  3041. }
  3042.  
  3043. Msg.UIN = 0;
  3044. Msg.Type = 1;
  3045. Msg.Msg = tomsg;
  3046.  
  3047. DoMethod(app->LV_Msgs,MUIM_NList_InsertSingleWrap,&Msg,MUIV_NList_Insert_Bottom,WRAPCOL2,ALIGN_LEFT);
  3048.  
  3049. Msg.Msg = LINE;
  3050.  
  3051. DoMethod(app->LV_Msgs,MUIM_NList_InsertSingleWrap,&Msg,MUIV_NList_Insert_Bottom,WRAPCOL2,ALIGN_LEFT);
  3052. if (user) DoMethod(user->UWin->LV_Msgs,MUIM_NList_InsertSingleWrap,&Msg,MUIV_NList_Insert_Bottom,WRAPCOL2,ALIGN_LEFT);
  3053.  
  3054. DoMethod(app->LV_Msgs,MUIM_NList_Jump,MUIV_NList_Jump_Bottom);
  3055. if (user) DoMethod(user->UWin->LV_Msgs,MUIM_NList_Jump,MUIV_NList_Jump_Bottom);
  3056.  
  3057. if (obj == app->TI_QuickMsg) set(app->TI_QuickMsg,MUIA_Textinput_Contents,NULL);
  3058. if (obj == user->UWin->TI_QuickMsg) set(user->UWin->TI_QuickMsg,MUIA_Textinput_Contents,NULL);
  3059.  
  3060. return;
  3061.  
  3062. }
  3063.  
  3064.  
  3065. void __asm GetUINInfo(REG(a2) APTR obj)
  3066.  
  3067. {
  3068.  
  3069. int len = 0;
  3070.  
  3071. ULONG uin, id = 0;
  3072.  
  3073. struct Contact *user;
  3074. struct C_Info_Req Info;
  3075. struct C_Meta Meta;
  3076. struct ICQMessage *msg;
  3077.  
  3078. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  3079.  
  3080. get(obj,MUIA_UserData,&id);
  3081.  
  3082. if (obj == app->BT_GetInfo3) {
  3083.   DoMethod(app->LV_SearchList,MUIM_NList_GetEntry,MUIV_NList_GetEntry_Active,&user);
  3084.   if (user) {
  3085.     Meta.Subcommand = META_REQ_INFO_1;
  3086.     Meta.UIN = Info.UIN = UserInfoReqID[1] = user->UIN;
  3087.     UserInfoReqID[0] = INFO_VIEW;
  3088.   }
  3089.   else {
  3090.     HandleError(DBG_OTH_INFO,"Select a Nick from the list first.");
  3091.     return;
  3092.   }
  3093. }
  3094. else {
  3095.   if (obj == app->BT_GetInfo) {
  3096.     DoMethod(app->LV_Msgs,MUIM_NList_GetEntry,MUIV_NList_GetEntry_Active,&msg);
  3097.     if (msg) {
  3098.       Meta.Subcommand = META_REQ_INFO_1;
  3099.       Meta.UIN = Info.UIN = UserInfoReqID[1] = msg->UIN;
  3100.       UserInfoReqID[0] = INFO_VIEW;
  3101.     }
  3102.     else {
  3103.       HandleError(DBG_OTH_INFO,"Select a message from the message list first.");
  3104.       return;
  3105.     }
  3106.   }
  3107.   else {
  3108.     if (obj == app->BT_GrabMyStats) {
  3109.       Meta.Subcommand = META_REQ_GRABME_1;
  3110.       Meta.UIN = Info.UIN = UserInfoReqID[1] = uin;
  3111.       UserInfoReqID[0] = INFO_GRABME;
  3112.     }
  3113.     else {
  3114.       if (obj == app->BT_AddUIN) {
  3115.         Meta.Subcommand = META_REQ_INFO_1;
  3116.         Meta.UIN = Info.UIN = UserInfoReqID[1] = id;
  3117.         UserInfoReqID[0] = INFO_VIEW;
  3118.       }
  3119.       else {
  3120.         Meta.Subcommand = META_REQ_INFO_1;
  3121.         Meta.UIN = Info.UIN = UserInfoReqID[1] = id;
  3122.         UserInfoReqID[0] = INFO_REFRESH;
  3123.       }
  3124.     }
  3125.   }
  3126. }
  3127.  
  3128. switch(Header.Version) {
  3129.   case 0x0002:
  3130.     Header.Command = C_INFO_REQ;
  3131.     Info.Sequence = UserInfoReqID[2] = info_seq;
  3132.     len = UDP_CreatePacket(&Header,&Info,UDP_Buf);
  3133.     info_seq = Info.Sequence;
  3134.     send_udp_pkt(UDP_Buf,len,uin);
  3135.     Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  3136.     Header.Command = C_EXT_INFO_REQ;
  3137.     Info.Sequence = extinfo_seq;
  3138.     len = UDP_CreatePacket(&Header,&Info,UDP_Buf);
  3139.     extinfo_seq = Info.Sequence;
  3140.     send_udp_pkt(UDP_Buf,len,uin);
  3141.     Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  3142.     break;
  3143.   case 0x0005:
  3144.     Header.Command = C_META;
  3145.     len = UDP_CreatePacket(&Header,&Meta,UDP_Buf);
  3146.     UserInfoReqID[2] = Header.Sequence;
  3147.     send_udp_pkt(UDP_Buf,len,uin);
  3148.     Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  3149.     break;
  3150. }
  3151.  
  3152. DoMethod(app->WI_Information,MUIM_MultiSet,MUIA_Text_Contents,NULL,app->STR_UserUIN,app->STR_UserEMail,app->STR_UserAuth,
  3153.   app->TX_UserCity,app->TX_UserCountry,app->TX_UserState,app->TX_UserAge,app->TX_UserSex,app->TX_UserPhone,app->TX_UserURL,NULL);
  3154.  
  3155. DoMethod(app->WI_Information,MUIM_MultiSet,MUIA_Textinput_Contents,NULL,app->STR_UserNick,app->STR_UserFirst,app->STR_UserLast,NULL);
  3156.  
  3157. set(app->NU_UserZone,MUIA_Numeric_Value,0);
  3158.  
  3159. DoMethod(app->LV_UserAbout,MUIM_NList_Clear);
  3160.  
  3161. return;
  3162.  
  3163. }
  3164.  
  3165.  
  3166. void __asm AddContact(REG(a2) APTR obj)
  3167.  
  3168. {
  3169.  
  3170. char *email, *nick, *first, *last;
  3171.  
  3172. int len;
  3173.  
  3174. BOOL *check;
  3175.  
  3176. ULONG uin = 0, localin = 0;
  3177.  
  3178. struct C_Info_Req Info;
  3179. struct C_Search_User Search;
  3180.  
  3181. set(app->WI_Searches,MUIA_Window_Open,FALSE);
  3182.  
  3183. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  3184. get(app->CH_SearchUIN,MUIA_Selected,&check);
  3185.  
  3186. if (check) {
  3187.   get(app->STR_SrchUIN,MUIA_Textinput_Integer,&localin);
  3188.   Header.Command = C_INFO_REQ;
  3189.   Info.Sequence = UserInfoReqID[2] = info_seq++;
  3190.   Info.UIN = UserInfoReqID[1] = localin;
  3191.   len = UDP_CreatePacket(&Header,&Info,UDP_Buf);
  3192.   send_udp_pkt(UDP_Buf,len,uin);
  3193.   Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  3194.   Header.Command = C_EXT_INFO_REQ;
  3195.   Info.Sequence = extinfo_seq++;
  3196.   len = UDP_CreatePacket(&Header,&Info,UDP_Buf);
  3197.   send_udp_pkt(UDP_Buf,len,uin);
  3198.   Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  3199.   DoMethod(app->WI_Information,MUIM_MultiSet,MUIA_Text_Contents,NULL,app->STR_UserUIN,app->STR_UserEMail,app->STR_UserAuth,
  3200.     app->TX_UserCity,app->TX_UserCountry,app->TX_UserState,app->TX_UserAge,app->TX_UserSex,app->TX_UserPhone,app->TX_UserURL,NULL);
  3201.   DoMethod(app->WI_Information,MUIM_MultiSet,MUIA_Textinput_Contents,NULL,app->STR_UserNick,app->STR_UserFirst,app->STR_UserLast,NULL);
  3202.   DoMethod(app->LV_UserAbout,MUIM_NList_Clear);
  3203.   UserInfoReqID[0] = INFO_VIEW;
  3204.   return;
  3205. }
  3206.  
  3207. email = nick = first = last = "";
  3208.  
  3209. get(app->CH_SearchEMail,MUIA_Selected,&check);
  3210.  
  3211. if (check) get(app->STR_SrchEMail,MUIA_Textinput_Contents,&email);
  3212.  
  3213. get(app->CH_SearchName,MUIA_Selected,&check);
  3214.  
  3215. if (check) {
  3216.   get(app->STR_SrchNick,MUIA_Textinput_Contents,&nick);
  3217.   get(app->STR_SrchFirst,MUIA_Textinput_Contents,&first);
  3218.   get(app->STR_SrchLast,MUIA_Textinput_Contents,&last);
  3219. }
  3220.  
  3221. Header.Command = C_SEARCH_USER;
  3222.  
  3223. Search.Sequence = srch_seq++;
  3224.  
  3225. strcpy(Search.Nick,nick);
  3226. strcpy(Search.First,first);
  3227. strcpy(Search.Last,last);
  3228. strcpy(Search.EMail,email);
  3229.  
  3230. len = UDP_CreatePacket(&Header,&Search,UDP_Buf);
  3231.  
  3232. send_udp_pkt(UDP_Buf,len,uin);
  3233.  
  3234. DoMethod(app->LV_SearchList,MUIM_NList_Clear);
  3235.  
  3236. found = 0;
  3237.  
  3238. set(app->TX_SearchStat,MUIA_Text_Contents,"Searching...");
  3239. set(app->WI_SrchResults,MUIA_Window_Open,TRUE);
  3240.  
  3241. Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  3242.  
  3243. return;
  3244.  
  3245. }
  3246.  
  3247.  
  3248. void __asm AddUpdate(REG(a2) APTR obj)
  3249.  
  3250. {
  3251.  
  3252. BOOL flag = FALSE, seeinvis, newmsg, beinvis;
  3253.  
  3254. char *uin, *auth, *tmp1;
  3255. char nick[50], first[50], last[50], email[50], cmnt[256], about[512];
  3256.  
  3257. int i, len;
  3258.  
  3259. LONG zone, line = -1;
  3260.  
  3261. ULONG total, localin = 0, stat = STATUS_OFFLINE, ip, port, realip, tmp2;
  3262.  
  3263. struct Contact User, *user;
  3264. struct C_ContactList CList;
  3265. struct MUI_NList_GetEntryInfo res;
  3266. struct FileWin *FWin = NULL;
  3267. struct UserWindow *UWin = NULL;
  3268.  
  3269. PrepNewContact(&User);
  3270.  
  3271. cmnt[0] = '\0';
  3272.  
  3273. ip = port = realip = 0;
  3274.  
  3275. beinvis = seeinvis = newmsg = FALSE;
  3276.  
  3277. if (obj == app->BT_AddUpdate2) {
  3278.   DoMethod(app->LV_SearchList,MUIM_NList_GetEntry,MUIV_NList_GetEntry_Active,&user);
  3279.   if (user) {
  3280.     User.UIN = user->UIN;
  3281.     strcpy(nick,user->Nick);
  3282.     User.Nick = nick;
  3283.     strcpy(first,user->First);
  3284.     User.First = first;
  3285.     strcpy(last,user->Last);
  3286.     User.Last = last;
  3287.     strcpy(email,user->EMail);
  3288.     User.EMail = email;
  3289.     User.Authorize = user->Authorize;
  3290.     ip = user->IP;
  3291.     port = user->Port;
  3292.     realip = user->RealIP;
  3293.     stat = user->Status;
  3294.     seeinvis = user->SeeInvis;
  3295.     beinvis = user->BeInvis;
  3296.     User.City = User.State = User.Phone = User.HomePage = User.About = User.Comment = NULL;
  3297.     User.Country = User.Age = 0xffff;
  3298.     User.Sex = 0x00;
  3299.   }
  3300.   else {
  3301.     HandleError(DBG_OTH_INFO,"Select a Nick from the Search Results List first.");
  3302.     return;
  3303.   }
  3304. }
  3305. else {
  3306.   get(app->STR_UserUIN,MUIA_Text_Contents,&uin);
  3307.   if (!uin) return;
  3308.   StrToLong(uin,(LONG *)&User.UIN);
  3309.   get(app->STR_UserNick,MUIA_Textinput_Contents,&User.Nick);
  3310.   get(app->STR_UserFirst,MUIA_Textinput_Contents,&User.First);
  3311.   get(app->STR_UserLast,MUIA_Textinput_Contents,&User.Last);
  3312.   get(app->STR_UserEMail,MUIA_Text_Contents,&User.EMail);
  3313.   get(app->STR_UserAuth,MUIA_Text_Contents,&auth);
  3314.   if (!strcmp(auth,"Yes")) User.Authorize = 0x00;
  3315.   else User.Authorize = 0x01;
  3316.   get(app->TX_UserCity,MUIA_Text_Contents,&User.City);
  3317.   get(app->TX_UserCountry,MUIA_Text_Contents,&tmp1);
  3318.   if (!strcmp(tmp1,"Unspecified")) tmp2 = 0xffff;          // Enforcer hits here if Ext. pkt does not come in...
  3319.   else StrToLong(tmp1,(LONG *)&tmp2);
  3320.   User.Country = tmp2;
  3321.   get(app->NU_UserZone,MUIA_Numeric_Value,&zone);
  3322.   User.TimeZone = zone;
  3323.   get(app->TX_UserState,MUIA_Text_Contents,&User.State);
  3324.   get(app->TX_UserAge,MUIA_Text_Contents,&tmp1);
  3325.   if (!strcmp(tmp1,"Unspecified")) tmp2 = 0xffff;
  3326.   else StrToLong(tmp1,(LONG *)&tmp2);
  3327.   User.Age = tmp2;
  3328.   get(app->TX_UserSex,MUIA_Text_Contents,&tmp1);
  3329.   if (!strcmp(tmp1,"Unspecified")) tmp2 = 0x00;
  3330.   else {
  3331.     if (!strcmp(tmp1,"Female")) tmp2 = 0x01;
  3332.     else tmp2 = 0x02;
  3333.   }
  3334.   User.Sex = tmp2;
  3335.   get(app->TX_UserPhone,MUIA_Text_Contents,&User.Phone);
  3336.   get(app->TX_UserURL,MUIA_Text_Contents,&User.HomePage);
  3337.   get(app->LV_UserAbout,MUIA_NList_Entries,&total);
  3338.   about[0] = '\0';
  3339.   for(i = 0; i < total; i++) {
  3340.     res.pos = i;
  3341.     DoMethod(app->LV_UserAbout,MUIM_NList_GetEntryInfo,&res);
  3342.     if (res.line == line) continue;
  3343.     strcat(about,(char *)res.entry);
  3344.     strcat(about,"\r\n");
  3345.     line = res.line;
  3346.   }
  3347.   User.About = about;
  3348.   User.Comment = NULL;
  3349. }
  3350.  
  3351. get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  3352.  
  3353. for(i = 0; i<total; i++) {
  3354.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  3355.   if (user) {
  3356.     if (user->UIN == User.UIN) {
  3357.       stat = user->Status;
  3358.       ip = user->IP;
  3359.       port = user->Port;
  3360.       realip = user->RealIP;
  3361.       if (user->Comment) strcpy(cmnt,user->Comment);
  3362.       User.Comment = cmnt;
  3363.       if (user->UWin) {
  3364.         user->UWin->DoNotDelete = TRUE;
  3365.         UWin = user->UWin;
  3366.       }
  3367.       if (user->FWin) {
  3368.         user->FWin->DoNotDelete = TRUE;
  3369.         FWin = user->FWin;
  3370.       }
  3371.       DoMethod(app->LV_OfflineList,MUIM_NList_Remove,i);
  3372.       if (user->Status != STATUS_NEWUIN) flag = TRUE;
  3373.       else stat = STATUS_OFFLINE;
  3374.       seeinvis = user->SeeInvis;
  3375.       beinvis = user->BeInvis;
  3376.       newmsg = user->NewMsg;
  3377.       break;
  3378.     }
  3379.   }
  3380. }
  3381.  
  3382. User.IP = ip;
  3383. User.Port = port;
  3384. User.RealIP = realip;
  3385. User.Status = stat;
  3386.  
  3387. User.SeeInvis = seeinvis;
  3388. User.BeInvis = beinvis;
  3389. User.NewMsg = newmsg;
  3390. User.UWin = NULL;
  3391.  
  3392. if (strlen(User.First) == 0) User.First = LINE;
  3393. if (strlen(User.Last)  == 0) User.Last  = LINE;
  3394. if (strlen(User.EMail) == 0) User.EMail = LINE;
  3395. if (strlen(User.Nick)  == 0) User.Nick  = User.First;
  3396.  
  3397. if (UWin) User.UWin = UWin;
  3398. if (FWin) User.FWin = FWin;
  3399.  
  3400. AddUser2CList(&User);
  3401.  
  3402. DoMethod(app->LV_OfflineList,MUIM_NList_Sort);
  3403.  
  3404. UpdateUserWin(GetContact(User.UIN));
  3405. SaveContact(User.UIN);
  3406.  
  3407. if (!flag) {
  3408.   get(app->STR_ICQUIN,MUIA_String_Integer,&localin);
  3409.   Header.Command = C_CONTACT_LIST;
  3410.   CList.UIN_Count = 1;
  3411.   CList.UIN[0] = User.UIN;
  3412.   len = UDP_CreatePacket(&Header,&CList,UDP_Buf);
  3413.   send_udp_pkt(UDP_Buf,len,localin);
  3414.   Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  3415.   sprintf(maintitle,"STRICQ (%d)",++contacts_cnt);
  3416.   set(app->WI_Main,MUIA_Window_Title,maintitle);
  3417. }
  3418.  
  3419. return;
  3420.  
  3421. }
  3422.  
  3423.  
  3424. void SendContacts(ULONG uin, UWORD cmd)
  3425.  
  3426. {
  3427.  
  3428. int len = 0, i;
  3429.  
  3430. ULONG total = 0;
  3431.  
  3432. struct Contact *user;
  3433. struct C_ContactList CList;
  3434.  
  3435. get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  3436.  
  3437. Header.Command = cmd;
  3438.  
  3439. for(CList.UIN_Count = i = 0; i<total; i++) {
  3440.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  3441.   if (user) {
  3442.     if (user->Status != STATUS_NEWUIN) {
  3443.       switch(cmd) {
  3444.         case C_CONTACT_LIST:
  3445.           CList.UIN[CList.UIN_Count++] = user->UIN;
  3446.           break;
  3447.         case C_VIS_LIST:
  3448.           if (user->SeeInvis) CList.UIN[CList.UIN_Count++] = user->UIN;
  3449.           break;
  3450.         case C_INVIS_LIST:
  3451.           if (user->BeInvis) CList.UIN[CList.UIN_Count++] = user->UIN;
  3452.           break;
  3453.       }
  3454.     }
  3455.     if (CList.UIN_Count == MAX_CONTACTS_PKT) {
  3456.       len = UDP_CreatePacket(&Header,&CList,UDP_Buf);
  3457.       Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  3458.       Delay(5);
  3459.       send_udp_pkt(UDP_Buf,len,uin);
  3460.       CList.UIN_Count = 0;
  3461.     }
  3462.   }
  3463. }
  3464.  
  3465. if (CList.UIN_Count > 0) {
  3466.   len = UDP_CreatePacket(&Header,&CList,UDP_Buf);
  3467.   Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  3468.   Delay(5);
  3469.   send_udp_pkt(UDP_Buf,len,uin);
  3470. }
  3471.  
  3472. return;
  3473.  
  3474. }
  3475.  
  3476.  
  3477. void __asm ChangePW(REG(a2) APTR obj)
  3478.  
  3479. {
  3480.  
  3481. char *pw;
  3482.  
  3483. int len;
  3484.  
  3485. ULONG uin = 0;
  3486.  
  3487. struct C_ChangePassword Pass;
  3488.  
  3489. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  3490. get(app->STR_ICQPass,MUIA_String_Contents,&pw);
  3491.  
  3492. Header.Command = C_CHANGE_PASSWORD;
  3493.  
  3494. Pass.Sequence = pw_seq++;
  3495.  
  3496. strcpy(Pass.Password,pw);
  3497.  
  3498. len = UDP_CreatePacket(&Header,&Pass,UDP_Buf);
  3499.  
  3500. send_udp_pkt(UDP_Buf,len,uin);
  3501.  
  3502. Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  3503.  
  3504. return;
  3505.  
  3506. }
  3507.  
  3508.  
  3509. void __asm SetQuickTo(REG(a2) APTR obj)
  3510.  
  3511. {
  3512.  
  3513. char mesg[100], nick[100];
  3514.  
  3515. int i;
  3516.  
  3517. LONG entry = 0, total = 0;
  3518.  
  3519. struct Contact *user;
  3520. struct ICQMessage *msg;
  3521.  
  3522. get(app->LV_Msgs,MUIA_NList_EntryClick,&entry);
  3523.  
  3524. if (entry < 0) return;
  3525.  
  3526. DoMethod(app->LV_Msgs,MUIM_NList_GetEntry,entry,&msg);
  3527.  
  3528. if (msg->UIN == 0 || msg->UIN == 10) return;
  3529.  
  3530. get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  3531.  
  3532. for(i = 0; i<total; i++) {
  3533.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  3534.   if (user) {
  3535.     if (user->UIN == msg->UIN) {
  3536.       strcpy(nick,user->Nick);
  3537.       sprintf(mesg,"%ld %s",user->UIN,nick);
  3538.       set(app->TX_QuickTo,MUIA_Text_Contents,mesg);
  3539.       return;
  3540.     }
  3541.   }
  3542. }
  3543.  
  3544. sprintf(mesg,"%ld",msg->UIN);
  3545. set(app->TX_QuickTo,MUIA_Text_Contents,mesg);
  3546.  
  3547. return;
  3548.  
  3549. }
  3550.  
  3551.  
  3552. void __asm ChangeMyStatus(REG(a2) APTR obj)
  3553.  
  3554. {
  3555.  
  3556. BOOL *opts;
  3557.  
  3558. int len;
  3559.  
  3560. LONG index = 0;
  3561.  
  3562. ULONG uin = 0;
  3563.  
  3564. struct C_StatusChange Status;
  3565.  
  3566. get(app->CY_MyStatus,MUIA_Cycle_Active,&index);
  3567.  
  3568. if (Codes[index] == STATUS_OFFLINE) {
  3569.   if (Online) DisconnectICQ(NULL);
  3570.   set(app->TX_Color,MUIA_Text_Contents,"Offline");
  3571.   return;
  3572. }
  3573.  
  3574. if (Codes[index] != STATUS_OFFLINE && !Online) {
  3575.   ConnectICQ(NULL);
  3576.   return;
  3577. }
  3578.  
  3579. Status.Status = Codes[index];
  3580.  
  3581. get(app->CH_WebPresence,MUIA_Selected,&opts);
  3582.  
  3583. if (opts) Status.Status |= STATUSF_WEBPRESENCE;
  3584.  
  3585. get(app->CH_HideIP,MUIA_Selected,&opts);
  3586.  
  3587. if (opts) Status.Status |= STATUSF_HIDEIP;
  3588.  
  3589. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  3590.  
  3591. Header.Command = C_STATUS_CHANGE;
  3592.  
  3593. len = UDP_CreatePacket(&Header,&Status,UDP_Buf);
  3594.  
  3595. send_udp_pkt(UDP_Buf,len,uin);
  3596.  
  3597. Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  3598.  
  3599. return;
  3600.  
  3601. }
  3602.  
  3603.  
  3604. void __asm SavePrefs(REG(a2) APTR obj)
  3605.  
  3606. {
  3607.  
  3608. char line[1024], *line_p, *nick, *uinstr;
  3609.  
  3610. int i;
  3611.  
  3612. LONG total = 0;
  3613.  
  3614. UWORD length = 0;
  3615.  
  3616. struct AsyncFile *loadfh;
  3617. struct Column  *col;
  3618. struct MUI_PenSpec *startpen = NULL;
  3619. struct IgnoreUIN *ignore;
  3620.  
  3621. get(app->STR_ICQUIN,MUIA_String_Contents,&uinstr);
  3622.  
  3623. MakeFilenames(NULL);
  3624.  
  3625. sprintf(line,"%sUsers/%s",currentdir,uinstr);
  3626.  
  3627. MyCreateDir(logdir_fl);
  3628. MyCreateDir(userdir_fl);
  3629.  
  3630. get(app->STR_Nick,MUIA_String_Contents,&nick);
  3631. SetComment(line,nick);
  3632.  
  3633. if (loadfh = OpenAsync(colors_fl,MODE_WRITE,AsyncBuf)) {
  3634.   for(i = 0; i < 8; i++) {
  3635.     get(app->PP_StatusColors[i],MUIA_Pendisplay_Spec,&startpen);
  3636.     WriteAsync(loadfh,startpen,sizeof(struct MUI_PenSpec));
  3637.   }
  3638.   WriteAsync(loadfh,&URLMsg_cnt,sizeof(URLMsg_cnt));
  3639.   get(app->TI_About,MUIA_Textinput_Contents,&line_p);
  3640.   length = strlen(line_p)+1;
  3641.   WriteAsync(loadfh,&length,sizeof(length));
  3642.   WriteAsync(loadfh,line_p,length);
  3643.   WriteAsync(loadfh,&SrvrMsg_cnt,sizeof(SrvrMsg_cnt));
  3644.   for(i = 8; i < NUM_STATUS_COLORS; i++) {
  3645.     get(app->PP_StatusColors[i],MUIA_Pendisplay_Spec,&startpen);
  3646.     WriteAsync(loadfh,startpen,sizeof(struct MUI_PenSpec));
  3647.   }
  3648.   for(i = 0; i < NUM_CHAT_COLORS; i++) {
  3649.     get(app->PP_ChatColors[i],MUIA_Pendisplay_Spec,&startpen);
  3650.     WriteAsync(loadfh,startpen,sizeof(struct MUI_PenSpec));
  3651.   }
  3652.   CloseAsync(loadfh);
  3653. }
  3654.  
  3655.  
  3656. if (loadfh = OpenAsync(server_fl,MODE_WRITE,AsyncBuf)) {
  3657.   get(app->LV_ICQServers,MUIA_NList_Entries,&total);
  3658.   for(i = 0; i<total; i++) {
  3659.     DoMethod(app->LV_ICQServers,MUIM_NList_GetEntry,i,&line_p);
  3660.     if (line) {
  3661.       sprintf(line,"%s\n",line_p);
  3662.       WriteLineAsync(loadfh,line);
  3663.     }
  3664.   }
  3665.   WriteLineAsync(loadfh,";\n");
  3666.   get(app->LV_ColsStore,MUIA_NList_Entries,&total);
  3667.   for(i = 0; i<total; i++) {
  3668.     DoMethod(app->LV_ColsStore,MUIM_NList_GetEntry,i,&col);
  3669.     if (col) {
  3670.       sprintf(line,"%s\n%s\n",col->Name,col->COL);
  3671.       WriteLineAsync(loadfh,line);
  3672.     }
  3673.   }
  3674.   WriteLineAsync(loadfh,";\n");
  3675.   get(app->LV_ColsUse,MUIA_NList_Entries,&total);
  3676.   for(i = 0; i<total; i++) {
  3677.     DoMethod(app->LV_ColsUse,MUIM_NList_GetEntry,i,&col);
  3678.     if (col) {
  3679.       sprintf(line,"%s\n%s\n",col->Name,col->COL);
  3680.       WriteLineAsync(loadfh,line);
  3681.     }
  3682.   }
  3683.   WriteLineAsync(loadfh,";\n");
  3684.   get(app->LV_IgnoreUIN,MUIA_NList_Entries,&total);
  3685.   for(i = 0; i<total; i++) {
  3686.     DoMethod(app->LV_IgnoreUIN,MUIM_NList_GetEntry,i,&ignore);
  3687.     if (ignore) {
  3688.       sprintf(line,"%ld\n%s\n%ld\n%ld\n",ignore->UIN,ignore->Nick,ignore->Timehack,ignore->ExpireDays);
  3689.       WriteLineAsync(loadfh,line);
  3690.     }
  3691.   }
  3692.   WriteLineAsync(loadfh,";\n");
  3693.   CloseAsync(loadfh);
  3694. }
  3695.  
  3696. DoMethod(app->App,MUIM_Application_Save,config_fl);
  3697.  
  3698. if (loadfh = OpenAsync(lastuser_fl,MODE_WRITE,AsyncBuf)) {
  3699.   WriteAsync(loadfh,uinstr,strlen(uinstr));
  3700.   WriteCharAsync(loadfh,'\n');
  3701.   CloseAsync(loadfh);
  3702. }
  3703.  
  3704. DoMethod(app->DL_UINList,MUIM_Dirlist_ReRead);
  3705.  
  3706. SaveAllContacts();
  3707.  
  3708. return;
  3709.  
  3710. }
  3711.  
  3712.  
  3713. ULONG __asm ColorDispatcher(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg)
  3714.  
  3715. {
  3716.  
  3717. switch(msg->MethodID) {
  3718.   case OM_SET:
  3719.     return(COLOR_Set(cl,obj,(APTR)msg));
  3720.   case MUIM_Setup:
  3721.     return(COLOR_Setup(cl,obj,(APTR)msg));
  3722.   case MUIM_Cleanup:
  3723.     return(COLOR_Cleanup(cl,obj,(APTR)msg));
  3724.   case MUIM_Draw:
  3725.     return(COLOR_Draw(cl,obj,(APTR)msg));
  3726. }
  3727.  
  3728. return(DoSuperMethodA(cl,obj,msg));
  3729.  
  3730. }
  3731.  
  3732.  
  3733. ULONG COLOR_Set(struct IClass *cl, Object *obj, Msg msg)
  3734.  
  3735. {
  3736.  
  3737. struct ColorData *data = INST_DATA(cl,obj);
  3738. struct TagItem *tags, *tag;
  3739.  
  3740. //printf("COLOR_Set()\n");
  3741.  
  3742. for(tags = ((struct opSet *)msg)->ops_AttrList; tag = NextTagItem(&tags); ) {
  3743.   if ((tag->ti_Tag-TAG_USER) >= 0 && (tag->ti_Tag-TAG_USER) < NUM_STATUS_COLORS) {
  3744. //  printf("(tag->ti_Tag-TAG_USER) = %ld\n",(tag->ti_Tag-TAG_USER));
  3745.     data->StatusPens[(tag->ti_Tag-TAG_USER)] = *((struct MUI_PenSpec *)tag->ti_Data);
  3746.     data->ChangedPen[(tag->ti_Tag-TAG_USER)] = TRUE;
  3747.     MUI_Redraw(obj,MADF_DRAWOBJECT);
  3748.   }
  3749.   if ((tag->ti_Tag-100-TAG_USER) >= 0 && (tag->ti_Tag-100-TAG_USER) < NUM_CHAT_COLORS) {
  3750. //  printf("(tag->ti_Tag-100-TAG_USER) = %ld\n",(tag->ti_Tag-100-TAG_USER));
  3751.     data->ChatPens[(tag->ti_Tag-100-TAG_USER)] = *((struct MUI_PenSpec *)tag->ti_Data);
  3752.     data->ChangedChat[(tag->ti_Tag-100-TAG_USER)] = TRUE;
  3753.     MUI_Redraw(obj,MADF_DRAWOBJECT);
  3754.   }
  3755. }
  3756.  
  3757. return(DoSuperMethodA(cl,obj,msg));
  3758.  
  3759. }
  3760.  
  3761.  
  3762. ULONG COLOR_Setup(struct IClass *cl, Object *obj, Msg msg)
  3763.  
  3764. {
  3765.  
  3766. int i;
  3767.  
  3768. struct ColorData *data = INST_DATA(cl,obj);
  3769.  
  3770. //printf("COLOR_Setup()\n");
  3771.  
  3772. if (!DoSuperMethodA(cl,obj,msg)) return(FALSE);
  3773.  
  3774. for(i = 0; i < NUM_STATUS_COLORS; i++) {
  3775.   Pens.StatusColors[i] = MUI_ObtainPen(muiRenderInfo(obj),&data->StatusPens[i],0);
  3776. //printf("Pens.StatusColors[%d] = %ld\n",i,Pens.StatusColors[i]);
  3777. }
  3778.  
  3779. for(i = 0; i < NUM_CHAT_COLORS; i++) {
  3780.   Pens.ChatColors[i] = MUI_ObtainPen(muiRenderInfo(obj),&data->ChatPens[i],0);
  3781. //printf("Pens.ChatColors[%d] = %ld\n",i,Pens.ChatColors[i]);
  3782. }
  3783.  
  3784. return(TRUE);
  3785.  
  3786. }
  3787.  
  3788.  
  3789. ULONG COLOR_Cleanup(struct IClass *cl, Object *obj, Msg msg)
  3790.  
  3791. {
  3792.  
  3793. int i;
  3794.  
  3795. //struct ColorData *data = INST_DATA(cl,obj);
  3796.  
  3797. //printf("COLOR_Cleanup()\n");
  3798.  
  3799. for(i = 0; i < NUM_STATUS_COLORS; i++) MUI_ReleasePen(muiRenderInfo(obj),Pens.StatusColors[i]);
  3800.  
  3801. for(i = 0; i < NUM_CHAT_COLORS; i++) MUI_ReleasePen(muiRenderInfo(obj),Pens.ChatColors[i]);
  3802.  
  3803. return(DoSuperMethodA(cl,obj,msg));
  3804.  
  3805. }
  3806.  
  3807.  
  3808. ULONG COLOR_Draw(struct IClass *cl, Object *obj, struct MUIP_Draw *msg)
  3809.  
  3810. {
  3811.  
  3812. BOOL flag = TRUE;
  3813.  
  3814. int i;
  3815.  
  3816. struct ColorData *data = INST_DATA(cl,obj);
  3817.  
  3818. //printf("COLOR_Draw()\n");
  3819.  
  3820. DoSuperMethodA(cl,obj,(Msg)msg);
  3821.  
  3822. if (!(msg->flags & MADF_DRAWOBJECT)) return(FALSE);
  3823.  
  3824. for(i = 0; i < NUM_STATUS_COLORS; i++) {
  3825.   if (data->ChangedPen[i]) {
  3826.     flag = data->ChangedPen[i] = FALSE;
  3827.     MUI_ReleasePen(muiRenderInfo(obj),Pens.StatusColors[i]);
  3828.     Pens.StatusColors[i] = MUI_ObtainPen(muiRenderInfo(obj),&data->StatusPens[i],0);
  3829. //  printf("Pens.StatusColors[%d] = %ld\n",i,Pens.StatusColors[i]);
  3830.   }
  3831. }
  3832.  
  3833. for(i = 0; i < NUM_CHAT_COLORS; i++) {
  3834.   if (data->ChangedChat[i]) {
  3835.     data->ChangedChat[i] = FALSE;
  3836.     MUI_ReleasePen(muiRenderInfo(obj),Pens.ChatColors[i]);
  3837.     Pens.ChatColors[i] = MUI_ObtainPen(muiRenderInfo(obj),&data->ChatPens[i],0);
  3838. //  printf("Pens.ChatColors[%d] = %ld\n",i,Pens.ChatColors[i]);
  3839.   }
  3840. }
  3841.  
  3842. if (!flag) DoMethod(app->LV_OfflineList,MUIM_NList_Redraw,MUIV_NList_Redraw_All);
  3843.  
  3844. return(FALSE);
  3845.  
  3846. }
  3847.  
  3848.  
  3849. void ParseMessage(UWORD cmd, char *buf, ULONG uin, UWORD type)
  3850.  
  3851. {
  3852.  
  3853. BOOL *iconic = NULL;
  3854.  
  3855. char mesg[200], nick[100], *c, *quickmsg, url[1024];
  3856.  
  3857. int i;
  3858.  
  3859. LONG total;
  3860.  
  3861. struct Contact *user, User;
  3862. struct ICQMessage msg;
  3863.  
  3864. if (uin != 10) {
  3865.   if (!(user = GetContact(uin))) {
  3866.     PrepNewContact(&User);
  3867.     User.UIN = uin;
  3868.     sprintf(nick,"%ld",uin);
  3869.     User.Nick = nick;
  3870.     User.Status = STATUS_NEWUIN;
  3871.     AddUser2CList(&User);
  3872.     user = GetContact(uin);
  3873.   }
  3874. }
  3875. else user = NULL;
  3876.  
  3877. get(app->App,MUIA_Application_Iconified,&iconic);
  3878.  
  3879. if (iconic) set(app->App,MUIA_Application_Iconified,FALSE);
  3880.  
  3881. msg.UIN = uin;
  3882. msg.Type = type;
  3883. msg.Timehack = time(NULL);
  3884.  
  3885. user->LastMessageFm = time(NULL);
  3886. user->Changed = TRUE;
  3887.  
  3888. SendMessage2Script(buf,uin,type);
  3889.  
  3890. if (user) {
  3891.   if (user->UWin) {
  3892.     set(user->UWin->RG_UserPages,MUIA_Group_ActivePage,0);
  3893.     set(user->UWin->WI_UserWindow,MUIA_Window_ActiveObject,user->UWin->TI_QuickMsg);
  3894.   }
  3895. }
  3896.  
  3897. switch(type) {
  3898.   case MSG_MSG:
  3899.   case MSG_CHAT:
  3900.   case MSG_FILE: {
  3901.     struct MSG_Message Message;
  3902.     MSG_ParseMessage(type,buf,&Message);
  3903.     msg.Msg = Message.Message;
  3904.     for(c = msg.Msg; *c; c++) if (*c == '\n' || *c == '\r') *c = ' ';
  3905.     break;
  3906.   }
  3907.   case MSG_URL: {
  3908.     struct MSG_URLDesc URL;
  3909.     MSG_ParseMessage(type,buf,&URL);
  3910.     msg.Type = 1;
  3911.     msg.Msg = URL.Desc;
  3912.     StoreMessage(&msg,uin,cmd);
  3913.     msg.Timehack = 0;
  3914.     msg.Type = 4;
  3915.     sprintf(url,"\x1Bu%s",URL.URL);
  3916.     msg.Msg = url;
  3917.     break;
  3918.   }
  3919.   case MSG_REQ_AUTH: {
  3920.     struct MSG_Common ReqAuth;
  3921.     MSG_ParseMessage(type,buf,&ReqAuth);
  3922.     sprintf(url,"%s (%s %s) Requests your Authorization to add you to his/her Contact List.  Reason:  \033b%s\033n",ReqAuth.Nick,ReqAuth.First,ReqAuth.Last,ReqAuth.Message);
  3923.     msg.Msg = url;
  3924.     break;
  3925.   }
  3926.   case MSG_GIVE_AUTH:
  3927.     msg.Msg = "Authorizes you to add him/her to your Contact List.";
  3928.     break;
  3929.   case MSG_ADDED: {
  3930.     struct MSG_Common Added;
  3931.     MSG_ParseMessage(type,buf,&Added);
  3932.     sprintf(url,"You have been added to %s's (%s %s) Contact List.",Added.Nick,Added.First,Added.Last);
  3933.     msg.Msg = url;
  3934.     break;
  3935.   }
  3936.   case MSG_WEB_PAGER:
  3937.   case MSG_EMAIL_PAGER: {
  3938.     struct MSG_Common Pager;
  3939.     if (uin != 10) HandleError(DBG_OTH_INFO,"Pager msg has uin = %ld",uin);
  3940.     MSG_ParseMessage(type,buf,&Pager);
  3941.     set(app->TX_WebName,MUIA_Text_Contents,Pager.Nick);
  3942.     set(app->TX_WebEMail,MUIA_Text_Contents,Pager.EMail);
  3943.     DoMethod(app->LV_WebMsg,MUIM_NList_InsertWrap,Pager.Message,-2,MUIV_NList_Insert_Bottom,WRAPCOL0,ALIGN_LEFT);
  3944.     set(app->WI_WebPager,MUIA_Window_Open,TRUE);
  3945.     return;
  3946.   }
  3947.   case MSG_ADDUIN: {
  3948.     struct MSG_AddUIN AddUIN;
  3949.     char desc[100];
  3950.     int i;
  3951.     AddUIN.Total = 0;
  3952.     AddUIN.Next = NULL;
  3953.     DoMethod(app->LV_ToAddUIN,MUIM_NList_Clear);
  3954.     MSG_ParseMessage(type,buf,&AddUIN);
  3955.     for(i = 0; i < AddUIN.Total; i++) {
  3956.       DoMethod(app->LV_ToAddUIN,MUIM_NList_InsertSingle,&AddUIN,MUIV_NList_Insert_Sorted);
  3957.       if (i < AddUIN.Total-1) MSG_ParseMessage(type,AddUIN.Next,&AddUIN);
  3958.     }
  3959.     sprintf(desc,"New UIN(s) Received From %s",GetNick(uin));
  3960.     set(app->TX_Desc,MUIA_Text_Contents,desc);
  3961.     set(app->WI_AddUIN,MUIA_Window_ActiveObject,app->BT_AddUIN);
  3962.     set(app->WI_AddUIN,MUIA_Window_Open,TRUE);
  3963.     return;
  3964.   }
  3965. }
  3966.  
  3967. StoreMessage(&msg,uin,cmd);
  3968.  
  3969. msg.UIN = msg.Timehack = msg.Type = 0;
  3970. msg.Msg = LINE;
  3971. StoreMessage(&msg,uin,cmd);
  3972.  
  3973. get(app->TI_QuickMsg,MUIA_Textinput_Contents,&quickmsg);
  3974.  
  3975. if (!strlen(quickmsg)) {
  3976.   set(app->LV_Msgs,MUIA_NList_Active,MUIV_NList_Active_Bottom);
  3977.   set(app->LV_Msgs,MUIA_NList_Active,MUIV_NList_Active_Up);
  3978.   get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  3979.   for(i = 0; i<total; i++) {
  3980.     DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  3981.     if (user) {
  3982.       if (user->UIN == uin) {
  3983.         strcpy(nick,user->Nick);
  3984.         sprintf(mesg,"%ld %s",user->UIN,nick);
  3985.         set(app->TX_QuickTo,MUIA_Text_Contents,mesg);
  3986.         if (user->Status == STATUS_OFFLINE && (cmd == S_GET_MESSAGE || cmd == TCP_MESSAGE)) {
  3987.           user->Status = STATUS_ONLINE|STATUSF_INVISIBLE;
  3988.           if (user->UWin) {
  3989.             strcpy(user->UWin->Status,"Invisible");
  3990.             sprintf(user->UWin->Title,"%ld %s (%s)",user->UIN,user->Nick,user->UWin->Status);
  3991.             set(user->UWin->WI_UserWindow,MUIA_Window_Title,user->UWin->Title);
  3992.           }
  3993.           DoMethod(app->LV_OfflineList,MUIM_NList_Redraw,i);
  3994.           DoMethod(app->LV_OfflineList,MUIM_NList_Sort);
  3995.         }
  3996.         break;
  3997.       }
  3998.     }
  3999.   }
  4000.   if (i == total) {
  4001.     sprintf(mesg,"%ld",uin);
  4002.     set(app->TX_QuickTo,MUIA_Text_Contents,mesg);
  4003.   }
  4004.   set(app->WI_Message,MUIA_Window_ActiveObject,app->TI_QuickMsg);
  4005. }
  4006. else {
  4007.   get(app->LV_Msgs,MUIA_NList_Active,&total);
  4008.   set(app->LV_Msgs,MUIA_NList_Active,MUIV_NList_Active_Bottom);
  4009.   set(app->LV_Msgs,MUIA_NList_Active,total);
  4010. }
  4011.  
  4012. return;
  4013.  
  4014. }
  4015.  
  4016.  
  4017. void __asm GoURL(REG(a2) APTR obj)
  4018.  
  4019. {
  4020.  
  4021. char *txt = NULL, page[75];
  4022.  
  4023. LONG entry;
  4024.  
  4025. ULONG id = 0;
  4026.  
  4027. struct Contact *user;
  4028. struct ICQMessage *msg = NULL;
  4029.  
  4030. if (obj == app->BT_AdGoURL) get(app->TX_AdURL,MUIA_Text_Contents,&txt);
  4031.  
  4032. if (obj == app->TX_UserURL) get(app->TX_UserURL,MUIA_Text_Contents,&txt);
  4033.  
  4034. if (obj == app->LV_Msgs) {
  4035.   get(app->LV_Msgs,MUIA_NList_DoubleClick,&entry);
  4036.   if (entry < 0) return;
  4037.   DoMethod(app->LV_Msgs,MUIM_NList_GetEntry,entry,&msg);
  4038.   if (msg->Type != 0x0004) return;
  4039.   txt = (msg->Msg)+2;
  4040. }
  4041.  
  4042. if (!txt) {
  4043.   get(obj,MUIA_UserData,&id);
  4044.   if (id) {
  4045.     user = GetContact(id);
  4046.     if (obj == user->UWin->LV_Msgs) {
  4047.       get(user->UWin->LV_Msgs,MUIA_NList_DoubleClick,&entry);
  4048.       if (entry < 0) return;
  4049.       DoMethod(user->UWin->LV_Msgs,MUIM_NList_GetEntry,entry,&msg);
  4050.       if (msg->Type != 0x0004) return;
  4051.       txt = (msg->Msg)+2;
  4052.     }
  4053.     if (obj == user->UWin->BT_HomePage) get(user->UWin->BT_HomePage,MUIA_Text_Contents,&txt);
  4054.     if (obj == user->UWin->BT_WhitePage) {
  4055.       sprintf(page,"http://wwp.mirabilis.com/%ld/",id);
  4056.       txt = page;
  4057.     }
  4058.   }
  4059. }
  4060.  
  4061. if (!txt) return;
  4062.  
  4063. /*
  4064. if (!OpenURL) {
  4065.   get(app->STR_URLCmnd,MUIA_String_Contents,&urlcmd);
  4066.   if (!urlcmd || !txt) return;
  4067.   sprintf(gocmd,urlcmd,txt);
  4068.   System(gocmd,NULL);
  4069. }
  4070. else URL_Open(txt,TAG_DONE);
  4071. */
  4072.  
  4073. if (OpenURL) URL_Open(txt,TAG_DONE);
  4074.  
  4075. return;
  4076.  
  4077. }
  4078.  
  4079.  
  4080. char *ParseMsgHdr(char *buf, struct Contact *user)
  4081.  
  4082. {
  4083.  
  4084. char *c, *p;
  4085.  
  4086. UBYTE auth;
  4087.  
  4088. p = buf;
  4089. c = strchr(p,'\376');
  4090. *c = '\0';
  4091.  
  4092. user->Nick = p;
  4093.  
  4094. p = c+1;
  4095. c = strchr(p,'\376');
  4096. *c = '\0';
  4097.  
  4098. user->First = p;
  4099.  
  4100. p = c+1;
  4101. c = strchr(p,'\376');
  4102. *c = '\0';
  4103.  
  4104. user->Last = p;
  4105.  
  4106. p = c+1;
  4107. c = strchr(p,'\376');
  4108. *c = '\0';
  4109.  
  4110. user->EMail = p;
  4111.  
  4112. p = c+1;
  4113.  
  4114. revmemcpy((char *)&auth,p,1);
  4115.  
  4116. user->Authorize = auth;
  4117.  
  4118. return(p++);
  4119.  
  4120. }
  4121.  
  4122.  
  4123. char *GetNick(ULONG uin)
  4124.  
  4125. {
  4126.  
  4127. BOOL flag = FALSE;
  4128.  
  4129. static char nick[100], *localnick;
  4130.  
  4131. int i;
  4132.  
  4133. ULONG total, localin;
  4134.  
  4135. struct Contact *user;
  4136.  
  4137. get(app->STR_ICQUIN,MUIA_String_Integer,&localin);
  4138. get(app->STR_Nick,MUIA_String_Contents,&localnick);
  4139.  
  4140. get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  4141.  
  4142. for(i = 0; i<total; i++) {
  4143.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  4144.   if (user) {
  4145.     if (user->UIN == uin) {
  4146.       strcpy(nick,user->Nick);
  4147.       flag = TRUE;
  4148.       break;
  4149.     }
  4150.   }
  4151. }
  4152. if (!flag) {
  4153.   if (uin == localin) {
  4154.     strcpy(nick,localnick);
  4155.   }
  4156.   else sprintf(nick,"%ld",uin);
  4157. }
  4158.  
  4159. return(nick);
  4160.  
  4161. }
  4162.  
  4163.  
  4164. void ContactsOffline(void)
  4165.  
  4166. {
  4167.  
  4168. int i;
  4169.  
  4170. ULONG total = 0;
  4171.  
  4172. struct Contact *user;
  4173.  
  4174. get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  4175.  
  4176. for(i = 0; i<total; i++) {
  4177.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  4178.   if (user) {
  4179.     if (user->Status != STATUS_NEWUIN) {
  4180.       user->Status = STATUS_OFFLINE;
  4181.       DoMethod(app->LV_OfflineList,MUIM_NList_Redraw,i);
  4182.       UpdateUserWin(user);
  4183.     }
  4184.   }
  4185. }
  4186. DoMethod(app->LV_OfflineList,MUIM_NList_Sort);
  4187.  
  4188. return;
  4189.  
  4190. }
  4191.  
  4192.  
  4193. BOOL OpenICQSocket(void)
  4194.  
  4195. {
  4196.  
  4197. char *host;
  4198.  
  4199. int i;
  4200.  
  4201. LONG size, total;
  4202.  
  4203. ULONG uin;
  4204.  
  4205. UWORD port;
  4206.  
  4207. struct Sockets Socks, *socks;
  4208.  
  4209. maxfd = -1;
  4210.  
  4211. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  4212. get(app->STR_TheServer,MUIA_String_Contents,&host);
  4213. get(app->STR_ThePort,MUIA_String_Integer,&size);
  4214.  
  4215. port = size;
  4216.  
  4217. #ifdef DEBUG
  4218. HandleError(DBG_UDP_DBUG,"%s:%d",host,port);
  4219. #endif
  4220.  
  4221. //if (!SocketBase) if (!(SocketBase = OpenLibrary("bsdsocket.library",4))) fail(NULL,"Could not open bsdsocket.library v4.");
  4222.  
  4223. if (FirstLogin) {
  4224.   if (SocketBaseTags(SBTM_SETREF(SBTC_SIGIOMASK),&PORT_mask,TAG_DONE) > 0) {
  4225.     HandleError(DBG_UDP_ERRS,"SocketBaseTags failed.");
  4226.     return(FALSE);
  4227.   }
  4228.   FD_ZERO(&rset);
  4229.   FD_ZERO(&wset);
  4230. }
  4231.  
  4232. FileListen = 0;
  4233.  
  4234. get(app->LV_SockList,MUIA_NList_Entries,&total);
  4235.  
  4236. for(i = total-1; i>-1; i--) {
  4237.   DoMethod(app->LV_SockList,MUIM_NList_GetEntry,i,&socks);
  4238.   if (socks) {
  4239.     if (socks->Type == SOCK_UDP || (socks->Dir == TCP_DIR_LISTEN && socks->Type != SOCK_CHAT)) DelSockets(socks->Socket);
  4240.   }
  4241. }
  4242.  
  4243. Socks.UIN = uin;
  4244. Socks.Dir = TCP_DIR_OUT;
  4245. Socks.TCPLen = Socks.Timehack = 0;
  4246. Socks.LastTCP = NULL;
  4247. Socks.ChatMode = Socks.FileMode = NULL;
  4248. Socks.RCObj = NULL;
  4249. Socks.Type = SOCK_UDP;
  4250. Socks.PktLen[0] = Socks.PktLen[1] = '\0';
  4251. Socks.Connecting = Socks.HadInit = Socks.Hidden = Socks.Backward = Socks.Closing = FALSE;
  4252. Socks.CWin = NULL;
  4253.  
  4254. memset((char *)&Socks.Address,0,sizeof(Socks.Address));
  4255.  
  4256. HandleError(DBG_UDP_DBUG,"Looking up ICQ server: %s",host);
  4257.  
  4258. if ((nameinfo = gethostbyname(host)) == NULL) {
  4259.   Socks.Address.sin_addr.s_addr = inet_addr(host);
  4260.   if ((int)Socks.Address.sin_addr.s_addr == -1) {
  4261.     HandleError(DBG_UDP_ERRS,"Your host '%s' was not found.",host);
  4262.     return(FALSE);
  4263.   }
  4264. }
  4265. else memcpy((char *)&Socks.Address.sin_addr.s_addr,nameinfo->h_addr,nameinfo->h_length);
  4266.  
  4267. HandleError(DBG_UDP_DBUG,"Found the host at %s",Inet_NtoA(Socks.Address.sin_addr.s_addr));
  4268.  
  4269. Socks.Address.sin_family = nameinfo->h_addrtype;
  4270. Socks.Address.sin_len = sizeof(struct sockaddr_in);
  4271.  
  4272. if (MiamiBase = OpenLibrary("miami.library",10)) {
  4273.   MiamiSetSocksConn((struct sockaddr *)&Socks.Address,sizeof(struct sockaddr_in));
  4274.   CloseLibrary(MiamiBase);
  4275. }
  4276.  
  4277. HandleError(DBG_UDP_DBUG,"Creating the UDP socket...");
  4278.  
  4279. if ((Socks.Socket = socket(nameinfo->h_addrtype,SOCK_DGRAM,0)) == -1) {
  4280.   HandleError(DBG_UDP_ERRS,"Could not open Mirabilis socket.");
  4281.   return(FALSE);
  4282. }
  4283.  
  4284. HandleError(DBG_UDP_DBUG,"Opened the UDP connection as socket %d",Socks.Socket);
  4285.  
  4286. if (Socks.Socket > maxfd) maxfd = Socks.Socket;
  4287.  
  4288. FD_SET(Socks.Socket,&rset);
  4289.  
  4290. Socks.Address.sin_port = htons(port);
  4291.  
  4292. Socks.IP = Socks.Address.sin_addr.s_addr;
  4293. Socks.Port = Socks.Address.sin_port;
  4294.  
  4295. HandleError(DBG_UDP_DBUG,"Making UDP socket asynchronous");
  4296.  
  4297. if (IoctlSocket(Socks.Socket,FIOASYNC,(char *)&size) == -1) {
  4298.   HandleError(DBG_UDP_ERRS,"Error in IoctlSocket FIOASYNC for UDP socket.");
  4299.   return(FALSE);
  4300. }
  4301.  
  4302. HandleError(DBG_UDP_DBUG,"Making UDP socket non-blocking");
  4303.  
  4304. if (IoctlSocket(Socks.Socket,FIONBIO,(char *)&size) == -1) {
  4305.   HandleError(DBG_UDP_ERRS,"Error in IoctlSocket FIONBIO for UDP socket.");
  4306.   return(FALSE);
  4307. }
  4308.  
  4309. /*
  4310. if (bind(Socks.Socket,(struct sockaddr *)&Socks.Address,sizeof(struct sockaddr_in)) == -1) {
  4311.   HandleError(DBG_UDP_ERRS,"Could not bind the UDP socket.");
  4312. }
  4313. */
  4314.  
  4315. /*
  4316. if (connect(sock,(struct sockaddr *)&server,sizeof(server)) == -1) {
  4317.   if (Errno() != EINPROGRESS) {
  4318.     HandleError(DBG_UDP_ERRS,"Could not connect on UDP socket.");
  4319.     return(FALSE);
  4320.   }
  4321. }
  4322. */
  4323.  
  4324. DoMethod(app->LV_SockList,MUIM_NList_InsertSingle,&Socks,MUIV_NList_Insert_Sorted);
  4325.  
  4326. HandleError(DBG_UDP_DBUG,"UDP socket is established");
  4327.  
  4328. // Finished with the UDP socket(s), now for the TCP socket(s)
  4329.  
  4330. if (!OpenTCPListen(SOCK_MESSAGE)) return(FALSE);
  4331.  
  4332. get(app->LV_SockList,MUIA_NList_Entries,&total);
  4333.  
  4334. if (total > 0) {
  4335.   DoMethod(app->LV_SockList,MUIM_NList_GetEntry,total-1,&socks);
  4336.   if (socks->Socket > maxfd) maxfd = socks->Socket;
  4337. }
  4338.  
  4339. return(TRUE);
  4340.  
  4341. }
  4342.  
  4343.  
  4344. ULONG OpenTCPListen(UBYTE type)
  4345.  
  4346. {
  4347.  
  4348. BOOL *hideip;
  4349.  
  4350. char host[128];
  4351.  
  4352. LONG size;
  4353.  
  4354. ULONG uin;
  4355.  
  4356. struct Sockets Socks;
  4357.  
  4358. host[0] = '\0';
  4359.  
  4360. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  4361. get(app->CH_HideIP,MUIA_Selected,&hideip);
  4362.  
  4363. gethostname(host,sizeof(host));
  4364.  
  4365. Socks.UIN = uin;
  4366. Socks.Dir = TCP_DIR_LISTEN;
  4367. Socks.TCPLen = Socks.Timehack = 0;
  4368. Socks.LastTCP = NULL;
  4369. Socks.ChatMode = Socks.FileMode = NULL;
  4370. Socks.CWin = NULL;
  4371. Socks.RCObj = NULL;
  4372. Socks.Connecting = Socks.HadInit = Socks.Backward = Socks.Closing = FALSE;
  4373. Socks.Hidden = hideip?TRUE:FALSE;
  4374. Socks.Type = type;
  4375. Socks.CWin = NULL;
  4376. Socks.PktLen[0] = Socks.PktLen[1] = '\0';
  4377.  
  4378. if ((Socks.Socket = socket(AF_INET,SOCK_STREAM,0)) == -1) {
  4379.   HandleError(DBG_TCP_ERRS,"Could not open TCP socket.");
  4380.   return(FALSE);
  4381. }
  4382.  
  4383. FD_SET(Socks.Socket,&rset);
  4384.  
  4385. size = 1;
  4386.  
  4387. memset((char *)&Socks.Address,0,sizeof(Socks.Address));
  4388.  
  4389. Socks.Address.sin_family = AF_INET;
  4390. Socks.Address.sin_addr.s_addr = htonl(INADDR_ANY);
  4391. Socks.Address.sin_port = htons(0);
  4392. Socks.Address.sin_len = sizeof(struct sockaddr_in);
  4393.  
  4394. if (bind(Socks.Socket,(struct sockaddr *)&Socks.Address,sizeof(Socks.Address)) == -1) {
  4395.   HandleError(DBG_TCP_ERRS,"Could not bind TCP socket.");
  4396. //return(FALSE);
  4397. }
  4398.  
  4399. if (listen(Socks.Socket,5) == -1) {
  4400.   HandleError(DBG_TCP_ERRS,"Could not listen to TCP socket.");
  4401.   return(FALSE);
  4402. }
  4403.  
  4404. size = sizeof(Socks.Address);
  4405.  
  4406. if (getsockname(Socks.Socket,(struct sockaddr *)&Socks.Address,&size) == -1) {
  4407.   HandleError(DBG_TCP_ERRS,"Error in getsockname while opening a listening socket.");
  4408.   return(FALSE);
  4409. }
  4410.  
  4411. Socks.Port = Socks.ConnectPort = Socks.Address.sin_port;
  4412.  
  4413. memset((char *)&Socks.Address,0,sizeof(Socks.Address));
  4414.  
  4415. if ((nameinfo = gethostbyname(host)) == NULL) {
  4416.   Socks.Address.sin_addr.s_addr = inet_addr(host);
  4417.   if ((int)Socks.Address.sin_addr.s_addr == -1) {
  4418.     HandleError(DBG_TCP_ERRS,"Your LOCAL host name '%s' could not be resolved.",host);
  4419.   }
  4420. }
  4421. else memcpy((char *)&Socks.Address.sin_addr.s_addr,nameinfo->h_addr_list[0],nameinfo->h_length);
  4422.  
  4423. Socks.IP = Socks.Address.sin_addr.s_addr;
  4424.  
  4425. size = 1;
  4426.  
  4427. if (IoctlSocket(Socks.Socket,FIOASYNC,(char *)&size) == -1) {
  4428.   HandleError(DBG_TCP_ERRS,"Error in IoctlSocket FIOASYNC for TCP socket.");
  4429.   return(FALSE);
  4430. }
  4431.  
  4432. if (IoctlSocket(Socks.Socket,FIONBIO,(char *)&size) == -1) {
  4433.   HandleError(DBG_TCP_ERRS,"Error in IoctlSocket FIONBIO for TCP socket.");
  4434.   return(FALSE);
  4435. }
  4436.  
  4437. if (Socks.Socket > maxfd) maxfd = Socks.Socket;
  4438.  
  4439. DoMethod(app->LV_SockList,MUIM_NList_InsertSingle,&Socks,MUIV_NList_Insert_Sorted);
  4440.  
  4441. return(Socks.Port);
  4442.  
  4443. }
  4444.  
  4445.  
  4446. void __asm AddServer(REG(a2) APTR obj)
  4447.  
  4448. {
  4449.  
  4450. char *server, *port, *line_p, line[100], *c;
  4451.  
  4452. ULONG entry;
  4453.  
  4454. if (obj == app->BT_AddServer) {
  4455.   get(app->STR_TheServer,MUIA_String_Contents,&server);
  4456.   get(app->STR_ThePort,MUIA_String_Contents,&port);
  4457.   sprintf(line,"%s:%s",server,port);
  4458.   DoMethod(app->LV_ICQServers,MUIM_NList_InsertSingle,line,MUIV_NList_Insert_Sorted);
  4459. }
  4460. else {
  4461.   get(app->LV_ICQServers,MUIA_NList_EntryClick,&entry);
  4462.   if (entry < 0) return;
  4463.   DoMethod(app->LV_ICQServers,MUIM_NList_GetEntry,entry,&line_p);
  4464.   strcpy(line,line_p);
  4465.   server = line;
  4466.   c = strchr(line,':');
  4467.   *c = '\0';
  4468.   port = c+1;
  4469.   set(app->STR_TheServer,MUIA_String_Contents,server);
  4470.   set(app->STR_ThePort,MUIA_String_Contents,port);
  4471. }
  4472.  
  4473. return;
  4474.  
  4475. }
  4476.  
  4477.  
  4478. void StoreMessage(struct ICQMessage *msg, ULONG uinwin, UWORD cmd)
  4479.  
  4480. {
  4481.  
  4482. BOOL *auto_ch, *winopen;
  4483.  
  4484. char uinlog[MAXNAMLEN], *notifycmd, cmdln[MAXNAMLEN];
  4485.  
  4486. int i;
  4487.  
  4488. LONG lamp;
  4489.  
  4490. ULONG uin = 0, total = 0;
  4491.  
  4492. struct AsyncFile *logfh;
  4493.  
  4494. struct Contact *user;
  4495.  
  4496. if (strlen(msg->Msg) && msg->Type != 0x04) {
  4497.   get(app->STR_MsgNotify,MUIA_String_Contents,¬ifycmd);
  4498.   if (notifycmd) {
  4499.     if (strlen(notifycmd) > 0) {
  4500.       sprintf(cmdln,notifycmd,uinwin);
  4501.       System(cmdln,NULL);
  4502.     }
  4503.   }
  4504.   else DisplayBeep(NULL);
  4505. }
  4506.  
  4507. DoMethod(app->LV_Msgs,MUIM_NList_InsertSingleWrap,msg,MUIV_NList_Insert_Bottom,WRAPCOL2,ALIGN_LEFT);
  4508. DoMethod(app->LV_Msgs,MUIM_NList_Jump,MUIV_NList_Jump_Bottom);
  4509.  
  4510. get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  4511.  
  4512. for(i = 0; i < total; i++) {
  4513.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  4514.   if (user) if (user->UIN == uinwin) {
  4515.     if (!user->UWin) if (!CreateUserWin(uinwin)) break;
  4516.     if (msg->Type == 0x04) {
  4517.       uin = msg->UIN;
  4518.       msg->UIN = 0;
  4519.     }
  4520.     DoMethod(user->UWin->LV_Msgs,MUIM_NList_InsertSingleWrap,msg,MUIV_NList_Insert_Bottom,WRAPCOL2,ALIGN_LEFT);
  4521.     DoMethod(user->UWin->LV_Msgs,MUIM_NList_Jump,MUIV_NList_Jump_Bottom);
  4522.     if (msg->Type == 0x04) msg->UIN = uin;
  4523.     if (!strlen(msg->Msg)) break;
  4524.     get(app->CH_Scrn2Frnt,MUIA_Selected,&auto_ch);
  4525.     if (auto_ch) DoMethod(app->WI_Main,MUIM_Window_ScreenToFront);
  4526.     get(app->CH_MsgPopup,MUIA_Selected,&auto_ch);
  4527.     if (auto_ch) {
  4528.       get(user->UWin->WI_UserWindow,MUIA_Window_Open,&winopen);
  4529.       if (!winopen) set(user->UWin->WI_UserWindow,MUIA_Window_Open,TRUE);
  4530.       else DoMethod(user->UWin->WI_UserWindow,MUIM_Window_ToFront);
  4531.     }
  4532.     else {
  4533.       get(user->UWin->WI_UserWindow,MUIA_Window_Open,&winopen);
  4534.       get(app->WI_Message,MUIA_Window_Open,&auto_ch);
  4535.       if (!winopen && !auto_ch && msg->Type != 0x04) {
  4536.         switch(++user->NewMsg) {
  4537.           case 1:
  4538.             if (WhichLamp == 0) lamp = MUIV_Lamp_Color_Ok;
  4539.             else lamp = MUIV_TWFmultiLED_Colour_On;
  4540.             break;
  4541.           case 2:
  4542.             if (WhichLamp == 0) lamp = MUIV_Lamp_Color_Warning;
  4543.             else lamp = MUIV_TWFmultiLED_Colour_Ok;
  4544.             break;
  4545.           case 3:
  4546.             if (WhichLamp == 0) lamp = MUIV_Lamp_Color_Error;
  4547.             else lamp = MUIV_TWFmultiLED_Colour_Load;
  4548.             break;
  4549.           default:
  4550.             if (WhichLamp == 0) lamp = MUIV_Lamp_Color_FatalError;
  4551.             else lamp = MUIV_TWFmultiLED_Colour_Error;
  4552.         }
  4553.         if (WhichLamp == 0) set(user->LampObj,MUIA_Lamp_Color,lamp);
  4554.         else set(user->LampObj,MUIA_TWFmultiLED_Colour,lamp);
  4555. //      DoMethod(app->LV_OfflineList,MUIM_NList_Redraw,MUIV_NList_Redraw_All);
  4556.         DoMethod(app->LV_OfflineList,MUIM_NList_Redraw,i);
  4557.         DoMethod(app->LV_OfflineList,MUIM_NList_Sort);
  4558.       }
  4559.     }
  4560.     break;
  4561.   }
  4562. }
  4563.  
  4564. get(app->CH_NoMsgLog,MUIA_Selected,&auto_ch);
  4565.  
  4566. if (auto_ch) return;
  4567.  
  4568. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  4569.  
  4570. sprintf(uinlog,"%sUsers/%ld/Logs/%ld",currentdir,uin,msg->UIN);
  4571.  
  4572. if (logfh = OpenAsync(uinlog,MODE_APPEND,AsyncBuf)) {
  4573.   if (msg->Type == 0x04) SeekAsync(logfh,-1,MODE_CURRENT);
  4574.   if (msg->Timehack) {
  4575.     WriteLineAsync(logfh,ctime(&msg->Timehack));
  4576.   }
  4577.   WriteLineAsync(logfh,"R: ");
  4578.   WriteLineAsync(logfh,msg->Msg);
  4579.   WriteLineAsync(logfh,"\n\n");
  4580.   CloseAsync(logfh);
  4581.   SetComment(uinlog,GetNick(msg->UIN));
  4582. }
  4583.  
  4584. return;
  4585.  
  4586. }
  4587.  
  4588.  
  4589. void __asm ViewHistory(REG(a2) APTR obj)
  4590.  
  4591. {
  4592.  
  4593. char uinlog[MAXNAMLEN], line[1024], info[100], *path;
  4594.  
  4595. ULONG uin = 0, localin = 0;
  4596.  
  4597. struct AsyncFile *loadfh;
  4598.  
  4599. if (obj == app->WI_MessageHist) {
  4600.   set(app->DL_MsgDir,MUIA_Dirlist_Directory,logdir_fl);
  4601.   get(app->STR_ICQUIN,MUIA_String_Integer,&localin);
  4602. }
  4603. else {
  4604.   get(app->DL_MsgDir,MUIA_Dirlist_Path,&path);
  4605.   if (!strlen(path)) return;
  4606.   StrToLong(FilePart(path),(LONG *)&localin);
  4607. }
  4608.  
  4609. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  4610.  
  4611. DoMethod(app->LV_MsgText,MUIM_NList_Clear);
  4612.  
  4613. sprintf(uinlog,"%sUsers/%ld/Logs/%ld",currentdir,uin,localin);
  4614.  
  4615. set(app->LV_MsgText,MUIA_NList_Quiet,TRUE);
  4616.  
  4617. if (loadfh = OpenAsync(uinlog,MODE_READ,AsyncBuf)) {
  4618.   sprintf(info,"%ld %s",localin,GetNick(localin));
  4619.   set(app->TX_MsgUser,MUIA_Text_Contents,info);
  4620.   while(ReadLineAsync(loadfh,line,sizeof(line)) > 0) {
  4621.     LASTCHAR(line) = '\0';
  4622.     DoMethod(app->LV_MsgText,MUIM_NList_InsertWrap,line,-2,MUIV_NList_Insert_Bottom,WRAPCOL0,ALIGN_LEFT);
  4623.   }
  4624.   CloseAsync(loadfh);
  4625. }
  4626. else set(app->TX_MsgUser,MUIA_Text_Contents,"Not Found");
  4627.  
  4628. set(app->LV_MsgText,MUIA_NList_Quiet,FALSE);
  4629.  
  4630. set(app->WI_MessageHist,MUIA_Window_Open,TRUE);
  4631.  
  4632. return;
  4633.  
  4634. }
  4635.  
  4636.  
  4637. void __asm SendUInfo1(REG(a2) APTR obj)
  4638.  
  4639. {
  4640.  
  4641. char *nick, *first, *last, *email;
  4642.  
  4643. int len;
  4644.  
  4645. UBYTE auth;
  4646.  
  4647. ULONG uin, reqauth;
  4648.  
  4649. UWORD cmd;
  4650.  
  4651. struct C_Update_Basic_Info basic;
  4652. struct C_UpdateAuth Auth;
  4653.  
  4654. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  4655. get(app->STR_Nick,MUIA_String_Contents,&nick);
  4656. get(app->STR_First,MUIA_String_Contents,&first);
  4657. get(app->STR_Last,MUIA_String_Contents,&last);
  4658. get(app->STR_EMail,MUIA_String_Contents,&email);
  4659. get(app->RD_ReqAuth,MUIA_Radio_Active,&reqauth);
  4660.  
  4661. if (reqauth) auth = 0x00;
  4662. else auth = 0x01;
  4663.  
  4664. if (obj == app->BT_UpUInfo1) cmd = C_UPDATE_INFO;
  4665. else cmd = C_NEW_USER_INFO;
  4666.  
  4667. Header.Command = cmd;
  4668.  
  4669. basic.Sequence = chguinfo_seq++;
  4670.  
  4671. strcpy(basic.Nick,nick);
  4672. strcpy(basic.First,first);
  4673. strcpy(basic.Last,last);
  4674. strcpy(basic.EMail,email);
  4675.  
  4676. basic.Authorize = -auth+1;
  4677.  
  4678. len = UDP_CreatePacket(&Header,&basic,UDP_Buf);
  4679.  
  4680. send_udp_pkt(UDP_Buf,len,uin);
  4681.  
  4682. Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  4683.  
  4684. if (!NewUser) {
  4685.   Header.Command = C_UPDATE_AUTH;
  4686.   Auth.Sequence = chguinfo_seq++;
  4687.   Auth.Authorize = auth;
  4688.   len = UDP_CreatePacket(&Header,&Auth,UDP_Buf);
  4689.   send_udp_pkt(UDP_Buf,len,uin);
  4690.   Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  4691. }
  4692.  
  4693. return;
  4694.  
  4695. }
  4696.  
  4697.  
  4698. void __asm SendUInfo2(REG(a2) APTR obj)
  4699.  
  4700. {
  4701.  
  4702. BYTE status;
  4703.  
  4704. char *city, *state, *phone, *url, *about, about2[512], *c, *d;
  4705.  
  4706. int len;
  4707.  
  4708. LONG zone;
  4709.  
  4710. UBYTE sex;
  4711.  
  4712. ULONG uin, country1, age1, sex1;
  4713.  
  4714. UWORD country, age;
  4715.  
  4716. struct C_Update_Ext_Info Ext;
  4717.  
  4718. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  4719. get(app->STR_City,MUIA_String_Contents,&city);
  4720. get(app->STR_State,MUIA_String_Contents,&state);
  4721. get(app->STR_Phone,MUIA_String_Contents,&phone);
  4722. get(app->STR_Page,MUIA_String_Contents,&url);
  4723. get(app->TI_About,MUIA_Textinput_Contents,&about);
  4724. get(app->STR_Country,MUIA_String_Integer,&country1);
  4725. get(app->NU_TimeZone,MUIA_Numeric_Value,&zone);
  4726. get(app->STR_Age,MUIA_String_Integer,&age1);
  4727. get(app->CY_Sex,MUIA_Cycle_Active,&sex1);
  4728.  
  4729. country = country1;
  4730. age = age1;
  4731. sex = sex1;
  4732.  
  4733. if (country == 0) country = 0xffff;
  4734.  
  4735. status = -(zone*2);
  4736.  
  4737. if (age == 0) age = 0xffff;
  4738.  
  4739. Header.Command = C_UPDATE_EXT_INFO;
  4740.  
  4741. Ext.Sequence = chguinfo_seq++;
  4742. Ext.Country = country;
  4743. Ext.Timezone = status;
  4744. Ext.Age = age;
  4745. Ext.Sex = sex;
  4746.  
  4747. for(c = about, d = about2; *c; c++, d++) {
  4748.   if (*c == '\n') *d++ = '\r';
  4749.   *d = *c;
  4750. }
  4751. *d = '\0';
  4752.  
  4753. strcpy(Ext.City,city);
  4754. strcpy(Ext.State,state);
  4755. strcpy(Ext.Phone,phone);
  4756. strcpy(Ext.URL,url);
  4757. strcpy(Ext.About,about2);
  4758.  
  4759. len = UDP_CreatePacket(&Header,&Ext,UDP_Buf);
  4760.  
  4761. send_udp_pkt(UDP_Buf,len,uin);
  4762.  
  4763. Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  4764.  
  4765. return;
  4766.  
  4767. }
  4768.  
  4769.  
  4770. void __asm NewUIN(REG(a2) APTR obj)
  4771.  
  4772. {
  4773.  
  4774. char *pw;
  4775.  
  4776. int len;
  4777.  
  4778. if (!MUI_Request(app->App,app->WI_Main,0,NULL,"Continue|Cancel","\033cPress Continue only after\nyou have filled in all\nthe information on the\n ICQ Basic and Extended Prefs pages\nin the Prefs window\nexcept for User ID Number.")) return;
  4779.  
  4780. get(app->STR_ICQPass,MUIA_String_Contents,&pw);
  4781.  
  4782. if (!strlen(pw)) {
  4783.   HandleError(DBG_OTH_FATL,"You need to at least specify a Password!");
  4784.   return;
  4785. }
  4786.  
  4787. if (Online) DisconnectICQ(NULL);
  4788.  
  4789. FirstLogin = NewUser = TRUE;
  4790.  
  4791. set(app->TX_Color,MUIA_Text_Contents,"Creating New UIN");
  4792.  
  4793. if (!(SocketOpen = OpenICQSocket())) {
  4794.   HandleError(DBG_OTH_FATL,"Could not connect to ICQ.");
  4795.   return;
  4796. }
  4797.  
  4798. Header.Command = C_NEW_USER_1;
  4799. Header.UIN = 0;
  4800.  
  4801. len = UDP_CreatePacket(&Header,NULL,UDP_Buf);
  4802.  
  4803. send_udp_pkt(UDP_Buf,len,0x00000000);
  4804.  
  4805. DoMethod(app->LV_ICQCliLog,MUIM_NList_Clear);
  4806. DoMethod(app->LV_ICQSrvLog,MUIM_NList_Clear);
  4807.  
  4808. Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  4809.  
  4810. return;
  4811.  
  4812. }
  4813.  
  4814.  
  4815. void __asm MakeFilenames(REG(a2) APTR obj)
  4816.  
  4817. {
  4818.  
  4819. ULONG uin = 0;
  4820.  
  4821. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  4822.  
  4823. sprintf(contact_fl,"%sUsers/%ld/Contacts",currentdir,uin);
  4824. sprintf(config_fl,"%sUsers/%ld/STRICQ.cfg",currentdir,uin);
  4825. sprintf(colors_fl,"%sUsers/%ld/Config.cfg",currentdir,uin);
  4826. sprintf(server_fl,"%sUsers/%ld/Servers.cfg",currentdir,uin);
  4827. sprintf(logdir_fl,"%sUsers/%ld/Logs/",currentdir,uin);
  4828. sprintf(userdir_fl,"%sUsers/%ld/Users/",currentdir,uin);
  4829.  
  4830. return;
  4831.  
  4832. }
  4833.  
  4834.  
  4835. APTR __asm AddActy(REG(a2) APTR pool, REG(a1) struct Activity *acty)
  4836.  
  4837. {
  4838.  
  4839. struct Activity *newacty = NULL;
  4840.  
  4841. if (!(newacty = AllocPooled(pool,sizeof(struct Activity)))) return(NULL);
  4842.  
  4843. newacty->UIN = acty->UIN;
  4844. newacty->Status = acty->Status;
  4845. newacty->Timehack = acty->Timehack;
  4846.  
  4847. return(newacty);
  4848.  
  4849. }
  4850.  
  4851.  
  4852. void __asm RemActy(REG(a2) APTR pool, REG(a1) struct Activity *newacty)
  4853.  
  4854. {
  4855.  
  4856. FreePooled(pool,newacty,sizeof(struct Activity));
  4857.  
  4858. return;
  4859.  
  4860. }
  4861.  
  4862.  
  4863. LONG __asm CmpActy(REG(a1) struct Activity *a1, REG(a2) struct Activity *a2)
  4864.  
  4865. {
  4866.  
  4867. BOOL *auto_ch;
  4868.  
  4869. struct Contact *u1, *u2;
  4870.  
  4871. get(app->CH_ActySort,MUIA_Selected,&auto_ch);
  4872.  
  4873. if (!auto_ch) {
  4874.   if (a1->Timehack < a2->Timehack) return(-1);
  4875.   if (a1->Timehack > a2->Timehack) return(1);
  4876.   return(0);
  4877. }
  4878.  
  4879. u1 = GetContact(a1->UIN);
  4880. u2 = GetContact(a2->UIN);
  4881.  
  4882. if (stricmp(u1->Nick,u2->Nick) == 0) {
  4883.   if (a1->Timehack < a2->Timehack) return(-1);
  4884.   else return(1);
  4885. }
  4886.  
  4887. return(stricmp(u1->Nick,u2->Nick));
  4888.  
  4889. }
  4890.  
  4891.  
  4892. void __asm DisplayActy(REG(a2) char **array, REG(a1) struct Activity *acty)
  4893.  
  4894. {
  4895.  
  4896. BOOL *usebeats;
  4897.  
  4898. static char nick[100], tmp[15], tme[20], status[30];
  4899.  
  4900. struct ColorText *ct;
  4901.  
  4902. ULONG pen = 2;
  4903.  
  4904. get(app->CH_UseBeats,MUIA_Selected,&usebeats);
  4905.  
  4906. if (acty) {
  4907.   ct = GetStatus(acty->Status);
  4908.   pen = MUIPEN(ct->Pen);
  4909.   sprintf(status,"\033P[%ld]%s",pen,ct->Status);
  4910.   if (usebeats) sprintf(tmp,"@ %d",MakeBeats(acty->Timehack));
  4911.   else strncpy(tmp,ctime(&acty->Timehack)+11,8);
  4912.   sprintf(tme,"\033P[%ld]%s",pen,tmp);
  4913.   sprintf(nick,"\033P[%ld]%s",pen,GetNick(acty->UIN));
  4914.   *array++ = nick;
  4915.   *array++ = tme;
  4916.   *array   = status;
  4917. }
  4918. else {
  4919.   *array++ = "Nick";
  4920.   *array++ = "Time";
  4921.   *array   = "Activity";
  4922. }
  4923.  
  4924. return;
  4925.  
  4926. }
  4927.  
  4928.  
  4929. void __asm LoadPrefs(REG(a2) APTR obj)
  4930.  
  4931. {
  4932.  
  4933. BPTR mylock;
  4934.  
  4935. char line[1024], first[50], last[50];
  4936.  
  4937. int i;
  4938.  
  4939. ULONG uin;
  4940.  
  4941. UWORD length = 0;
  4942.  
  4943. __aligned struct FileInfoBlock *myFIB;
  4944.  
  4945. struct AsyncFile  *loadfh;
  4946. struct Column      Col;
  4947. struct Contact     User;
  4948. struct IgnoreUIN   Ignore;
  4949. struct MUI_PenSpec startpen;
  4950.  
  4951. PrepNewContact(&User);
  4952. MakeFilenames(NULL);
  4953.  
  4954. MyCreateDir(logdir_fl);
  4955. MyCreateDir(userdir_fl);
  4956.  
  4957. line[0] = '\0';
  4958.  
  4959. set(app->GA_Contacts,MUIA_Gauge_InfoText,"Loading Application");
  4960.  
  4961. DoMethod(app->App,MUIM_Application_Load,config_fl);
  4962.  
  4963. set(app->GA_Contacts,MUIA_Gauge_InfoText,"Loading Pens & About");
  4964.  
  4965. if (loadfh = OpenAsync(colors_fl,MODE_READ,AsyncBuf)) {
  4966.   for(i = 0; i < 8; i++) {
  4967.     ReadAsync(loadfh,&startpen,sizeof(struct MUI_PenSpec));
  4968.     set(app->PP_StatusColors[i],MUIA_Pendisplay_Spec,&startpen);
  4969.   }
  4970.   ReadAsync(loadfh,&URLMsg_cnt,sizeof(URLMsg_cnt));
  4971.   ReadAsync(loadfh,&length,sizeof(length));
  4972.   ReadAsync(loadfh,line,length);
  4973.   set(app->TI_About,MUIA_Textinput_Contents,line);
  4974.   ReadAsync(loadfh,&SrvrMsg_cnt,sizeof(SrvrMsg_cnt));
  4975.   for(i = 8; i < NUM_STATUS_COLORS; i++) {
  4976.     if (ReadAsync(loadfh,&startpen,sizeof(struct MUI_PenSpec))) set(app->PP_StatusColors[i],MUIA_Pendisplay_Spec,&startpen);
  4977.   }
  4978.   for(i = 0; i < NUM_CHAT_COLORS; i++) {
  4979.     if (ReadAsync(loadfh,&startpen,sizeof(struct MUI_PenSpec))) set(app->PP_ChatColors[i],MUIA_Pendisplay_Spec,&startpen);
  4980.   }
  4981.   CloseAsync(loadfh);
  4982. }
  4983.  
  4984. DoMethod(app->App,MUIM_Application_InputBuffered);
  4985.  
  4986. DoMethod(app->LV_OfflineList,MUIM_NList_Clear);
  4987.  
  4988. set(app->LV_OfflineList,MUIA_NList_Quiet,TRUE);
  4989.  
  4990. contacts_cnt = 0;
  4991.  
  4992. get(app->CY_Lamp,MUIA_Cycle_Active,&WhichLamp);
  4993.  
  4994. // TX_LoadProgress,MUIA__Contents
  4995. set(app->GA_Contacts,MUIA_Gauge_InfoText,"Loading Contacts");
  4996.  
  4997. if (!(myFIB = (struct FileInfoBlock *)AllocVec(sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR))) {
  4998.   HandleError(DBG_OTH_FATL,"Could not allocate FileInfoBlock.  Out of memory.");
  4999.   return;
  5000. }
  5001.  
  5002. if ((mylock = Lock(userdir_fl,SHARED_LOCK)) == NULL) {
  5003.   HandleError(DBG_OTH_FATL,"Could not Lock '%s' to read dir.",userdir_fl);
  5004.   FreeVec(myFIB);
  5005.   return;
  5006. }
  5007.  
  5008. if (Examine(mylock,myFIB) == NULL) {
  5009.   HandleError(DBG_OTH_FATL,"Could not Examine '%s' to count dir.",userdir_fl);
  5010.   FreeVec(myFIB);
  5011.   UnLock(mylock);
  5012.   return;
  5013. }
  5014.  
  5015. while(ExNext(mylock,myFIB) != NULL) contacts_cnt++;
  5016.  
  5017. set(app->GA_Contacts,MUIA_Gauge_Current,0);
  5018. set(app->GA_Contacts,MUIA_Gauge_Max,contacts_cnt);
  5019.  
  5020. contacts_cnt = 0;
  5021.  
  5022. if (Examine(mylock,myFIB) == NULL) {
  5023.   HandleError(DBG_OTH_FATL,"Could not Examine '%s' to read dir.",userdir_fl);
  5024.   FreeVec(myFIB);
  5025.   UnLock(mylock);
  5026.   return;
  5027. }
  5028.  
  5029. while(ExNext(mylock,myFIB) != NULL) {
  5030.   sscanf(myFIB->fib_FileName,"%ld",&uin);
  5031.   LoadContact(uin);
  5032.   DoMethod(app->App,MUIM_Application_InputBuffered);
  5033.   contacts_cnt++;
  5034.   set(app->GA_Contacts,MUIA_Gauge_Current,contacts_cnt);
  5035. }
  5036.  
  5037. UnLock(mylock);
  5038. FreeVec(myFIB);
  5039.  
  5040. set(app->GA_Contacts,MUIA_Gauge_InfoText,"Sorting Contacts");
  5041.  
  5042. DoMethod(app->LV_OfflineList,MUIM_NList_Sort);
  5043.  
  5044. set(app->LV_OfflineList,MUIA_NList_Quiet,FALSE);
  5045.  
  5046. set(app->GA_Contacts,MUIA_Gauge_InfoText,"Servers, Columns, Ignore");
  5047.  
  5048. DoMethod(app->LV_ICQServers,MUIM_NList_Clear);
  5049. DoMethod(app->LV_ColsStore,MUIM_NList_Clear);
  5050. DoMethod(app->LV_ColsUse,MUIM_NList_Clear);
  5051. DoMethod(app->LV_IgnoreUIN,MUIM_NList_Clear);
  5052.  
  5053. if (loadfh = OpenAsync(server_fl,MODE_READ,AsyncBuf)) {
  5054.   while(ReadLineAsync(loadfh,line,sizeof(line)) > 0) {
  5055.     if (line[0] == ';') break;
  5056.     LASTCHAR(line) = '\0';
  5057.     DoMethod(app->LV_ICQServers,MUIM_NList_InsertSingle,line,MUIV_NList_Insert_Sorted);
  5058.   }
  5059.   while(ReadLineAsync(loadfh,first,sizeof(first)) > 0) {
  5060.     if (first[0] == ';') break;
  5061.     LASTCHAR(first) = '\0';
  5062.     ReadLineAsync(loadfh,last,sizeof(last));
  5063.     LASTCHAR(last) = '\0';
  5064.     Col.Name = first;
  5065.     Col.COL = last;
  5066.     DoMethod(app->LV_ColsStore,MUIM_NList_InsertSingle,&Col,MUIV_NList_Insert_Bottom);
  5067.   }
  5068.   while(ReadLineAsync(loadfh,first,sizeof(first)) > 0) {
  5069.     if (first[0] == ';') break;
  5070.     LASTCHAR(first) = '\0';
  5071.     ReadLineAsync(loadfh,last,sizeof(last));
  5072.     LASTCHAR(last) = '\0';
  5073.     Col.Name = first;
  5074.     Col.COL = last;
  5075.     DoMethod(app->LV_ColsUse,MUIM_NList_InsertSingle,&Col,MUIV_NList_Insert_Bottom);
  5076.   }
  5077.   while(ReadLineAsync(loadfh,line,sizeof(line)) > 0) {
  5078.     if (line[0] == ';') break;
  5079.     StrToLong(line,(LONG *)&Ignore.UIN);
  5080.     ReadLineAsync(loadfh,line,sizeof(line));
  5081.     LASTCHAR(line) = '\0';
  5082.     strcpy(Ignore.Nick,line);
  5083.     ReadLineAsync(loadfh,line,sizeof(line));
  5084.     StrToLong(line,(LONG *)&Ignore.Timehack);
  5085.     ReadLineAsync(loadfh,line,sizeof(line));
  5086.     StrToLong(line,(LONG *)&uin);
  5087.     Ignore.ExpireDays = uin;
  5088.     if (time(NULL) < Ignore.ExpireDays && Ignore.ExpireDays > 0) DoMethod(app->LV_IgnoreUIN,MUIM_NList_InsertSingle,&Ignore,MUIV_NList_Insert_Bottom);
  5089.   }
  5090.   CloseAsync(loadfh);
  5091. }
  5092.  
  5093. DoMethod(app->App,MUIM_Application_InputBuffered);
  5094.  
  5095. DoMethod(app->LV_Activity,MUIM_NList_Clear);
  5096.  
  5097. sprintf(maintitle,"STRICQ (%d)",contacts_cnt);
  5098. set(app->WI_Main,MUIA_Window_Title,maintitle);
  5099.  
  5100. return;
  5101.  
  5102. }
  5103.  
  5104.  
  5105. BOOL MyCreateDir(char *dir)
  5106.  
  5107. {
  5108.  
  5109. BPTR mylock;
  5110.  
  5111. char *s;
  5112.  
  5113. s = dir;
  5114.  
  5115. while (s = strchr(s+1,'/')) {
  5116.   *s = '\0';
  5117.   if (mylock = Lock(dir,ACCESS_READ)) {
  5118.     UnLock(mylock);
  5119.     *s = '/';
  5120.     continue;
  5121.   }
  5122.   if (mylock = CreateDir(dir)) UnLock(mylock);
  5123.   else {
  5124.     HandleError(DBG_OTH_INFO,"Could not create directory:  %s",dir);
  5125.     return(FALSE);
  5126.   }
  5127.   *s = '/';
  5128. }
  5129.  
  5130. return(TRUE);
  5131.  
  5132. }
  5133.  
  5134.  
  5135. void __asm ChangeMyUIN(REG(a2) APTR obj)
  5136.  
  5137. {
  5138.  
  5139. BOOL tmponline;
  5140.  
  5141. char *entry;
  5142.  
  5143. get(app->DL_UINList,MUIA_Dirlist_Path,&entry);
  5144.  
  5145. tmponline = Online;
  5146.  
  5147. DisconnectICQ(NULL);
  5148.  
  5149. SavePrefs(NULL);
  5150.  
  5151. set(app->STR_ICQUIN,MUIA_String_Contents,FilePart(entry));
  5152.  
  5153. get(app->STR_ICQUIN,MUIA_String_Integer,&Header.UIN);
  5154.  
  5155. LoadPrefs(NULL);
  5156.  
  5157. if (tmponline) ConnectICQ(NULL);
  5158.  
  5159. return;
  5160.  
  5161. }
  5162.  
  5163.  
  5164. void __asm SaveMsgWin(REG(a2) APTR obj)
  5165.  
  5166. {
  5167.  
  5168. char save_fl[MAXNAMLEN], line[1024];
  5169.  
  5170. char title[] = "Save Current Messages:";
  5171.  
  5172. int i;
  5173.  
  5174. time_t newhack, lasthack = 0;
  5175.  
  5176. ULONG entries;
  5177.  
  5178. struct AsyncFile     *savefh;
  5179. struct ICQMessage    *msg;
  5180. struct FileRequester *myasl;
  5181. struct Window        *mywin = NULL;
  5182.  
  5183. struct TagItem MyASLTags[] = {
  5184.   {ASLFR_TitleText,    NULL},
  5185.   {ASLFR_Window,       NULL},
  5186.   {ASLFR_InitialDrawer,NULL},
  5187.   {ASLFR_DoSaveMode,   TRUE},
  5188.   {ASLFR_RejectIcons,  TRUE},
  5189.  
  5190.   {TAG_DONE,NULL},
  5191. };
  5192.  
  5193. get(app->LV_Msgs,MUIA_NList_Entries,&entries);
  5194. get(app->WI_Main,MUIA_Window_Window,&mywin);
  5195.  
  5196. MyASLTags[0].ti_Data = (ULONG)title;
  5197. MyASLTags[1].ti_Data = (ULONG)mywin;
  5198. MyASLTags[2].ti_Data = (ULONG)currentdir;
  5199.  
  5200. if (entries < 1) return;
  5201.  
  5202. if (!(myasl = MUI_AllocAslRequest(ASL_FileRequest,MyASLTags))) return;
  5203.  
  5204. if (!MUI_AslRequest(myasl,NULL)) return;
  5205.  
  5206. if (LASTCHAR(myasl->fr_Drawer) != ':' && LASTCHAR(myasl->fr_Drawer) != '/') sprintf(save_fl,"%s/%s",myasl->fr_Drawer,myasl->fr_File);
  5207. else sprintf(save_fl,"%s%s",myasl->fr_Drawer,myasl->fr_File);
  5208.  
  5209. MUI_FreeAslRequest(myasl);
  5210.  
  5211. if (!(savefh = OpenAsync(save_fl,MODE_WRITE,AsyncBuf))) {
  5212.   HandleError(DBG_OTH_INFO,"Could not open the save file:  %s",save_fl);
  5213.   return;
  5214. }
  5215.  
  5216. for(i = 0; i < entries; i++) {
  5217.   DoMethod(app->LV_Msgs,MUIM_NList_GetEntry,i,&msg);
  5218.   if (msg) {
  5219.     if (msg->Type == 0) {
  5220.       WriteCharAsync(savefh,'\n');
  5221.       continue;
  5222.     }
  5223.     newhack = msg->Timehack;
  5224.     if (newhack == lasthack) continue;
  5225.     line[0] = '\0';
  5226.     if (msg->UIN != 0) sprintf(line,"%s %.8s ",GetNick(msg->UIN),ctime(&msg->Timehack)+11);
  5227.     if (msg->Type != 0x0004) strcat(line,msg->Msg);
  5228.     else strcat(line,msg->Msg+2);
  5229.     WriteLineAsync(savefh,line);
  5230.     WriteCharAsync(savefh,'\n');
  5231.     lasthack = newhack;
  5232.   }
  5233. }
  5234.  
  5235. CloseAsync(savefh);
  5236.  
  5237. return;
  5238.  
  5239. }
  5240.  
  5241.  
  5242. void __asm NewUserWin(REG(a2) APTR obj)
  5243.  
  5244. {
  5245.  
  5246. BOOL *openwin, flag = TRUE;
  5247.  
  5248. LONG entry;
  5249.  
  5250. struct Contact *user;
  5251.  
  5252. get(app->LV_OfflineList,MUIA_NList_DoubleClick,&entry);
  5253.  
  5254. if (entry < 0) return;
  5255.  
  5256. DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,entry,&user);
  5257.  
  5258. if (!user) return;
  5259.  
  5260. if (user->NewMsg) {
  5261.   user->NewMsg = 0;
  5262.   user->Changed = TRUE;
  5263.   if (WhichLamp == 0) set(user->LampObj,MUIA_Lamp_Color,MUIV_Lamp_Color_Off);
  5264.   else set(user->LampObj,MUIA_TWFmultiLED_Colour,MUIV_TWFmultiLED_Colour_Off);
  5265.   DoMethod(app->LV_OfflineList,MUIM_NList_Redraw,entry);
  5266.   DoMethod(app->LV_OfflineList,MUIM_NList_Sort);
  5267. }
  5268.  
  5269. if (!user->UWin) flag = CreateUserWin(user->UIN);
  5270.  
  5271. get(user->UWin->WI_UserWindow,MUIA_Window_Open,&openwin);
  5272.  
  5273. if (!openwin && flag) set(user->UWin->WI_UserWindow,MUIA_Window_Open,TRUE);
  5274. if (openwin && flag) DoMethod(user->UWin->WI_UserWindow,MUIM_Window_ToFront);
  5275.  
  5276. return;
  5277.  
  5278. }
  5279.  
  5280.  
  5281. BOOL CreateUserWin(ULONG id)
  5282.  
  5283. {
  5284.  
  5285. BOOL *multiline, *usetime;
  5286.  
  5287. struct Contact *user = NULL;
  5288.  
  5289. struct UserWindow *UWin;
  5290.  
  5291. if (!(user = GetContact(id))) return(FALSE);
  5292.  
  5293. if (!(UWin = AllocVec(sizeof(struct UserWindow),MEMF_CLEAR))) {
  5294.   HandleError(DBG_OTH_FATL,"Failed to AllocVec %d bytes!",sizeof(struct UserWindow));
  5295.   return(FALSE);
  5296. }
  5297.  
  5298. get(app->CH_MsgTime,MUIA_Selected,&usetime);
  5299. get(app->CH_MultiLine,MUIA_Selected,&multiline);
  5300.  
  5301. UWin->DoNotDelete = FALSE;
  5302.  
  5303. UWin->SC_AboutScroll   = ScrollbarObject, End;
  5304. UWin->SC_CommentScroll = ScrollbarObject, End;
  5305.  
  5306. UWin->WI_UserWindow = WindowObject,
  5307.   MUIA_Window_Title, UWin->Title,
  5308.   MUIA_Window_ID, id,
  5309.   MUIA_Window_Activate, FALSE,
  5310.   MUIA_UserData, id,
  5311.   WindowContents, GroupObject,
  5312.     Child, UWin->RG_UserPages = RegisterObject,
  5313.       MUIA_Register_Titles, UPages,
  5314.       MUIA_CycleChain, TRUE,
  5315.       Child, VGroup,
  5316.         Child, VGroup,
  5317.           Child, UWin->LV_Msgs = NListviewObject,
  5318.             MUIA_CycleChain, 1,
  5319.             MUIA_NListview_NList, NListObject,
  5320.             MUIA_NList_TypeSelect, MUIV_NList_TypeSelect_Char,
  5321.               MUIA_Frame, MUIV_Frame_ReadList,
  5322.               MUIA_NList_Title, TRUE,
  5323.               MUIA_NList_Format, "BAR,BAR,BAR",
  5324. //            MUIA_NList_TypeSelect, MUIV_NList_TypeSelect_Char,
  5325.               MUIA_NList_CompareHook, &CmpMsgHook,
  5326.               MUIA_NList_ConstructHook, &AddMsgHook,
  5327.               MUIA_NList_DestructHook, &RemMsgHook,
  5328.               MUIA_NList_DisplayHook, &DisplayMsgHook,
  5329.               MUIA_ShortHelp, "Double-Click an underlined URL to\nopen the link in a browser.  Click on\nthe URL, not description, to Forward\nthe URL message.",
  5330.             End,
  5331.           End,
  5332.         End,
  5333.         Child, BalanceObject, End,
  5334.         Child, HGroup,
  5335.           Child, UWin->TI_QuickMsg = TextinputObject,
  5336.             MUIA_Frame, MUIV_Frame_String,
  5337.             MUIA_CycleChain, 1,
  5338.             MUIA_UserData, id,
  5339.             MUIA_Textinput_Multiline, multiline,
  5340.             MUIA_Textinput_Contents, NULL,
  5341.             MUIA_Textinput_MaxLen, 450,
  5342.             MUIA_Textinput_RemainActive, TRUE,
  5343.             MUIA_ShortHelp, "To send a message, type it\nhere and press RETURN to send.",
  5344.           End,
  5345.           Child, VGroup,
  5346.             MUIA_Weight, 40,
  5347.             Child, HGroup,
  5348.               Child, UWin->BT_SendIt = TextObject,
  5349.                 MUIA_Frame, MUIV_Frame_Button,
  5350.                 MUIA_Font, MUIV_Font_Button,
  5351.                 MUIA_Text_Contents, "Send",
  5352.                 MUIA_Text_PreParse, "\33c",
  5353.                 MUIA_InputMode, MUIV_InputMode_RelVerify,
  5354.                 MUIA_Background, MUII_ButtonBack,
  5355.                 MUIA_ShortHelp, "Click here to send a multi-line message.\nUse TAB then ENTER for keyboard control.",
  5356.                 MUIA_Weight, 0,
  5357.                 MUIA_CycleChain, 1,
  5358.                 MUIA_UserData, id,
  5359.               End,
  5360.               Child, UWin->BB_WaitTCP = BusyObject,
  5361.                 MUIA_Busy_Speed, MUIV_Busy_Speed_Off,
  5362.               End,
  5363.               Child, UWin->CH_MultiSend = ImageObject,
  5364.                 MUIA_Frame, MUIV_Frame_ImageButton,
  5365.                 MUIA_InputMode, MUIV_InputMode_Toggle,
  5366.                 MUIA_Image_Spec, MUII_CheckMark,
  5367.                 MUIA_Image_FreeVert, TRUE,
  5368.                 MUIA_Selected, FALSE,
  5369.                 MUIA_Background, MUII_ButtonBack,
  5370.                 MUIA_ShowSelState, FALSE,
  5371.                 MUIA_CycleChain, 1,
  5372.                 MUIA_ShortHelp, "Tick this gadget to also send a message to\nall selected contacts in the contact list",
  5373.               End,
  5374.               Child, UWin->POP_Choices = PopobjectObject,
  5375.                 MUIA_Popstring_Button, PopButton(MUII_PopUp),
  5376.                 MUIA_CycleChain, 1,
  5377.                 MUIA_ShortHelp, "Commands that act\non this UIN.",
  5378.                 MUIA_Popobject_Object, GroupObject,
  5379.                   MUIA_Group_Spacing, 0,
  5380.                   MUIA_Frame, MUIV_Frame_String,
  5381.                   Child, UWin->BT_Auth = SimpleButton("Authorize"),
  5382.                   Child, UWin->BT_ChatReq = SimpleButton("Chat"),
  5383.                   Child, UWin->BT_Clear = SimpleButton("Clear Messages"),
  5384.                   Child, UWin->BT_FileSend = SimpleButton("FileDirect"),
  5385.                   Child, UWin->BT_Forward = SimpleButton("Forward"),
  5386.                   Child, UWin->BT_IgnoreMe = SimpleButton("Ignore"),
  5387.                   Child, UWin->BT_Contacts = SimpleButton("Send Contacts"),
  5388.                   Child, UWin->BT_WhitePage = SimpleButton("WhitePage"),
  5389.                 End,
  5390.               End,
  5391.             End,
  5392.             Child, HVSpace,
  5393.           End,
  5394.         End,
  5395.       End,
  5396.       Child, VGroup,
  5397.         Child, HGroup,
  5398.           MUIA_Group_Columns, 2,
  5399.           Child, Label("Description"),
  5400.           Child, UWin->STR_Desc = TextinputObject,
  5401.             MUIA_Frame, MUIV_Frame_String,
  5402.             MUIA_Textinput_Multiline, FALSE,
  5403.             MUIA_Textinput_MaxLen, 450,
  5404.             MUIA_Textinput_Contents, NULL,
  5405.             MUIA_CycleChain, 1,
  5406.           End,
  5407.           Child, Label("URL"),
  5408.           Child, UWin->STR_URL = TextinputObject,
  5409.             MUIA_Frame, MUIV_Frame_String,
  5410.             MUIA_Textinput_Multiline, FALSE,
  5411.             MUIA_Textinput_MaxLen, 450,
  5412.             MUIA_Textinput_Contents, NULL,
  5413.             MUIA_CycleChain, 1,
  5414.           End,
  5415.         End,
  5416.         Child, HGroup,
  5417.           Child, HSpace(0),
  5418.           Child, UWin->BT_URLSend = SimpleButton("Send This URL"),
  5419.           Child, HSpace(0),
  5420.         End,
  5421.       End,
  5422. /**/  Child, VGroup,
  5423.         Child, HGroup,
  5424.           Child, VGroup,
  5425.           Child, UWin->LV_InfoPages = NListviewObject,
  5426.             MUIA_CycleChain, TRUE,
  5427.             MUIA_NListview_NList, NListObject,
  5428.               MUIA_Frame, MUIV_Frame_InputList,
  5429.               MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String,
  5430.               MUIA_NList_DestructHook, MUIV_NList_DestructHook_String,
  5431.               MUIA_NList_AdjustWidth, TRUE,
  5432.               MUIA_NList_SourceArray, InfoPages,
  5433.             End,
  5434.            End,
  5435.           End,
  5436.           Child, UWin->GP_InfoPages = GroupObject,
  5437.             MUIA_Group_PageMode, TRUE,
  5438.             MUIA_Frame, MUIV_Frame_Group,
  5439.             Child, VGroup,
  5440.               Child, HVSpace,
  5441.               Child, HGroup,
  5442.                 MUIA_Frame, MUIV_Frame_Group,
  5443.                 MUIA_FrameTitle, "ICQ Number",
  5444.                 Child, Label("ICQ#"),
  5445.                 Child, UWin->TX_UIN = TextObject,
  5446.                   MUIA_Background, MUII_TextBack,
  5447.                   MUIA_Frame, MUIV_Frame_Text,
  5448.                   MUIA_Text_Contents, NULL,
  5449.                 End,
  5450.                 Child, Label("Current / Last IP"),
  5451.                 Child, UWin->TX_IP = TextObject,
  5452.                   MUIA_Background, MUII_TextBack,
  5453.                   MUIA_Frame, MUIV_Frame_Text,
  5454.                   MUIA_Text_Contents, NULL,
  5455.                 End,
  5456.               End,
  5457.               Child, HGroup,
  5458.                 MUIA_Frame, MUIV_Frame_Group,
  5459.                 MUIA_FrameTitle, "Name",
  5460.                 MUIA_Group_Columns, 4,
  5461.                 Child, Label("First Name"),
  5462.                 Child, UWin->STR_First = TextinputObject,
  5463.                   MUIA_Frame, MUIV_Frame_String,
  5464.                   MUIA_Textinput_Contents, NULL,
  5465.                   MUIA_CycleChain, TRUE,
  5466.                 End,
  5467.                 Child, Label("Last Name"),
  5468.                 Child, UWin->STR_Last = TextinputObject,
  5469.                   MUIA_Frame, MUIV_Frame_String,
  5470.                   MUIA_Textinput_Contents, NULL,
  5471.                   MUIA_CycleChain, TRUE,
  5472.                 End,
  5473.                 Child, Label("Nickname"),
  5474.                 Child, UWin->STR_Nick = TextinputObject,
  5475.                   MUIA_Frame, MUIV_Frame_String,
  5476.                   MUIA_Textinput_Contents, NULL,
  5477.                   MUIA_CycleChain, TRUE,
  5478.                 End,
  5479.                 Child, Label("Display"),
  5480.                 Child, HGroup,
  5481.                   Child, HSpace(0),
  5482.                   Child, CLabel("Coming soon..."),
  5483.                   Child, HSpace(0),
  5484.                 End,
  5485.               End,
  5486.               Child, HGroup,
  5487.                 MUIA_Frame, MUIV_Frame_Group,
  5488.                 MUIA_FrameTitle, "EMail Addresses",
  5489.                 MUIA_Group_Columns, 2,
  5490.                 Child, Label("Primary EMail"),
  5491.                 Child, UWin->STR_EMail = TextinputObject,
  5492.                   MUIA_Frame, MUIV_Frame_String,
  5493.                   MUIA_Textinput_Contents, NULL,
  5494.                   MUIA_Textinput_Editable, FALSE,
  5495.                   MUIA_CycleChain, TRUE,
  5496.                 End,
  5497.                 Child, HGroup,
  5498.                   Child, HSpace(0),
  5499.                   Child, UWin->CH_EditEMail = ImageObject,
  5500.                     MUIA_Frame, MUIV_Frame_ImageButton,
  5501.                     MUIA_InputMode, MUIV_InputMode_Toggle,
  5502.                     MUIA_Image_Spec, MUII_CheckMark,
  5503.                     MUIA_Image_FreeVert, TRUE,
  5504.                     MUIA_Selected, FALSE,
  5505.                     MUIA_Background, MUII_ButtonBack,
  5506.                     MUIA_ShowSelState, FALSE,
  5507.                     MUIA_CycleChain, TRUE,
  5508.                   End,
  5509.                 End,
  5510.                 Child, HGroup,
  5511.                   Child, LLabel("Don't update Primary EMail address"),
  5512.                   Child, HSpace(0),
  5513.                 End,
  5514.                 Child, Label("Secondary EMail"),
  5515.                 Child, UWin->TX_EMail2 = TextObject,
  5516.                   MUIA_Background, MUII_TextBack,
  5517.                   MUIA_Frame, MUIV_Frame_Text,
  5518.                   MUIA_Text_Contents, NULL,
  5519.                 End,
  5520.                 Child, Label("Old EMail"),
  5521.                 Child, UWin->TX_EMailOld = TextObject,
  5522.                   MUIA_Background, MUII_TextBack,
  5523.                   MUIA_Frame, MUIV_Frame_Text,
  5524.                   MUIA_Text_Contents, NULL,
  5525.                 End,
  5526.               End,
  5527.               Child, HVSpace,
  5528.             End,
  5529.             Child, VGroup,
  5530.               Child, HVSpace,
  5531.               Child, HGroup,
  5532.                 MUIA_Frame, MUIV_Frame_Group,
  5533.                 MUIA_FrameTitle, "Home Address",
  5534.                 MUIA_Group_Columns, 3,
  5535.                 Child, VGroup,
  5536.                   Child, CLabel("Street"),
  5537.                   Child, Label("Address"),
  5538.                 End,
  5539.                 Child, UWin->TI_StreetAd = TextinputObject,
  5540.                   MUIA_Frame, MUIV_Frame_String,
  5541.                   MUIA_Textinput_Multiline, TRUE,
  5542.                   MUIA_Textinput_Contents, NULL,
  5543.                   MUIA_Textinput_MaxLen, 512,
  5544.                   MUIA_Textinput_Editable, FALSE,
  5545.                 End,
  5546.                 Child, VGroup,
  5547.                   MUIA_Group_Columns, 2,
  5548.                   Child, Label("City"),
  5549.                   Child, UWin->TX_City = TextObject,
  5550.                     MUIA_Frame, MUIV_Frame_Text,
  5551.                     MUIA_Background, MUII_TextBack,
  5552.                     MUIA_Text_Contents, NULL,
  5553.                   End,
  5554.                   Child, Label("State"),
  5555.                   Child, UWin->TX_State = TextObject,
  5556.                     MUIA_Frame, MUIV_Frame_Text,
  5557.                     MUIA_Background, MUII_TextBack,
  5558.                     MUIA_Text_Contents, NULL,
  5559.                   End,
  5560.                   Child, Label("Zip Code"),
  5561.                   Child, UWin->TX_ZipCode = TextObject,
  5562.                     MUIA_Frame, MUIV_Frame_Text,
  5563.                     MUIA_Background, MUII_TextBack,
  5564.                     MUIA_Text_Contents, NULL,
  5565.                   End,
  5566.                 End,
  5567.                 Child, HSpace(0),
  5568.                 Child, UWin->BT_DisplayMap = SimpleButton("Display Map"),
  5569.                 Child, HGroup,
  5570.                   Child, Label("Country"),
  5571.                   Child, UWin->TX_Country = TextObject,
  5572.                     MUIA_Frame, MUIV_Frame_Text,
  5573.                     MUIA_Background, MUII_TextBack,
  5574.                     MUIA_Text_Contents, NULL,
  5575.                   End,
  5576.                 End,
  5577.               End,
  5578.               Child, HGroup,
  5579.                 Child, VGroup,
  5580.                   MUIA_Frame, MUIV_Frame_Group,
  5581.                   MUIA_FrameTitle, "Phone Directory Listings",
  5582.                   MUIA_Group_Columns, 2,
  5583.                   Child, Label("Phone"),
  5584.                   Child, UWin->TX_Phone = TextObject,
  5585.                     MUIA_Frame, MUIV_Frame_Text,
  5586.                     MUIA_Background, MUII_TextBack,
  5587.                     MUIA_Text_Contents, NULL,
  5588.                   End,
  5589.                   Child, Label("FAX"),
  5590.                   Child, UWin->TX_FAX = TextObject,
  5591.                     MUIA_Frame, MUIV_Frame_Text,
  5592.                     MUIA_Background, MUII_TextBack,
  5593.                     MUIA_Text_Contents, NULL,
  5594.                   End,
  5595.                   Child, Label("Cellular"),
  5596.                   Child, UWin->TX_Cellular = TextObject,
  5597.                     MUIA_Frame, MUIV_Frame_Text,
  5598.                     MUIA_Background, MUII_TextBack,
  5599.                     MUIA_Text_Contents, NULL,
  5600.                   End,
  5601.                 End,
  5602.                 Child, VGroup,
  5603.                   MUIA_Frame, MUIV_Frame_Group,
  5604.                   MUIA_FrameTitle, "Local Time",
  5605.                   MUIA_Group_Columns, 2,
  5606.                   Child, Label("Time Zone"),
  5607.                   Child, UWin->NU_TimeZone = SliderObject,
  5608.                     MUIA_Numeric_Max, 12,
  5609.                     MUIA_Numeric_Min, -12,
  5610.                   End,
  5611.                   Child, Label("Local Time"),
  5612.                   Child, UWin->TX_LocalTime = TextObject,
  5613.                     MUIA_Background, MUII_TextBack,
  5614.                     MUIA_Frame, MUIV_Frame_Text,
  5615.                     MUIA_Text_Contents, NULL,
  5616.                     MUIA_Text_PreParse, "\033c",
  5617.                   End,
  5618.                   Child, Label("User Time"),
  5619.                   Child, UWin->TX_UserTime = TextObject,
  5620.                     MUIA_Background, MUII_TextBack,
  5621.                     MUIA_Frame, MUIV_Frame_Text,
  5622.                     MUIA_Text_Contents, NULL,
  5623.                     MUIA_Text_PreParse, "\033c",
  5624.                   End,
  5625.                 End,
  5626.               End,
  5627.               Child, HVSpace,
  5628.             End,
  5629.             Child, VGroup,
  5630.               Child, HVSpace,
  5631.               Child, VGroup,
  5632.                 MUIA_Frame, MUIV_Frame_Group,
  5633.                 MUIA_FrameTitle, "Additional Details",
  5634.                 Child, HGroup,
  5635.                   Child, Label("Home Page"),
  5636.                   Child, UWin->BT_HomePage = TextObject,
  5637.                     MUIA_Frame, MUIV_Frame_Button,
  5638.                     MUIA_Font, MUIV_Font_Button,
  5639.                     MUIA_Text_Contents, NULL,
  5640.                     MUIA_Text_PreParse, "\33c",
  5641.                     MUIA_InputMode, MUIV_InputMode_RelVerify,
  5642.                     MUIA_Background, MUII_ButtonBack,
  5643.                     MUIA_UserData, id,
  5644.                     MUIA_CycleChain, TRUE,
  5645.                   End,
  5646.                 End,
  5647.                 Child, HGroup,
  5648.                   Child, Label("Gender"),
  5649.                   Child, UWin->TX_Sex = TextObject,
  5650.                     MUIA_Frame, MUIV_Frame_Text,
  5651.                     MUIA_Background, MUII_TextBack,
  5652.                     MUIA_Text_Contents, NULL,
  5653.                   End,
  5654.                   Child, Label("Age"),
  5655.                   Child, UWin->TX_Age = TextObject,
  5656.                     MUIA_Frame, MUIV_Frame_Text,
  5657.                     MUIA_Background, MUII_TextBack,
  5658.                     MUIA_Text_Contents, NULL,
  5659.                   End,
  5660.                   Child, UWin->BT_URLCategory = SimpleButton("Homepage Category"),
  5661.                 End,
  5662.               End,
  5663.               Child, VGroup,
  5664.                 MUIA_Frame, MUIV_Frame_Group,
  5665.                 MUIA_FrameTitle, "Birth Date & Horoscope",
  5666.                 Child, HGroup,
  5667.                   Child, Label("Month"),
  5668.                   Child, UWin->TX_BDMonth = TextObject,
  5669.                     MUIA_Frame, MUIV_Frame_Text,
  5670.                     MUIA_Background, MUII_TextBack,
  5671.                     MUIA_Text_Contents, NULL,
  5672.                   End,
  5673.                   Child, Label("Day"),
  5674.                   Child, UWin->TX_BDDay = TextObject,
  5675.                     MUIA_Frame, MUIV_Frame_Text,
  5676.                     MUIA_Background, MUII_TextBack,
  5677.                     MUIA_Text_Contents, NULL,
  5678.                   End,
  5679.                   Child, Label("Year"),
  5680.                   Child, UWin->TX_BDYear = TextObject,
  5681.                     MUIA_Frame, MUIV_Frame_Text,
  5682.                     MUIA_Background, MUII_TextBack,
  5683.                     MUIA_Text_Contents, NULL,
  5684.                   End,
  5685.                   Child, Label("Zodiac"),
  5686.                   Child, UWin->GP_DTGroup = GroupObject,
  5687.                     Child, UWin->DT_Zodiac = DatatypeObject,
  5688. //                    MUIA_Dtpic_Name, zodiac,
  5689.                     End,
  5690.                   End,
  5691.                 End,
  5692.                 Child, HGroup,
  5693.                   Child, UWin->CH_BDNotify = ImageObject,
  5694.                     MUIA_Frame, MUIV_Frame_ImageButton,
  5695.                     MUIA_InputMode, MUIV_InputMode_Toggle,
  5696.                     MUIA_Image_Spec, MUII_CheckMark,
  5697.                     MUIA_Image_FreeVert, TRUE,
  5698.                     MUIA_Selected, TRUE,
  5699.                     MUIA_Background, MUII_ButtonBack,
  5700.                     MUIA_ShowSelState, FALSE,
  5701.                     MUIA_CycleChain, TRUE,
  5702.                   End,
  5703.                   Child, LLabel("Notify me xx days before the birthday"),
  5704.                   Child, UWin->BT_ViewHoroscope = SimpleButton("View Horoscope"),
  5705.                 End,
  5706.               End,
  5707.               Child, VGroup,
  5708.                 MUIA_Frame, MUIV_Frame_Group,
  5709.                 MUIA_FrameTitle, "Spoken Languages",
  5710.                 Child, HGroup,
  5711.                   Child, UWin->TX_Lang1 = TextObject,
  5712.                     MUIA_Frame, MUIV_Frame_Text,
  5713.                     MUIA_Background, MUII_TextBack,
  5714.                     MUIA_Text_Contents, NULL,
  5715.                   End,
  5716.                   Child, UWin->TX_Lang2 = TextObject,
  5717.                     MUIA_Frame, MUIV_Frame_Text,
  5718.                     MUIA_Background, MUII_TextBack,
  5719.                     MUIA_Text_Contents, NULL,
  5720.                   End,
  5721.                   Child, UWin->TX_Lang3 = TextObject,
  5722.                     MUIA_Frame, MUIV_Frame_Text,
  5723.                     MUIA_Background, MUII_TextBack,
  5724.                     MUIA_Text_Contents, NULL,
  5725.                   End,
  5726.                 End,
  5727.               End,
  5728.               Child, HVSpace,
  5729.             End,
  5730.             Child, VGroup,
  5731.               Child, VGroup,
  5732.                 MUIA_Frame, MUIV_Frame_Group,
  5733.                 MUIA_FrameTitle, "Additional Details About The User",
  5734.                 Child, HGroup,
  5735.                   MUIA_Group_Spacing, 0,
  5736.                   Child, UWin->TE_About = TextEditorObject,
  5737.                     MUIA_Frame, MUIV_Frame_String,
  5738.                     MUIA_TextEditor_ReadOnly, TRUE,
  5739.                     MUIA_TextEditor_Slider, UWin->SC_AboutScroll,
  5740.                   End,
  5741.                   Child, UWin->SC_AboutScroll,
  5742.                 End,
  5743.               End,
  5744.               Child, VGroup,
  5745.                 MUIA_Frame, MUIV_Frame_Group,
  5746.                 MUIA_FrameTitle, "Enter Additional Info/Notes About The User",
  5747.                 Child, HGroup,
  5748.                   MUIA_Group_Spacing, 0,
  5749.                   Child, UWin->TE_Comment = TextEditorObject,
  5750.                     MUIA_Frame, MUIV_Frame_String,
  5751.                     MUIA_TextEditor_Slider, UWin->SC_CommentScroll,
  5752.                     MUIA_CycleChain, TRUE,
  5753.                   End,
  5754.                   Child, UWin->SC_CommentScroll,
  5755.                 End,
  5756.               End,
  5757.             End,
  5758.             Child, VGroup,
  5759.               Child, HVSpace,
  5760.               Child, VGroup,
  5761.                 MUIA_Frame, MUIV_Frame_Group,
  5762.                 MUIA_FrameTitle, "Options",
  5763.                 MUIA_Group_Columns, 3,
  5764.                 Child, UWin->CH_SeeInvis = ImageObject,
  5765.                   MUIA_Frame, MUIV_Frame_ImageButton,
  5766.                   MUIA_InputMode, MUIV_InputMode_Toggle,
  5767.                   MUIA_Image_Spec, MUII_CheckMark,
  5768.                   MUIA_Image_FreeVert, TRUE,
  5769.                   MUIA_Selected, user->SeeInvis,
  5770.                   MUIA_Background, MUII_ButtonBack,
  5771.                   MUIA_ShowSelState, FALSE,
  5772.                   MUIA_CycleChain, TRUE,
  5773.                   MUIA_ShortHelp, "Tick this box to allow this user to\nsee you while you are 'Invisible'",
  5774.                   MUIA_UserData, id,
  5775.                 End,
  5776.                 Child, LLabel("Visible To User"),
  5777.                 Child, HSpace(0),
  5778.                 Child, UWin->CH_BeInvis = ImageObject,
  5779.                   MUIA_Frame, MUIV_Frame_ImageButton,
  5780.                   MUIA_InputMode, MUIV_InputMode_Toggle,
  5781.                   MUIA_Image_Spec, MUII_CheckMark,
  5782.                   MUIA_Image_FreeVert, TRUE,
  5783.                   MUIA_Selected, user->BeInvis,
  5784.                   MUIA_Background, MUII_ButtonBack,
  5785.                   MUIA_ShowSelState, FALSE,
  5786.                   MUIA_CycleChain, TRUE,
  5787.                   MUIA_ShortHelp, "Tick this box and this user\nwill never see you Online",
  5788.                   MUIA_UserData, id,
  5789.                 End,
  5790.                 Child, LLabel("Invisible To User"),
  5791.                 Child, HSpace(0),
  5792.               End,
  5793.               Child, VGroup,
  5794.                 MUIA_Frame, MUIV_Frame_Group,
  5795.                 MUIA_FrameTitle, "Last Seen",
  5796.                 MUIA_Group_Columns, 2,
  5797.                 Child, Label("Connecté"),
  5798.                 Child, UWin->TX_LastOnline = TextObject,
  5799.                   MUIA_Frame, MUIV_Frame_Text,
  5800.                   MUIA_Background, MUII_TextBack,
  5801.                   MUIA_Text_Contents, NULL,
  5802.                 End,
  5803.                 Child, Label("Message To"),
  5804.                 Child, UWin->TX_MessageTo = TextObject,
  5805.                   MUIA_Frame, MUIV_Frame_Text,
  5806.                   MUIA_Background, MUII_TextBack,
  5807.                   MUIA_Text_Contents, NULL,
  5808.                 End,
  5809.                 Child, Label("Message From"),
  5810.                 Child, UWin->TX_MessageFm = TextObject,
  5811.                   MUIA_Frame, MUIV_Frame_Text,
  5812.                   MUIA_Background, MUII_TextBack,
  5813.                   MUIA_Text_Contents, NULL,
  5814.                 End,
  5815.               End,
  5816.               Child, HVSpace,
  5817.             End,
  5818.           End,
  5819.         End,
  5820.         Child, HGroup,
  5821.           Child, UWin->BT_Load = SimpleButton("Load"),
  5822.           Child, UWin->BT_Save = SimpleButton("Save"),
  5823.           Child, UWin->BT_Query = SimpleButton("Refresh"),
  5824.         End,
  5825.       End,
  5826. /**/  Child, VGroup,
  5827.         Child, UWin->LV_History = NListviewObject,
  5828.           MUIA_NListview_NList, NListObject,
  5829.             MUIA_Frame, MUIV_Frame_ReadList,
  5830.             MUIA_NList_TypeSelect, MUIV_NList_TypeSelect_Char,
  5831.             MUIA_NList_MultiSelect, MUIV_NList_MultiSelect_Default,
  5832.             MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String,
  5833.             MUIA_NList_DestructHook, MUIV_NList_DestructHook_String,
  5834.           End,
  5835.         End,
  5836.         Child, VGroup,
  5837.         Child, HGroup,
  5838.           Child, UWin->BT_LoadHist = KeyButton("Load",'l'),
  5839.           Child, UWin->BT_ClearHist = KeyButton("Clear",'c'),
  5840.           Child, UWin->BT_SaveHist = KeyButton("Save",'s'),
  5841.           Child, UWin->BT_DeleteHist = KeyButton("Delete",'d'),
  5842.         End,
  5843.         Child, HGroup,
  5844.           Child, UWin->BT_RemoveLine = KeyButton("Remove Line",'r'),
  5845.           Child, UWin->BT_SelLine = SimpleButton("SelLine"),
  5846.           Child, UWin->BT_SelChar = SimpleButton("SelChar"),
  5847.         End,
  5848.         End,
  5849.      /* ICI!! */
  5850.  
  5851.       End,
  5852.     End,
  5853.   End,
  5854. End;
  5855.  
  5856. if (!UWin->WI_UserWindow) {
  5857.   HandleError(DBG_OTH_FATL,"Could not create User Window.");
  5858.   if (UWin->SC_AboutScroll) MUI_DisposeObject(UWin->SC_AboutScroll);
  5859.   if (UWin->SC_CommentScroll) MUI_DisposeObject(UWin->SC_CommentScroll);
  5860.   FreeVec(UWin);
  5861.   UWin = NULL;
  5862.   return(FALSE);
  5863. }
  5864.  
  5865. user->UWin = UWin;
  5866.  
  5867. DoMethod(app->App,OM_ADDMEMBER,UWin->WI_UserWindow);
  5868.  
  5869. set(UWin->BT_IgnoreMe,MUIA_UserData,id);
  5870. set(UWin->BT_ChatReq,MUIA_UserData,id);
  5871. set(UWin->BT_FileSend,MUIA_UserData,id);
  5872. set(UWin->BT_Forward,MUIA_UserData,id);
  5873. set(UWin->BT_Save,MUIA_UserData,id);
  5874. set(UWin->BT_Query,MUIA_UserData,id);
  5875. set(UWin->BT_URLSend,MUIA_UserData,id);
  5876. set(UWin->BT_Auth,MUIA_UserData,id);
  5877. set(UWin->BT_HomePage,MUIA_UserData,id);
  5878. set(UWin->BT_LoadHist,MUIA_UserData,id);
  5879. set(UWin->BT_SaveHist,MUIA_UserData,id);
  5880. set(UWin->BT_DeleteHist,MUIA_UserData,id);
  5881. set(UWin->LV_Msgs,MUIA_UserData,id);
  5882. set(UWin->BT_Contacts,MUIA_UserData,id);
  5883. set(UWin->BT_WhitePage,MUIA_UserData,id);
  5884.  
  5885. set(UWin->BB_WaitTCP,MUIA_ShowMe,FALSE);
  5886. set(UWin->BT_SendIt,MUIA_ShowMe,multiline);
  5887.  
  5888. set(UWin->BT_URLSend,MUIA_CycleChain,TRUE);
  5889. set(UWin->BT_IgnoreMe,MUIA_CycleChain,TRUE);
  5890. set(UWin->BT_Clear,MUIA_CycleChain,TRUE);
  5891. set(UWin->BT_Auth,MUIA_CycleChain,TRUE);
  5892. set(UWin->BT_ChatReq,MUIA_CycleChain,TRUE);
  5893. set(UWin->BT_FileSend,MUIA_CycleChain,TRUE);
  5894. set(UWin->BT_Forward,MUIA_CycleChain,TRUE);
  5895. set(UWin->BT_Contacts,MUIA_CycleChain,TRUE);
  5896. set(UWin->BT_WhitePage,MUIA_CycleChain,TRUE);
  5897. set(UWin->BT_Load,MUIA_CycleChain,TRUE);
  5898. set(UWin->BT_Save,MUIA_CycleChain,TRUE);
  5899. set(UWin->BT_Query,MUIA_CycleChain,TRUE);
  5900. set(UWin->BT_URLCategory,MUIA_CycleChain,TRUE);
  5901. set(UWin->BT_DisplayMap,MUIA_CycleChain,TRUE);
  5902. set(UWin->CH_EditEMail,MUIA_CycleChain,TRUE);
  5903.  
  5904. if (!usetime) set(UWin->LV_Msgs,MUIA_NList_Format,"COL=0 BAR,COL=2");
  5905.  
  5906. UpdateUserWin(user);
  5907.  
  5908. DoMethod(UWin->WI_UserWindow, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, UWin->WI_UserWindow, 3,
  5909.          MUIM_Set, MUIA_Window_Open, FALSE);
  5910.  
  5911. DoMethod(UWin->BT_Clear, MUIM_Notify, MUIA_Pressed, FALSE, UWin->LV_Msgs, 1,
  5912.          MUIM_NList_Clear);
  5913.  
  5914. DoMethod(UWin->BT_Clear, MUIM_Notify, MUIA_Pressed, FALSE, UWin->POP_Choices, 1,
  5915.          MUIM_Popstring_Close);
  5916.  
  5917. DoMethod(UWin->TI_QuickMsg, MUIM_Notify, MUIA_Textinput_Acknowledge, MUIV_EveryTime, UWin->TI_QuickMsg, 2,
  5918.          MUIM_CallHook, &SendMsg2ICQaHook);
  5919.  
  5920. DoMethod(UWin->BT_SendIt, MUIM_Notify, MUIA_Pressed, FALSE, UWin->TI_QuickMsg, 2,
  5921.          MUIM_CallHook, &SendMsg2ICQaHook);
  5922.  
  5923. DoMethod(UWin->BT_IgnoreMe, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_IgnoreMe, 2,
  5924.          MUIM_CallHook, &Add2IgnoreHook);
  5925.  
  5926. DoMethod(UWin->BT_IgnoreMe, MUIM_Notify, MUIA_Pressed, FALSE, UWin->POP_Choices, 1,
  5927.          MUIM_Popstring_Close);
  5928.  
  5929. DoMethod(UWin->BT_Auth, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_Auth, 2,
  5930.          MUIM_CallHook, &SendMsg2ICQaHook);
  5931.  
  5932. DoMethod(UWin->BT_Auth, MUIM_Notify, MUIA_Pressed, FALSE, UWin->POP_Choices, 1,
  5933.          MUIM_Popstring_Close);
  5934.  
  5935. DoMethod(UWin->BT_ChatReq, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_ChatReq, 2,
  5936.          MUIM_CallHook, &OpenChatReqWinHook);
  5937.  
  5938. DoMethod(UWin->BT_ChatReq, MUIM_Notify, MUIA_Pressed, FALSE, UWin->POP_Choices, 1,
  5939.          MUIM_Popstring_Close);
  5940.  
  5941. DoMethod(UWin->BT_FileSend, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_FileSend, 2,
  5942.          MUIM_CallHook, &OpenFileDirectWinHook);
  5943.  
  5944. DoMethod(UWin->BT_FileSend, MUIM_Notify, MUIA_Pressed, FALSE, UWin->POP_Choices, 1,
  5945.          MUIM_Popstring_Close);
  5946.  
  5947. DoMethod(UWin->BT_Forward, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_Forward, 2,
  5948.          MUIM_CallHook, &ForwardMsgHook);
  5949.  
  5950. DoMethod(UWin->BT_Forward, MUIM_Notify, MUIA_Pressed, FALSE, UWin->POP_Choices, 1,
  5951.          MUIM_Popstring_Close);
  5952.  
  5953. DoMethod(UWin->BT_Contacts, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_Contacts, 2,
  5954.          MUIM_CallHook, &ShareContactsHook);
  5955.  
  5956. DoMethod(UWin->BT_Contacts, MUIM_Notify, MUIA_Pressed, FALSE, UWin->POP_Choices, 1,
  5957.          MUIM_Popstring_Close);
  5958.  
  5959. DoMethod(UWin->BT_WhitePage, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_WhitePage, 2,
  5960.          MUIM_CallHook, &GoURLHook);
  5961.  
  5962. DoMethod(UWin->BT_WhitePage, MUIM_Notify, MUIA_Pressed, FALSE, UWin->POP_Choices, 1,
  5963.          MUIM_Popstring_Close);
  5964.  
  5965. DoMethod(UWin->BT_URLSend, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_URLSend, 2,
  5966.          MUIM_CallHook, &SendMsg2ICQaHook);
  5967.  
  5968. DoMethod(UWin->BT_Query, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_Query, 2,
  5969.          MUIM_CallHook, &GetUINInfoHook);
  5970.  
  5971. DoMethod(UWin->CH_SeeInvis, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, UWin->CH_SeeInvis, 2,
  5972.          MUIM_CallHook, &SetUserVisPrefsHook);
  5973.  
  5974. DoMethod(UWin->CH_BeInvis, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, UWin->CH_BeInvis, 2,
  5975.          MUIM_CallHook, &SetUserVisPrefsHook);
  5976.  
  5977. DoMethod(UWin->BT_Save, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_Save, 2,
  5978.          MUIM_CallHook, &SaveContactJumpHook);
  5979.  
  5980. DoMethod(UWin->BT_LoadHist, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_LoadHist, 2,
  5981.          MUIM_CallHook, &LoadHistoryHook);
  5982.  
  5983. DoMethod(UWin->BT_RemoveLine, MUIM_Notify, MUIA_Pressed, FALSE, UWin->LV_History, 2,
  5984.          MUIM_NList_Remove, MUIV_NList_Remove_Selected);
  5985.  
  5986. // Added
  5987.  
  5988. DoMethod(UWin->BT_SelLine, MUIM_Notify, MUIA_Pressed,FALSE, UWin->LV_History, 3,
  5989.            MUIM_Set, MUIA_NList_TypeSelect, MUIV_NList_TypeSelect_Line);
  5990.  
  5991. // Added
  5992.  
  5993. DoMethod(UWin->BT_SelChar, MUIM_Notify, MUIA_Pressed,FALSE, UWin->LV_History, 3,
  5994.            MUIM_Set, MUIA_NList_TypeSelect, MUIV_NList_TypeSelect_Char);
  5995.  
  5996.  
  5997. DoMethod(UWin->BT_ClearHist, MUIM_Notify, MUIA_Pressed, FALSE, UWin->LV_History, 1,
  5998.          MUIM_NList_Clear);
  5999.  
  6000. DoMethod(UWin->BT_SaveHist, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_SaveHist, 2,
  6001.          MUIM_CallHook, &SaveHistoryHook);
  6002.  
  6003. DoMethod(UWin->BT_DeleteHist, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_DeleteHist, 2,
  6004.          MUIM_CallHook, &DeleteHistoryHook);
  6005.  
  6006. DoMethod(UWin->LV_Msgs, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, UWin->LV_Msgs, 2,
  6007.          MUIM_CallHook, &GoURLHook);
  6008.  
  6009. DoMethod(UWin->BT_HomePage, MUIM_Notify, MUIA_Pressed, FALSE, UWin->BT_HomePage, 2,
  6010.          MUIM_CallHook, &GoURLHook);
  6011.  
  6012. DoMethod(UWin->LV_InfoPages, MUIM_Notify, MUIA_NList_EntryClick, MUIV_EveryTime, UWin->GP_InfoPages, 3,
  6013.          MUIM_Set, MUIA_Group_ActivePage, MUIV_TriggerValue);
  6014.  
  6015. DoMethod(UWin->CH_EditEMail, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, UWin->STR_EMail, 3,
  6016.          MUIM_Set, MUIA_Textinput_Editable, MUIV_TriggerValue);
  6017.  
  6018. DoMethod(UWin->CH_EditEMail, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, UWin->CH_EditEMail, 2,
  6019.          MUIM_CallHook, &SetUserVisPrefsHook);
  6020.  
  6021. return(TRUE);
  6022.  
  6023. }
  6024.  
  6025.  
  6026. struct Contact *GetContact(ULONG uin)
  6027.  
  6028. {
  6029.  
  6030. int i;
  6031.  
  6032. ULONG total;
  6033.  
  6034. struct Contact *user;
  6035.  
  6036. get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  6037.  
  6038. for(i = 0; i < total; i++) {
  6039.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  6040.   if (user) if (user->UIN == uin) {
  6041.     user->ListID = i;
  6042.     return(user);
  6043.   }
  6044. }
  6045.  
  6046. return(NULL);
  6047.  
  6048. }
  6049.  
  6050.  
  6051. struct Sockets *GetSocketFmSocket(UWORD sock)
  6052.  
  6053. {
  6054.  
  6055. int i;
  6056.  
  6057. ULONG total;
  6058.  
  6059. struct Sockets *socks;
  6060.  
  6061. if (sock < 0) return(NULL);
  6062.  
  6063. get(app->LV_SockList,MUIA_NList_Entries,&total);
  6064.  
  6065. if (!total) return(NULL);
  6066.  
  6067. for(i = 0; i < total; i++) {
  6068.   DoMethod(app->LV_SockList,MUIM_NList_GetEntry,i,&socks);
  6069.   if (socks) if (socks->Socket == sock) return(socks);
  6070. }
  6071.  
  6072. return(NULL);
  6073.  
  6074. }
  6075.  
  6076.  
  6077. struct Sockets *GetSocketFmPort(UWORD port)
  6078.  
  6079. {
  6080.  
  6081. int i;
  6082.  
  6083. ULONG total;
  6084.  
  6085. struct Sockets *socks;
  6086.  
  6087. HandleError(DBG_TCP_DBUG,"GetSocketFmPort(%d)",port);
  6088.  
  6089. if (port < 0) return(NULL);
  6090.  
  6091. get(app->LV_SockList,MUIA_NList_Entries,&total);
  6092.  
  6093. if (!total) return(NULL);
  6094.  
  6095. for(i = 0; i < total; i++) {
  6096.   DoMethod(app->LV_SockList,MUIM_NList_GetEntry,i,&socks);
  6097.   if (socks) {
  6098.     if (socks->Port == port) {
  6099.       HandleError(DBG_TCP_DBUG,"Socket %d has port %d",socks->Socket,socks->Port);
  6100.       return(socks);
  6101.     }
  6102.   }
  6103. }
  6104.  
  6105. return(NULL);
  6106.  
  6107. }
  6108.  
  6109.  
  6110. struct Sockets *GetSocketFmContact(struct Contact *user, UBYTE type)
  6111.  
  6112. {
  6113.  
  6114. int i;
  6115.  
  6116. ULONG total;
  6117.  
  6118. struct Sockets *socks;
  6119.  
  6120. if (!user) return(NULL);
  6121.  
  6122. get(app->LV_SockList,MUIA_NList_Entries,&total);
  6123.  
  6124. if (!total) return(NULL);
  6125.  
  6126. for(i = 0; i < total; i++) {
  6127.   DoMethod(app->LV_SockList,MUIM_NList_GetEntry,i,&socks);
  6128.   if (socks) if (socks->UIN == user->UIN && socks->Type == type && socks->Dir != TCP_DIR_LISTEN) return(socks);
  6129. }
  6130.  
  6131. return(NULL);
  6132.  
  6133. }
  6134.  
  6135.  
  6136. void UpdateUserWin(struct Contact *user)
  6137.  
  6138. {
  6139.  
  6140. LONG zone;
  6141.  
  6142. struct ColorText *ct;
  6143.  
  6144. if (!user) return;
  6145. if (!user->UWin) return;
  6146. if (!user->UWin->WI_UserWindow) return;
  6147.  
  6148. set(user->UWin->STR_Nick,MUIA_String_Contents,user->Nick);
  6149.  
  6150. sprintf(user->UWin->UIN,"%ld",user->UIN);
  6151. set(user->UWin->TX_UIN,MUIA_Text_Contents,user->UWin->UIN);
  6152.  
  6153. ct = GetStatus(user->Status);
  6154. strcpy(user->UWin->Status,ct->Status);
  6155.  
  6156. if (user->Status & STATUSF_HIDEIP) strcpy(user->UWin->IP,"Hidden");
  6157. else sprintf(user->UWin->IP,"%s:%ld",Inet_NtoA(user->IP),user->Port);
  6158. set(user->UWin->TX_IP,MUIA_Text_Contents,user->UWin->IP);
  6159.  
  6160. set(user->UWin->STR_First,MUIA_String_Contents,user->First);
  6161. set(user->UWin->STR_Last,MUIA_String_Contents,user->Last);
  6162. set(user->UWin->STR_EMail,MUIA_String_Contents,user->EMail);
  6163. set(user->UWin->TX_EMail2,MUIA_String_Contents,user->EMail_Secondary);
  6164. set(user->UWin->TX_EMailOld,MUIA_String_Contents,user->EMail_Old);
  6165.  
  6166. set(user->UWin->TI_StreetAd,MUIA_Textinput_Contents,user->Street);
  6167.  
  6168. set(user->UWin->TX_City,MUIA_Text_Contents,user->City);
  6169.  
  6170. if (user->Country == 0xffff) strcpy(user->UWin->Country,"Unspecified");
  6171. else sprintf(user->UWin->Country,"%s",FindCountryName(user->Country));
  6172. set(user->UWin->TX_Country,MUIA_Text_Contents,user->UWin->Country);
  6173.  
  6174. zone = user->TimeZone;
  6175.  
  6176. set(user->UWin->NU_TimeZone,MUIA_Numeric_Value,zone);
  6177.  
  6178. set(user->UWin->TX_State,MUIA_Text_Contents,user->State);
  6179. set(user->UWin->TX_ZipCode,MUIA_Text_Contents,user->ZipCode);
  6180.  
  6181. if (user->Age == 0xffff) strcpy(user->UWin->Age,"Unspecified");
  6182. else sprintf(user->UWin->Age,"%d",user->Age);
  6183. set(user->UWin->TX_Age,MUIA_Text_Contents,user->UWin->Age);
  6184.  
  6185. switch(user->Sex) {
  6186.   case 0x00:
  6187.     strcpy(user->UWin->Sex,"Unspecified");
  6188.     break;
  6189.   case 0x01:
  6190.     strcpy(user->UWin->Sex,"Female");
  6191.     break;
  6192.   case 0x02:
  6193.     strcpy(user->UWin->Sex,"Male");
  6194.     break;
  6195. };
  6196. set(user->UWin->TX_Sex,MUIA_Text_Contents,user->UWin->Sex);
  6197.  
  6198. if (user->BDay_Day) sprintf(user->UWin->Day,"%d",user->BDay_Day);
  6199. else strcpy(user->UWin->Day,"N/A");
  6200. if (user->BDay_Year) sprintf(user->UWin->Year,"%d",user->BDay_Year);
  6201. else strcpy(user->UWin->Year,"N/A");
  6202.  
  6203. set(user->UWin->TX_BDMonth,MUIA_Text_Contents,Months[user->BDay_Month]);
  6204. set(user->UWin->TX_BDDay,MUIA_Text_Contents,user->UWin->Day);
  6205. set(user->UWin->TX_BDYear,MUIA_Text_Contents,user->UWin->Year);
  6206.  
  6207. set(user->UWin->TX_Lang1,MUIA_Text_Contents,Languages[user->Language1]);
  6208. set(user->UWin->TX_Lang2,MUIA_Text_Contents,Languages[user->Language2]);
  6209. set(user->UWin->TX_Lang3,MUIA_Text_Contents,Languages[user->Language3]);
  6210.  
  6211. set(user->UWin->TX_Phone,MUIA_Text_Contents,user->Phone);
  6212. set(user->UWin->TX_FAX,MUIA_Text_Contents,user->FAX);
  6213. set(user->UWin->TX_Cellular,MUIA_Text_Contents,user->Cellular);
  6214. set(user->UWin->BT_HomePage,MUIA_Text_Contents,user->HomePage);
  6215.  
  6216. set(user->UWin->TE_About,MUIA_TextEditor_Contents,user->About);
  6217.  
  6218. set(user->UWin->TE_Comment,MUIA_TextEditor_Contents,user->Comment);
  6219.  
  6220. sprintf(user->UWin->Title,"%ld %s (%s)",user->UIN,user->Nick,user->UWin->Status);
  6221. set(user->UWin->WI_UserWindow,MUIA_Window_Title,user->UWin->Title);
  6222.  
  6223. set(user->UWin->CH_SeeInvis,MUIA_Selected,user->SeeInvis);
  6224. set(user->UWin->CH_BeInvis,MUIA_Selected,user->BeInvis);
  6225.  
  6226. sprintf(user->UWin->LastOnline,"%s",ctime(&user->LastOnline));
  6227. sprintf(user->UWin->MessageTo,"%s",ctime(&user->LastMessageTo));
  6228. sprintf(user->UWin->MessageFm,"%s",ctime(&user->LastMessageFm));
  6229.  
  6230. LASTCHAR(user->UWin->LastOnline) = '\0';
  6231. LASTCHAR(user->UWin->MessageTo) = '\0';
  6232. LASTCHAR(user->UWin->MessageFm) = '\0';
  6233.  
  6234. set(user->UWin->TX_LastOnline,MUIA_Text_Contents,user->UWin->LastOnline);
  6235. set(user->UWin->TX_MessageTo,MUIA_Text_Contents,user->UWin->MessageTo);
  6236. set(user->UWin->TX_MessageFm,MUIA_Text_Contents,user->UWin->MessageFm);
  6237.  
  6238. if (user->BDay_Day > 0 && user->BDay_Year > 0) ChangeZodiacPic(user,FALSE);
  6239.  
  6240. return;
  6241.  
  6242. }
  6243.  
  6244.  
  6245. struct ColorText *GetStatus(ULONG status)
  6246.  
  6247. {
  6248.  
  6249. ULONG bday, stat;
  6250.  
  6251. static struct ColorText cd;
  6252.  
  6253. bday = status & STATUSF_BIRTHDAY;
  6254. stat = status & STATUS_OFFLINE;
  6255.  
  6256. switch(stat) {
  6257.   case STATUS_ONLINE:
  6258.   case STAT_ONLINE_99:
  6259.     sprintf(cd.Status,"Online");
  6260.     cd.Pen = Pens.StatusColors[ONLINE];
  6261.     break;
  6262.   case STATUS_AWAY:
  6263.   case STAT_AWAY_99:
  6264.     sprintf(cd.Status,"Away");
  6265.     cd.Pen = Pens.StatusColors[AWAY];
  6266.     break;
  6267.   case STAT_DND:
  6268.   case STAT_DND_2:
  6269.   case STAT_DND_3:
  6270.     sprintf(cd.Status,"DND");
  6271.     cd.Pen = Pens.StatusColors[DONOTDISTURB];
  6272.     break;
  6273.   case STAT_INVISIBLE:
  6274.     sprintf(cd.Status,"Invisible");
  6275.     cd.Pen = Pens.StatusColors[INVISIBLE];
  6276.     break;
  6277.   case STATUS_OFFLINE:
  6278.     sprintf(cd.Status,"Offline");
  6279.     cd.Pen = Pens.StatusColors[OFFLINE];
  6280.     break;
  6281.   case STATUS_NA:
  6282.   case STAT_NA_99:
  6283.     sprintf(cd.Status,"Not Available");
  6284.     cd.Pen = Pens.StatusColors[NOTAVAILABLE];
  6285.     break;
  6286.   case STAT_FREE_CHAT:
  6287.   case STAT_FREE_CHAT_99:
  6288.     sprintf(cd.Status,"Free For Chat");
  6289.     cd.Pen = Pens.StatusColors[FREEFORCHAT];
  6290.     break;
  6291.   case STAT_OCCUPIED:
  6292.   case STAT_OCCUPIED_99:
  6293.     sprintf(cd.Status,"Occupied");
  6294.     cd.Pen = Pens.StatusColors[OCCUPIED];
  6295.     break;
  6296.   case STATUS_NEWUIN:
  6297.     sprintf(cd.Status,"New User");
  6298.     cd.Pen = Pens.StatusColors[NEWUSER];
  6299.     break;
  6300.   default:
  6301.     sprintf(cd.Status,"%08x",status);
  6302.     cd.Pen = 2;
  6303. }
  6304.  
  6305. return(&cd);
  6306.  
  6307. }
  6308.  
  6309.  
  6310. void SaveContact(ULONG uin)
  6311.  
  6312. {
  6313.  
  6314. char buf[512];
  6315.  
  6316. struct AsyncFile *save_fh;
  6317. struct Contact *user;
  6318.  
  6319. if (!(user = GetContact(uin))) return;
  6320.  
  6321. if (user->Status == STATUS_NEWUIN) return;
  6322.  
  6323. sprintf(userstat_fl,"%s%ld",userdir_fl,uin);
  6324.  
  6325. if (!(save_fh = OpenAsync(userstat_fl,MODE_WRITE,AsyncBuf))) {
  6326.   HandleError(DBG_OTH_INFO,"Could not open '%s' for saving.",userstat_fl);
  6327.   return;
  6328. }
  6329.  
  6330. sprintf(buf,"NICK=%s\n",(user->Nick?user->Nick:LINE));
  6331. WriteLineAsync(save_fh,buf);
  6332.  
  6333. sprintf(buf,"FIRST=%s\n",(user->First?user->First:LINE));
  6334. WriteLineAsync(save_fh,buf);
  6335.  
  6336. sprintf(buf,"LAST=%s\n",(user->Last?user->Last:LINE));
  6337. WriteLineAsync(save_fh,buf);
  6338.  
  6339. sprintf(buf,"EMAIL=%s\n",(user->EMail?user->EMail:LINE));
  6340. WriteLineAsync(save_fh,buf);
  6341.  
  6342. sprintf(buf,"CITY=%s\n",(user->City?user->City:LINE));
  6343. WriteLineAsync(save_fh,buf);
  6344.  
  6345. sprintf(buf,"STATE=%s\n",(user->State?user->State:LINE));
  6346. WriteLineAsync(save_fh,buf);
  6347.  
  6348. sprintf(buf,"PHONE=%s\n",(user->Phone?user->Phone:LINE));
  6349. WriteLineAsync(save_fh,buf);
  6350.  
  6351. sprintf(buf,"HOMEPAGE=%s\n",(user->HomePage?user->HomePage:LINE));
  6352. WriteLineAsync(save_fh,buf);
  6353.  
  6354. sprintf(buf,"COUNTRY=%d\n",user->Country);
  6355. WriteLineAsync(save_fh,buf);
  6356.  
  6357. sprintf(buf,"AGE=%d\n",user->Age);
  6358. WriteLineAsync(save_fh,buf);
  6359.  
  6360. sprintf(buf,"SEX=%d\n",user->Sex);
  6361. WriteLineAsync(save_fh,buf);
  6362.  
  6363. sprintf(buf,"AUTHORIZE=%d\n",user->Authorize);
  6364. WriteLineAsync(save_fh,buf);
  6365.  
  6366. sprintf(buf,"SEEINVIS=%d\n",user->SeeInvis);
  6367. WriteLineAsync(save_fh,buf);
  6368.  
  6369. WriteLineAsync(save_fh,"ABOUT=\n");
  6370.  
  6371. sprintf(buf,"%s\n;\n",(user->About?user->About:LINE));
  6372. WriteLineAsync(save_fh,buf);
  6373.  
  6374. WriteLineAsync(save_fh,"COMMENT=\n");
  6375.  
  6376. sprintf(buf,"%s\n;\n",(user->Comment?user->Comment:LINE));
  6377. WriteLineAsync(save_fh,buf);
  6378.  
  6379. sprintf(buf,"NEWMSGS=%d\n",user->NewMsg);
  6380. WriteLineAsync(save_fh,buf);
  6381.  
  6382. sprintf(buf,"TIMEZONE=%d\n",user->TimeZone);
  6383. WriteLineAsync(save_fh,buf);
  6384.  
  6385. sprintf(buf,"BEINVIS=%d\n",user->BeInvis);
  6386. WriteLineAsync(save_fh,buf);
  6387.  
  6388. sprintf(buf,"LASTONLINE=%ld\n",user->LastOnline);
  6389. WriteLineAsync(save_fh,buf);
  6390.  
  6391. sprintf(buf,"LASTMESSAGEFM=%ld\n",user->LastMessageFm);
  6392. WriteLineAsync(save_fh,buf);
  6393.  
  6394. sprintf(buf,"LASTMESSAGETO=%ld\n",user->LastMessageTo);
  6395. WriteLineAsync(save_fh,buf);
  6396.  
  6397. CloseAsync(save_fh);
  6398.  
  6399. user->Changed = FALSE;
  6400.  
  6401. SetComment(userstat_fl,user->Nick);
  6402.  
  6403. return;
  6404.  
  6405. }
  6406.  
  6407.  
  6408. void __asm SaveContactJump(REG(a2) APTR obj)
  6409.  
  6410. {
  6411.  
  6412. char *tmp, about[512];
  6413.  
  6414. int i;
  6415.  
  6416. ULONG id = 0, total = 0;
  6417.  
  6418. struct Contact User, *user;
  6419.  
  6420. PrepNewContact(&User);
  6421.  
  6422. get(obj,MUIA_UserData,&id);
  6423.  
  6424. user = GetContact(id);
  6425.  
  6426. get(user->UWin->STR_Nick,MUIA_Textinput_Contents,&tmp);
  6427. User.Nick = tmp;
  6428.  
  6429. get(user->UWin->STR_First,MUIA_Textinput_Contents,&tmp);
  6430. User.First = tmp;
  6431.  
  6432. get(user->UWin->STR_Last,MUIA_Textinput_Contents,&tmp);
  6433. User.Last = tmp;
  6434.  
  6435. get(user->UWin->STR_EMail,MUIA_Textinput_Contents,&tmp);
  6436. User.EMail = tmp;
  6437.  
  6438. get(user->UWin->TX_City,MUIA_Text_Contents,&tmp);
  6439. User.City = tmp;
  6440.  
  6441. get(user->UWin->TX_State,MUIA_Text_Contents,&tmp);
  6442. User.State = tmp;
  6443.  
  6444. get(user->UWin->TX_Phone,MUIA_Text_Contents,&tmp);
  6445. User.Phone = tmp;
  6446.  
  6447. get(user->UWin->BT_HomePage,MUIA_Text_Contents,&tmp);
  6448. User.HomePage = tmp;
  6449.  
  6450. strcpy(about,user->About);
  6451.  
  6452. User.UIN = user->UIN;
  6453. User.About = about;
  6454. User.Country = user->Country;
  6455. User.TimeZone = user->TimeZone;
  6456. User.Age = user->Age;
  6457. User.Sex = user->Sex;
  6458. User.Authorize = user->Authorize;
  6459. User.IP = user->IP;
  6460. User.Port = user->Port;
  6461. User.RealIP = user->RealIP;
  6462. User.Status = user->Status;
  6463. User.SeeInvis = user->SeeInvis;
  6464. User.BeInvis = user->BeInvis;
  6465. User.LastOnline = user->LastOnline;
  6466. User.LastMessageFm = user->LastMessageFm;
  6467. User.LastMessageTo = user->LastMessageTo;
  6468.  
  6469. User.Comment = (char *)DoMethod(user->UWin->TE_Comment,MUIM_TextEditor_ExportText);
  6470.  
  6471. User.UWin = user->UWin;
  6472.  
  6473. user->UWin->DoNotDelete = TRUE;
  6474.  
  6475. get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  6476.  
  6477. for(i = 0; i < total; i++) {
  6478.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  6479.   if (user) {
  6480.     if (user->UIN == id) {
  6481.       DoMethod(app->LV_OfflineList,MUIM_NList_Remove,i);
  6482.       break;
  6483.     }
  6484.   }
  6485. }
  6486.  
  6487. AddUser2CList(&User);
  6488.  
  6489. if (User.Comment) FreeVec(User.Comment);
  6490.  
  6491. SaveContact(id);
  6492.  
  6493. return;
  6494.  
  6495. }
  6496.  
  6497.  
  6498. BOOL LoadContact(ULONG uin)
  6499.  
  6500. {
  6501.  
  6502. char *data, about[512], cmnt[512], line[512];
  6503.  
  6504. LONG temp, lamp;
  6505.  
  6506. struct AsyncFile *load_fh;
  6507. struct Contact User, *user;
  6508.  
  6509. PrepNewContact(&User);
  6510.  
  6511. sprintf(userstat_fl,"%s%ld",userdir_fl,uin);
  6512.  
  6513. if (!(load_fh = OpenAsync(userstat_fl,MODE_READ,AsyncBuf))) {
  6514.   HandleError(DBG_OTH_INFO,"Could not open '%s' for loading.",userstat_fl);
  6515.   return(FALSE);
  6516. }
  6517.  
  6518. about[0] = cmnt[0] = '\0';
  6519.  
  6520. User.UIN = uin;
  6521.  
  6522. while(ReadLineAsync(load_fh,line,sizeof(line))) {
  6523.   if (line[0] == ';' || !(data = strchr(line,'='))) continue;
  6524.   *data++ = '\0';
  6525.   LASTCHAR(data) = '\0';
  6526.   if (!stricmp(line,"NICK")) RefreshUInfo(&User.Nick,data);
  6527.   if (!stricmp(line,"FIRST")) RefreshUInfo(&User.First,data);
  6528.   if (!stricmp(line,"LAST")) RefreshUInfo(&User.Last,data);
  6529.   if (!stricmp(line,"EMAIL")) RefreshUInfo(&User.EMail,data);
  6530.   if (!stricmp(line,"EMAIL2")) RefreshUInfo(&User.EMail_Secondary,data);
  6531.   if (!stricmp(line,"EMAILOLD")) RefreshUInfo(&User.EMail_Old,data);
  6532.   if (!stricmp(line,"CITY")) RefreshUInfo(&User.City,data);
  6533.   if (!stricmp(line,"STATE")) RefreshUInfo(&User.State,data);
  6534.   if (!stricmp(line,"PHONE")) RefreshUInfo(&User.Phone,data);
  6535.   if (!stricmp(line,"HOMEPAGE")) RefreshUInfo(&User.HomePage,data);
  6536.   if (!stricmp(line,"COUNTRY")) {
  6537.     StrToLong(data,&temp);
  6538.     User.Country = temp;
  6539.     continue;
  6540.   }
  6541.   if (!stricmp(line,"AGE")) {
  6542.     StrToLong(data,&temp);
  6543.     User.Age = temp;
  6544.     continue;
  6545.   }
  6546.   if (!stricmp(line,"SEX")) {
  6547.     StrToLong(data,&temp);
  6548.     User.Sex = temp;
  6549.     continue;
  6550.   }
  6551.   if (!stricmp(line,"AUTHORIZE")) {
  6552.     StrToLong(data,&temp);
  6553.     User.Authorize = temp;
  6554.     continue;
  6555.   }
  6556.   if (!stricmp(line,"SEEINVIS")) {
  6557.     StrToLong(data,&temp);
  6558.     User.SeeInvis = temp;
  6559.     continue;
  6560.   }
  6561.   if (!stricmp(line,"ABOUT")) {
  6562.     ReadLineAsync(load_fh,line,sizeof(line));
  6563.     while(line[0] != ';') {
  6564.       strcat(about,line);
  6565.       ReadLineAsync(load_fh,line,sizeof(line));
  6566.       if (!strnicmp(line,"COMMENT=",8)) {
  6567.         data = strchr(line,'=');
  6568.         *data++ = '\0';
  6569.         OldPrefsFmt = TRUE;
  6570.         break;
  6571.       }
  6572.     }
  6573.     LASTCHAR(about) = '\0';
  6574.     RefreshUInfo(&User.About,about);
  6575.   }
  6576.   if (!stricmp(line,"COMMENT")) {
  6577.     ReadLineAsync(load_fh,line,sizeof(line));
  6578.     while(line[0] != ';') {
  6579.       strcat(cmnt,line);
  6580.       ReadLineAsync(load_fh,line,sizeof(line));
  6581.       if (!strnicmp(line,"NEWMSGS=",8)) {
  6582.         data = strchr(line,'=');
  6583.         *data++ = '\0';
  6584.         break;
  6585.       }
  6586.     }
  6587.     LASTCHAR(cmnt) = '\0';
  6588.     RefreshUInfo(&User.Comment,cmnt);
  6589.   }
  6590.   if (!stricmp(line,"NEWMSGS")) {
  6591.     StrToLong(data,&temp);
  6592.     User.NewMsg = temp;
  6593.     continue;
  6594.   }
  6595.   if (!stricmp(line,"TIMEZONE")) {
  6596.     StrToLong(data,&temp);
  6597.     User.TimeZone = temp;
  6598.     continue;
  6599.   }
  6600.   if (!stricmp(line,"BEINVIS")) {
  6601.     StrToLong(data,&temp);
  6602.     User.BeInvis = temp;
  6603.     continue;
  6604.   }
  6605.   if (!stricmp(line,"LASTONLINE")) {
  6606.     StrToLong(data,&temp);
  6607.     User.LastOnline = temp;
  6608.     continue;
  6609.   }
  6610.   if (!stricmp(line,"LASTMESSAGEFM")) {
  6611.     StrToLong(data,&temp);
  6612.     User.LastMessageFm = temp;
  6613.     continue;
  6614.   }
  6615.   if (!stricmp(line,"LASTMESSAGETO")) {
  6616.     StrToLong(data,&temp);
  6617.     User.LastMessageTo = temp;
  6618.     continue;
  6619.   }
  6620. }
  6621.  
  6622. CloseAsync(load_fh);
  6623.  
  6624. AddUser2CList(&User);
  6625.  
  6626. FreeUser(&User);
  6627.  
  6628. user = GetContact(User.UIN);
  6629.  
  6630. if (user->NewMsg) {
  6631.   switch(user->NewMsg) {
  6632.     case 1:
  6633.       if (WhichLamp == 0) lamp = MUIV_Lamp_Color_Ok;
  6634.       else lamp = MUIV_TWFmultiLED_Colour_On;
  6635.       break;
  6636.     case 2:
  6637.       if (WhichLamp == 0) lamp = MUIV_Lamp_Color_Warning;
  6638.       else lamp = MUIV_TWFmultiLED_Colour_Ok;
  6639.       break;
  6640.     case 3:
  6641.       if (WhichLamp == 0) lamp = MUIV_Lamp_Color_Error;
  6642.       else lamp = MUIV_TWFmultiLED_Colour_Load;
  6643.       break;
  6644.     default:
  6645.       if (WhichLamp == 0) lamp = MUIV_Lamp_Color_FatalError;
  6646.       else lamp = MUIV_TWFmultiLED_Colour_Error;
  6647.   }
  6648.   if (WhichLamp == 0) set(user->LampObj,MUIA_Lamp_Color,lamp);
  6649.   else set(user->LampObj,MUIA_TWFmultiLED_Colour,lamp);
  6650.   DoMethod(app->LV_OfflineList,MUIM_NList_Sort);
  6651. }
  6652.  
  6653. return(TRUE);
  6654.  
  6655. }
  6656.  
  6657.  
  6658. void __asm LoadContactJump(REG(a2) APTR obj)
  6659.  
  6660. {
  6661.  
  6662. ULONG id = 0;
  6663.  
  6664. get(obj,MUIA_UserData,&id);
  6665.  
  6666. LoadContact(id);
  6667.  
  6668. UpdateUserWin(GetContact(id));
  6669.  
  6670. return;
  6671.  
  6672. }
  6673.  
  6674.  
  6675. void SaveAllContacts(void)
  6676.  
  6677. {
  6678.  
  6679. int i;
  6680.  
  6681. ULONG total = 0;
  6682.  
  6683. struct Contact *user;
  6684.  
  6685. get(app->LV_OfflineList,MUIA_NList_Entries,&total);
  6686.  
  6687. if (!total) return;
  6688.  
  6689. if (OldPrefsFmt) printf("Saving all contacts in new prefs format. (One time message.)\n");
  6690.  
  6691. for(i = 0; i < total; i++) {
  6692.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,i,&user);
  6693.   if (user) {
  6694.     if (user->Changed || user->NewMsg || OldPrefsFmt) SaveContact(user->UIN);
  6695.   }
  6696. }
  6697.  
  6698. return;
  6699.  
  6700. }
  6701.  
  6702.  
  6703. void __asm LoadHistory(REG(a2) APTR obj)
  6704.  
  6705. {
  6706.  
  6707. char uinlog[MAXNAMLEN], line[1024];
  6708.  
  6709. ULONG id, uin;
  6710.  
  6711. struct AsyncFile *loadfh;
  6712. struct Contact   *user;
  6713.  
  6714. get(obj,MUIA_UserData,&id);
  6715. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  6716.  
  6717. user = GetContact(id);
  6718.  
  6719. sprintf(uinlog,"%sUsers/%ld/Logs/%ld",currentdir,uin,id);
  6720.  
  6721. DoMethod(user->UWin->LV_History,MUIM_NList_Clear);
  6722.  
  6723. set(user->UWin->LV_History,MUIA_NList_Quiet,TRUE);
  6724.  
  6725. if (loadfh = OpenAsync(uinlog,MODE_READ,AsyncBuf)) {
  6726.   while(ReadLineAsync(loadfh,line,sizeof(line)) > 0) {
  6727.     LASTCHAR(line) = '\0';
  6728.     DoMethod(user->UWin->LV_History,MUIM_NList_InsertWrap,line,-2,MUIV_NList_Insert_Bottom,WRAPCOL0,ALIGN_LEFT);
  6729.   }
  6730.   CloseAsync(loadfh);
  6731. }
  6732.  
  6733. set(user->UWin->LV_History,MUIA_NList_Quiet,FALSE);
  6734.  
  6735. return;
  6736.  
  6737. }
  6738.  
  6739.  
  6740. void __asm SaveHistory(REG(a2) APTR obj)
  6741.  
  6742. {
  6743.  
  6744. char uinlog[MAXNAMLEN];
  6745.  
  6746. int i, last = -1;
  6747.  
  6748. ULONG id, total, uin;
  6749.  
  6750. struct AsyncFile *savefh;
  6751. struct MUI_NList_GetEntryInfo res;
  6752. struct Contact *user;
  6753.  
  6754. get(obj,MUIA_UserData,&id);
  6755. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  6756.  
  6757. sprintf(uinlog,"%sUsers/%ld/Logs/%ld",currentdir,uin,id);
  6758.  
  6759. user = GetContact(id);
  6760.  
  6761. get(user->UWin->LV_History,MUIA_NList_Entries,&total);
  6762.  
  6763. if (total < 1) return;
  6764.  
  6765. if (!(savefh = OpenAsync(uinlog,MODE_WRITE,AsyncBuf))) return;
  6766.  
  6767. for(i = 0; i < total; i++) {
  6768.   res.pos = i;
  6769.   DoMethod(user->UWin->LV_History,MUIM_NList_GetEntryInfo,&res);
  6770.   if (res.line == last) continue;
  6771.   WriteLineAsync(savefh,res.entry);
  6772.   WriteCharAsync(savefh,'\n');
  6773.   last = res.line;
  6774. }
  6775.  
  6776. CloseAsync(savefh);
  6777.  
  6778. SetComment(uinlog,GetNick(id));
  6779.  
  6780. return;
  6781.  
  6782. }
  6783.  
  6784.  
  6785. void __asm DeleteHistory(REG(a2) APTR obj)
  6786.  
  6787. {
  6788.  
  6789. char uinlog[MAXNAMLEN];
  6790.  
  6791. ULONG id, uin;
  6792.  
  6793. get(obj,MUIA_UserData,&id);
  6794. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  6795.  
  6796. sprintf(uinlog,"%sUsers/%ld/Logs/%ld",currentdir,uin,id);
  6797.  
  6798. DeleteFile(uinlog);
  6799.  
  6800. return;
  6801.  
  6802. }
  6803.  
  6804.  
  6805. void __asm RemoveContact(REG(a2) APTR obj)
  6806.  
  6807. {
  6808.  
  6809. LONG sel = MUIV_NList_PrevSelected_Start, ret;
  6810.  
  6811. struct Contact *user;
  6812.  
  6813. DoMethod(app->LV_OfflineList,MUIM_NList_PrevSelected,&sel);
  6814.  
  6815. ret=0;
  6816.  
  6817. while((sel != MUIV_NList_PrevSelected_End)&(ret!=1)) {
  6818.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,sel,&user);
  6819.   ret = MUI_Request(app->App,app->WI_Main,0,NULL,"Yes|Skip|Cancel","\033cDelete %s\n\nAre You Sure",user->Nick);
  6820.   switch (ret) {
  6821.     case 1:
  6822.         ret = MUI_Request(app->App,app->WI_Main,0,NULL,"Yes|Skip|Cancel","\033cDelete %s\n\nAre You Sure 111",user->Nick);
  6823.         break;
  6824.     case 2:
  6825.         ret = MUI_Request(app->App,app->WI_Main,0,NULL,"Yes|Skip|Cancel","\033cDelete %s\n\nAre You Sure 222",user->Nick);
  6826.         break;
  6827.     case 3:
  6828.         ret = MUI_Request(app->App,app->WI_Main,0,NULL,"Yes|Skip|Cancel","\033cDelete %s\n\nAre You Sure 333",user->Nick);
  6829.         break;
  6830.     case 0:
  6831.         ret = MUI_Request(app->App,app->WI_Main,0,NULL,"Yes|Skip|Cancel","\033cDelete %s\n\nAre You Sure 000",user->Nick);
  6832.         break;
  6833.   }
  6834.   /* josse */
  6835.   if (!(ret = MUI_Request(app->App,app->WI_Main,0,NULL,"Yes|Skip|Cancel","\033cDelete %s\n\nAre You Sure",user->Nick))) break;
  6836.   if (ret == 1) DeleteUIN(user->UIN);
  6837.   DoMethod(app->LV_OfflineList,MUIM_NList_PrevSelected,&sel);
  6838. }
  6839.  
  6840. return;
  6841.  
  6842. }
  6843.  
  6844.  
  6845. void DeleteUIN(ULONG uin)
  6846.  
  6847. {
  6848.  
  6849. char uinlog[MAXNAMLEN];
  6850.  
  6851. ULONG localin;
  6852.  
  6853. struct Contact *user;
  6854. struct Sockets *socks;
  6855.  
  6856. if (!(user = GetContact(uin))) return;
  6857.  
  6858. get(app->STR_ICQUIN,MUIA_String_Integer,&localin);
  6859.  
  6860. sprintf(uinlog,"%sUsers/%ld/Logs/%ld",currentdir,localin,user->UIN);
  6861.  
  6862. DeleteFile(uinlog);
  6863.  
  6864. sprintf(uinlog,"%sUsers/%ld/Users/%ld",currentdir,localin,user->UIN);
  6865.  
  6866. DeleteFile(uinlog);
  6867.  
  6868. if (socks = GetSocketFmContact(user,SOCK_MESSAGE)) DelSockets(socks->Socket);
  6869. if (socks = GetSocketFmContact(user,SOCK_CHAT)) DelSockets(socks->Socket);
  6870. if (socks = GetSocketFmContact(user,SOCK_FILE)) DelSockets(socks->Socket);
  6871.  
  6872. if (user->Status != STATUS_NEWUIN) {
  6873.   sprintf(maintitle,"STRICQ (%d)",--contacts_cnt);
  6874.   set(app->WI_Main,MUIA_Window_Title,maintitle);
  6875. }
  6876.  
  6877. DoMethod(app->LV_OfflineList,MUIM_NList_Remove,user->ListID);
  6878.  
  6879. return;
  6880.  
  6881. }
  6882.  
  6883.  
  6884. int recv_tcp_pkt(char *buf, struct Sockets *socks)
  6885.  
  6886. {
  6887.  
  6888. int i = 0, j = 0;
  6889.  
  6890. ULONG err, data;
  6891.  
  6892. UWORD len = 0;
  6893.  
  6894. if (socks->PktLen[0] == '\0' && socks->PktLen[1] == '\0') {
  6895.   i = recv(socks->Socket,buf,2,0);
  6896. //HandleError(DBG_TCP_DBUG,"Initial pkt read got %d bytes.",i);
  6897. }
  6898. else {
  6899.   i = 2;
  6900.   buf[0] = socks->PktLen[0];
  6901.   buf[1] = socks->PktLen[1];
  6902. //HandleError(DBG_OTH_INFO,"Already have the first 2, copying...");
  6903. }
  6904.  
  6905. if (i == 0) return(-1);
  6906.  
  6907. if (i > 0) {
  6908.   revmemcpy((char *)&len,buf,2);
  6909.   IoctlSocket(socks->Socket,FIONREAD,(char *)&data);
  6910.   if (data < len) {
  6911.     socks->PktLen[0] = buf[0];
  6912.     socks->PktLen[1] = buf[1];
  6913. //  HandleError(DBG_TCP_DBUG,"  Wasn't enough bytes, got %d, expecting %d.",data,len);
  6914.     return(0);
  6915.   }
  6916.   if (i != 2) {
  6917.     HandleError(DBG_TCP_ERRS,"Strange error, got %d bytes in recv_tcp_pkt.",i);
  6918.     i = 2;
  6919.   }
  6920. //PrintHex(DBG_TCP_DBUG,"buf before",buf,16);
  6921.   j = recv(socks->Socket,buf+i,len,0);
  6922. //PrintHex(DBG_TCP_DBUG,"buf after",buf,16);
  6923. }
  6924.  
  6925. if (i < 0 || j < 0) {
  6926.   if ((err = Errno()) != EWOULDBLOCK) {
  6927.     SocketBaseTags(SBTM_GETREF(SBTC_ERRNOSTRPTR),&err,TAG_DONE);
  6928.     HandleError(DBG_TCP_ERRS,"Error on msg/file socket %d: %s",socks->Socket,(char *)err);
  6929.     return(-1);
  6930.   }
  6931.   else {
  6932.     if (i > -1 && j < 0) {
  6933.       socks->PktLen[0] = buf[0];
  6934.       socks->PktLen[1] = buf[1];
  6935. //    HandleError(DBG_OTH_INFO,"  Got a EWOULDBLOCK, store [0],[1], return...");
  6936.     }
  6937.     return(0);
  6938.   }
  6939. }
  6940.  
  6941. socks->PktLen[0] = socks->PktLen[1] = '\0';
  6942.  
  6943. //HandleError(DBG_TCP_DBUG,"  i+j = %d",i+j);
  6944.  
  6945. return(i+j);
  6946.  
  6947. }
  6948.  
  6949.  
  6950. void ParseTCPCmd(char *buf, int len, UWORD sock)
  6951.  
  6952. {
  6953.  
  6954. BOOL *useaway, prec_flag;
  6955.  
  6956. char *tcpmsg, nick[50], *reply, *filename, filestats[512], *notifycmd, cmdln[MAXNAMLEN], *c;
  6957.  
  6958. int i, off = 0;
  6959.  
  6960. ULONG uin = 0, seq = 0, total = 0, index = 0, localin = 0, filesize = 0, ip = 0;
  6961.  
  6962. UWORD pktlen = 0, msglen = 0, cmdtype = 0, cmd = 0, msgtype = 0, status = 0, fnlen = 0, status2, port;
  6963.  
  6964. struct Contact *user, User;
  6965. struct ICQLog  *Logged;
  6966. struct Sockets *socks;
  6967.  
  6968. if (!len) return;
  6969.  
  6970. PrintHex(DBG_TCP_PKTS,"Incoming TCP message packet",buf,len);
  6971.  
  6972. get(app->STR_ICQUIN,MUIA_String_Integer,&localin);
  6973. get(app->CY_MyStatus,MUIA_Cycle_Active,&index);
  6974.  
  6975. if (socks = GetSocketFmSocket(sock)) {
  6976.   user = GetContact(socks->UIN);
  6977.   socks->Timehack = time(NULL);
  6978. }
  6979.  
  6980. status2 = TCPCodes[index];
  6981.  
  6982. revmemcpy((char *)&pktlen,buf+off,2); off += 2;
  6983.  
  6984. if (((UBYTE)buf[off] == (UBYTE)0xff) && !socks->HadInit) {
  6985.   struct TCP_Init Init;
  6986.   TCP_ParseTCPInit(&Init,buf);
  6987.   if (CheckIgnore(Init.UIN)) {
  6988.     DelSockets(socks->Socket);
  6989.     return;
  6990.   }
  6991.   if (!(user = GetContact(Init.UIN))) {
  6992.     PrepNewContact(&User);
  6993.     User.UIN = Init.UIN;
  6994.     sprintf(nick,"%ld",Init.UIN);
  6995.     User.Nick = nick;
  6996.     User.Status = STATUS_NEWUIN;
  6997.     User.CanTCP = 4;
  6998.     AddUser2CList(&User);
  6999.     user = GetContact(Init.UIN);
  7000.   }
  7001.   if (user->CanTCP != 4) user->CanTCP = 4;
  7002.   user->IP = socks->IP;
  7003.   user->Port = Init.TCP_MsgPort;
  7004.   socks->UIN = user->UIN;
  7005.   socks->Timehack = time(NULL);
  7006.   socks->HadInit = TRUE;
  7007.   DoMethod(app->LV_SockList,MUIM_NList_Redraw,MUIV_NList_Redraw_All);
  7008. //HandleError(DBG_TCP_DBUG,"Created IN entry for socket %d",sock);
  7009. }
  7010. else {
  7011.   if (!socks->HadInit) {
  7012.     HandleError(DBG_TCP_ERRS,"Got a TCP message without an init packet.  Source IP is %s.",Inet_NtoA(socks->Address.sin_addr.s_addr));
  7013.     DelSockets(socks->Socket);
  7014.     return;
  7015.   }
  7016.   revmemcpy((char *)&uin,buf+off,4); off += 4;          // UIN
  7017.   off += 2;                                             // Version (skip)
  7018.   revmemcpy((char *)&cmd,buf+off,2); off += 2;          // Msg Command
  7019.   if (cmd == TCP_MSG_UNK_2) return;
  7020.   off += 6;                                             // X1 & UIN2 (skip)
  7021.   revmemcpy((char *)&msgtype,buf+off,2); off += 2;      // Msg Type
  7022.   revmemcpy((char *)&msglen,buf+off,2); off += 2;       // Msg Len
  7023.   tcpmsg = buf+off; off += msglen;                      // Msg Text
  7024.      memcpy((char *)&ip,buf+off,4); off += 4;           // IP Real
  7025.   off += 9;                                             // IP, Port, X2 (skip)
  7026.   revmemcpy((char *)&status,buf+off,2); off += 2;       // Status
  7027.   revmemcpy((char *)&cmdtype,buf+off,2); off += 2;      // Msg Cmd Type
  7028.   switch(msgtype) {
  7029.     case TCP_MSG_MSG:
  7030.       if (len-off > 4) {
  7031.         if (*(buf+(len-3)) != 'L') {
  7032.           PrintHex(DBG_TCP_DBUG,"Unknown packet format, please report this",buf,len);
  7033.           off = len-4;
  7034.         }
  7035.       }
  7036.       break;
  7037.     case TCP_MSG_CHAT:
  7038.       revmemcpy((char *)&fnlen,buf+off,2); off += 2;    // Text Len
  7039.       filename = buf+off; off += fnlen;                 // Text
  7040.          memcpy((char *)&port,buf+off,2); off += 4;     // Port1 (Normal order)
  7041.       off += 4;                                         // Port2 (Reverse order) (skip)
  7042.       break;
  7043.     case TCP_MSG_FILE:
  7044.          memcpy((char *)&port,buf+off,2); off += 4;     // Port1 (Normal order)
  7045.       revmemcpy((char *)&fnlen,buf+off,2); off += 2;    // Filename Len
  7046.       filename = buf+off; off += fnlen;                 // Filename
  7047.       revmemcpy((char *)&filesize,buf+off,4); off += 4; // Filesize
  7048.       off += 4;                                         // Port2 (Reverse order) (skip)
  7049.       break;
  7050.   }
  7051.   revmemcpy((char *)&seq,buf+off,4); off += 4;          // Sequence
  7052.   if (!Online) {
  7053.     if (user) {
  7054.       for(i = 0; i<NUM_STATUS; i++) {
  7055.         if (TCPCodes[i] == status) {
  7056.           user->Status = Codes[i];
  7057.           break;
  7058.         }
  7059.       }
  7060.     }
  7061.   }
  7062.   if (status2 == TCP_STATUS_OCCUPIED || status2 == TCP_STATUS_DND) {
  7063.     if (cmdtype & TCP_MSG_LIST || cmdtype & TCP_MSG_URGENT) {
  7064.       if (strlen(tcpmsg)) ParseMessage(cmd,tcpmsg,uin,msgtype);
  7065.       status2 = TCP_STATUS_ONLINE;
  7066.     }
  7067.   }
  7068.   else {
  7069.     if (strlen(tcpmsg)) ParseMessage(cmd,tcpmsg,uin,msgtype);
  7070.   }
  7071.   Header.Command = cmd;
  7072.   Header.TCP_Sequence = seq;
  7073.   Header.Sequence2 = 0;
  7074.   switch(cmd) {
  7075.     case TCP_MESSAGE:
  7076.       cmdtype &= 0x007F;
  7077.       switch(cmdtype) {
  7078.         case TCP_MSG_REAL:
  7079.         case TCP_MSG_LIST:
  7080.         case TCP_MSG_URGENT:
  7081.           Add2Log(LOG_SERVER,&Header,TRUE,0,NULL);
  7082.           TCP_Seq--;
  7083.           reply = LINE;
  7084.           get(app->CY_MyStatus,MUIA_Cycle_Active,&index);
  7085.           get(app->CH_UseMessages[index],MUIA_Selected,&useaway);
  7086.           if (useaway && uin != localin) get(app->STR_Messages[index],MUIA_String_Contents,&reply);
  7087.           get(app->CH_Scrn2Frnt,MUIA_Selected,&useaway);
  7088.           switch(msgtype) {
  7089.             case TCP_MSG_MSG:
  7090.             case TCP_MSG_URL:
  7091.             case TCP_MSG_READAWAY:
  7092.             case TCP_MSG_READOCCUPIED:
  7093.             case TCP_MSG_READNA:
  7094.             case TCP_MSG_READDND:
  7095.             case TCP_MSG_READFFC:
  7096.               SendTCPMessage(uin,reply,TCP_ACK,msgtype,TCP_MSG_AUTO,seq,LINE,0x00000000,status2,0);
  7097.               break;
  7098.             case TCP_MSG_CHAT:
  7099.               if (useaway) DoMethod(app->WI_Main,MUIM_Window_ScreenToFront);
  7100.               if (strlen(filename)) sprintf(filestats,"%s\n\nMulti-Chat with:  %s",tcpmsg,filename);
  7101.               else strcpy(filestats,tcpmsg);
  7102.               CFWinOpen(uin,filestats,msgtype,seq,port);
  7103.               get(app->STR_ChatNotify,MUIA_String_Contents,¬ifycmd);
  7104.               if (strlen(notifycmd) > 0) {
  7105.                 sprintf(cmdln,notifycmd,uin);
  7106.                 System(cmdln,NULL);
  7107.               }
  7108.               break;
  7109.             case TCP_MSG_FILE:
  7110.               if (useaway) DoMethod(app->WI_Main,MUIM_Window_ScreenToFront);
  7111.               sprintf(filestats,"Filename: %s; Filesize: %ld\n\n%s",filename,filesize,tcpmsg);
  7112.               CFWinOpen(uin,filestats,msgtype,seq,port);
  7113.               get(app->STR_FileDirect,MUIA_String_Contents,¬ifycmd);
  7114.               if (strlen(notifycmd) > 0) {
  7115.                 sprintf(cmdln,notifycmd,uin);
  7116.                 System(cmdln,NULL);
  7117.               }
  7118.               break;
  7119.             case TCP_MSG_ADDUIN: {
  7120.               SendTCPMessage(uin,reply,TCP_ACK,msgtype,TCP_MSG_AUTO,seq,LINE,0x00000000,status2,0);
  7121.               break;
  7122.             }
  7123.             default:
  7124.               sprintf(err_buf,"Unknown message type 0x%04x.",msgtype);
  7125.               PrintHex(DBG_TCP_DBUG,err_buf,buf,len);
  7126.           }
  7127.           break;
  7128.         default:
  7129.           sprintf(err_buf,"Unknown message command type 0x%04x.",cmdtype);
  7130.           PrintHex(DBG_TCP_DBUG,err_buf,buf,len);
  7131.       }
  7132.       break;
  7133.     case TCP_ACK:
  7134.     case TCP_CANCEL:
  7135.       for(c = tcpmsg; *c; c++) if (*c == '\r') *c = ' ';
  7136.       switch(msgtype) {
  7137.         case TCP_MSG_CHAT:
  7138.           if (cmd == TCP_CANCEL) {
  7139.             HandleError(DBG_OTH_INFO,"Chat Request Canceled");
  7140.             if (user) {
  7141.               if (user->CFWin) {
  7142. //              set(user->CFWin->WI_ChatFileInWin,MUIA_Window_Open,FALSE);
  7143. //              DoMethod(app->App,OM_REMMEMBER,user->CFWin->WI_ChatFileInWin);
  7144. //              MUI_DisposeObject(user->CFWin->WI_ChatFileInWin);
  7145. //              FreeVec(user->CFWin);
  7146. //              user->CFWin = NULL;
  7147.               }
  7148.             }
  7149.           }
  7150.           else {
  7151.             if (status != TCP_STAT_ONLINE) {
  7152.               if (!strlen(tcpmsg)) tcpmsg = "No reason given.";
  7153.               HandleError(DBG_OTH_INFO,"Chat Request Refused:  %s",tcpmsg);
  7154.             }
  7155.             else {
  7156.               if (!user->ChatListen) user->ChatListen = OpenTCPListen(SOCK_CHAT);
  7157.               if (ip == 0) ip = user->IP;
  7158.               if (!user->ConnectMe) {
  7159.                 if (!OpenTCPSocket(user,SOCK_CHAT,ip,port)) {
  7160.                   if (!OpenTCPSocket(user,SOCK_CHAT,user->RealIP,port)) HandleError(DBG_TCP_ERRS,"Could not open a chat connection to %s.",user->Nick);
  7161. /*                else {
  7162.                     sock2 = GetSocketFmContact(user,SOCK_CHAT);
  7163.                     SendTCPInit(sock2->Socket,user,user->ChatListen);
  7164.                     SendChatInit(sock2->Socket);
  7165.                   }
  7166. */              }
  7167.               }
  7168.             }
  7169.           }
  7170.           break;
  7171.         case TCP_MSG_FILE:
  7172.           if (cmd == TCP_CANCEL) {
  7173.             HandleError(DBG_OTH_INFO,"File Send Canceled");
  7174.             if (user) {
  7175.               if (user->CFWin) {
  7176. //              set(user->CFWin->WI_ChatFileInWin,MUIA_Window_Open,FALSE);
  7177. //              DoMethod(app->App,OM_REMMEMBER,user->CFWin->WI_ChatFileInWin);
  7178. //              MUI_DisposeObject(user->CFWin->WI_ChatFileInWin);
  7179. //              FreeVec(user->CFWin);
  7180. //              user->CFWin = NULL;
  7181.               }
  7182.             }
  7183.           }
  7184.           else {
  7185.             if (status != TCP_STAT_ONLINE) {
  7186.               if (!strlen(tcpmsg)) tcpmsg = "No reason given.";
  7187.               HandleError(DBG_OTH_INFO,"File Transfer Refused:  %s",tcpmsg);
  7188.             }
  7189.             else {
  7190.               if (!FileListen) FileListen = OpenTCPListen(SOCK_FILE);
  7191.               if (ip == 0) ip = user->IP;
  7192.               if (!OpenTCPSocket(user,SOCK_FILE,ip,port)) {
  7193.                 if (!OpenTCPSocket(user,SOCK_FILE,user->RealIP,port)) {
  7194.                   HandleError(DBG_TCP_ERRS,"Could not open a file send connection to %s.",user->Nick);
  7195.                 }
  7196.               }
  7197.             }
  7198.           }
  7199.           break;
  7200.       }
  7201.       prec_flag = FALSE;
  7202.       if (cmdtype == TCP_MSG_AUTO) {
  7203.         char *buttons;
  7204.         int ret;
  7205.         UWORD prec;
  7206.         if (status == TCP_STATUS_OCCUPIED || status == TCP_STATUS_DND) {
  7207.           if (status == TCP_STATUS_OCCUPIED) buttons = "Send To Contact List|Send Urgent|Cancel";
  7208.           else buttons = "Send To Contact List|Cancel";
  7209.           if ((ret = MUI_Request(app->App,NULL,0,"Message Precedence",buttons,"User is either Occupied or set Do Not Disturb.")) == 0) break;
  7210.           prec_flag = TRUE;
  7211.           if (ret == 1) prec = TCP_MSG_LIST;
  7212.           else prec = TCP_MSG_URGENT;
  7213.           SendTCPMessage(uin,socks->LastTCP+18,TCP_MESSAGE,msgtype,prec,TCP_Seq,LINE,0x00000000,0x0000,0);
  7214.           Add2Log(LOG_CLIENT,&Header,FALSE,0,NULL);
  7215.         }
  7216.       }
  7217.       if (!prec_flag) {
  7218.         if (socks) {
  7219.           if (socks->LastTCP) {
  7220.             FreeVec(socks->LastTCP);
  7221.             socks->LastTCP = NULL;
  7222.           }
  7223.         }
  7224.         if (user->UWin) {
  7225.           set(user->UWin->BB_WaitTCP,MUIA_Busy_Speed,MUIV_Busy_Speed_Off);
  7226.           set(user->UWin->BB_WaitTCP,MUIA_ShowMe,FALSE);
  7227.         }
  7228.       }
  7229.       get(app->LV_ICQCliLog,MUIA_NList_Entries,&total);
  7230.       for(i = total-1; i>-1; i--) {
  7231.         DoMethod(app->LV_ICQCliLog,MUIM_NList_GetEntry,i,&Logged);
  7232.         if (Logged) {
  7233. //        HandleError(DBG_TCP_DBUG,"Logged->Seq = %ld, Header.TCP_Sequence = %ld",Logged->Seq,Header.TCP_Sequence);
  7234.           if (Logged->Seq == Header.TCP_Sequence) {
  7235.             Logged->Ack = TRUE;
  7236.             DoMethod(app->LV_ICQCliLog,MUIM_NList_Redraw,i);
  7237.             break;
  7238.           }
  7239.         }
  7240.       }
  7241.       break;
  7242.     default:
  7243.       sprintf(err_buf,"Unknown message command 0x%04x.",cmd);
  7244.       PrintHex(DBG_TCP_DBUG,err_buf,buf,len);
  7245.   }
  7246. }
  7247.  
  7248. return;
  7249.  
  7250. }
  7251.  
  7252.  
  7253. BOOL SendTCPMessage(ULONG to, char *msg, UWORD cmd, UWORD type, UWORD cmdtype, ULONG seq, char *filename, ULONG filesize, UWORD status, ULONG port2)
  7254.  
  7255. {
  7256.  
  7257. char buf[2048];
  7258.  
  7259. LONG ret = 1;
  7260.  
  7261. UBYTE x2;
  7262.  
  7263. ULONG uin = 0, port, addr, index;
  7264.  
  7265. UWORD len = 0, ver, x1, msglen, revlen, fnlen, port3;
  7266.  
  7267. UWORD MsgStatus[] = {TCP_MSG_REAL, TCP_MSGF_S_INVISIBLE, TCP_MSGF_S_NA, TCP_MSG_REAL, TCP_MSGF_S_OCCUPIED, TCP_MSGF_S_AWAY, TCP_MSGF_S_DND, TCP_MSG_REAL};
  7268.  
  7269. struct Contact *User;
  7270. struct Sockets *socks;
  7271.  
  7272. if (!(User = GetContact(to))) return(FALSE);
  7273.  
  7274. if (!(socks = GetSocketFmContact(User,SOCK_MESSAGE))) {
  7275.   if (User->CanTCP != 4) return(FALSE);
  7276.   if (!(ret = OpenTCPSocket(User,SOCK_MESSAGE,User->IP,User->Port))) {
  7277.     if (!(ret = OpenTCPSocket(User,SOCK_MESSAGE,User->RealIP,User->Port))) return(FALSE);
  7278.   }
  7279.   socks = GetSocketFmContact(User,SOCK_MESSAGE);
  7280.   if (User->Status & STATUSF_HIDEIP) socks->Hidden = TRUE;
  7281.   if (ret != -1) SendTCPInit(socks->Socket,User,0);
  7282. }
  7283.  
  7284. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  7285. get(app->CY_MyStatus,MUIA_Cycle_Active,&index);
  7286.  
  7287. if (cmdtype != TCP_MSG_AUTO) {
  7288.   MsgStatus[0] = MsgStatus[3] = MsgStatus[7] = cmdtype;
  7289.   cmdtype |= MsgStatus[index];
  7290. }
  7291.  
  7292. ver = 0x0002;
  7293. x1 = 0x0000;
  7294. msglen = strlen(msg)+1;
  7295. fnlen = strlen(filename)+1;
  7296. port = socks->LocalAddr.sin_port;
  7297. addr = socks->LocalAddr.sin_addr.s_addr;
  7298. x2 = 0x02;
  7299. port3 = port2;
  7300.  
  7301. revmemcpy(buf+len,(char *)&uin,4); len += 4;
  7302. revmemcpy(buf+len,(char *)&ver,2); len += 2;
  7303. revmemcpy(buf+len,(char *)&cmd,2); len += 2;
  7304. revmemcpy(buf+len,(char *)&x1,2); len += 2;
  7305. revmemcpy(buf+len,(char *)&uin,4); len += 4;
  7306. revmemcpy(buf+len,(char *)&type,2); len += 2;
  7307. revmemcpy(buf+len,(char *)&msglen,2); len += 2;
  7308. strcpy   (buf+len,msg); len += msglen;
  7309.    memcpy(buf+len,(char *)&addr,4); len += 4;
  7310.    memcpy(buf+len,(char *)&addr,4); len += 4;
  7311. revmemcpy(buf+len,(char *)&port,4); len += 4;
  7312. revmemcpy(buf+len,(char *)&x2,1); len++;
  7313. revmemcpy(buf+len,(char *)&status,2); len += 2;
  7314. revmemcpy(buf+len,(char *)&cmdtype,2); len += 2;
  7315.  
  7316. switch(type) {
  7317.   case TCP_MSG_CHAT:
  7318.     revmemcpy(buf+len,(char *)&fnlen,2); len += 2;
  7319.     strcpy   (buf+len,filename); len += fnlen;
  7320.        memcpy(buf+len,(char *)&port3,2); len += 2;
  7321.     revmemcpy(buf+len,(char *)&x1,2); len += 2;
  7322.     revmemcpy(buf+len,(char *)&port2,4); len += 4;
  7323.     break;
  7324.   case TCP_MSG_FILE:
  7325.        memcpy(buf+len,(char *)&port3,2); len += 2;
  7326.     revmemcpy(buf+len,(char *)&x1,2); len += 2;
  7327.     revmemcpy(buf+len,(char *)&fnlen,2); len += 2;
  7328.     strcpy   (buf+len,filename); len += fnlen;
  7329.     revmemcpy(buf+len,(char *)&filesize,4); len += 4;
  7330.     revmemcpy(buf+len,(char *)&port2,4); len += 4;
  7331.     break;
  7332. }
  7333.  
  7334. revmemcpy(buf+len,(char *)&seq,4); len += 4;
  7335.  
  7336. PrintHex(DBG_TCP_PKTS,"Outgoing TCP message packet",buf,len);
  7337.  
  7338. if (cmd != TCP_ACK) {
  7339.   if (!socks->LastTCP) {
  7340.     if (!(socks->LastTCP = AllocVec(len,MEMF_CLEAR))) {
  7341.       HandleError(DBG_OTH_FATL,"Could not allocate %d bytes.",len);
  7342.       return(FALSE);
  7343.     }
  7344.     memcpy(socks->LastTCP,buf,len);
  7345.     socks->TCPLen = len;
  7346.   }
  7347.   if (User->UWin) {
  7348.     set(User->UWin->BB_WaitTCP,MUIA_ShowMe,TRUE);
  7349.     set(User->UWin->BB_WaitTCP,MUIA_Busy_Speed,MUIV_Busy_Speed_User);
  7350.   }
  7351. }
  7352.  
  7353. if (ret == -1) return(TRUE);
  7354.  
  7355. revmemcpy((char *)&revlen,(char *)&len,2);
  7356.  
  7357. send(socks->Socket,(char *)&revlen,2,0);
  7358. send(socks->Socket,buf,len,0);
  7359.  
  7360. socks->Timehack = time(NULL);
  7361.  
  7362. return(TRUE);
  7363.  
  7364. }
  7365.  
  7366.  
  7367. LONG OpenTCPSocket(struct Contact *user, UBYTE type, ULONG ip, ULONG port)
  7368.  
  7369. {
  7370.  
  7371. LONG size = 1, ret = TRUE;
  7372.  
  7373. struct Sockets Socks;
  7374. struct timeval tv;
  7375.  
  7376. //HandleError(DBG_TCP_DBUG,"%s:%ld",Inet_NtoA(ip),port);
  7377.  
  7378. if (ip == 0 || port == 0) return(FALSE);
  7379.  
  7380. memset(&Socks.Address,NULL,sizeof(struct sockaddr));
  7381. memset(&Socks.LocalAddr,NULL,sizeof(struct sockaddr));
  7382.  
  7383. Socks.Address.sin_addr.s_addr = ip;
  7384. Socks.Address.sin_len = sizeof(struct sockaddr_in);
  7385.  
  7386. if ((Socks.Socket = socket(AF_INET,SOCK_STREAM,0)) == -1) {
  7387.   HandleError(DBG_TCP_ERRS,"Could not create a TCP socket.");
  7388.   return(FALSE);
  7389. }
  7390.  
  7391. if (Socks.Socket > maxfd) maxfd = Socks.Socket;
  7392.  
  7393. FD_SET(Socks.Socket,&rset);
  7394. FD_SET(Socks.Socket,&wset);
  7395.  
  7396. Socks.Address.sin_family = AF_INET;
  7397. Socks.Address.sin_port = port;
  7398.  
  7399. if (IoctlSocket(Socks.Socket,FIOASYNC,(char *)&size) == -1) {
  7400.   HandleError(DBG_TCP_ERRS,"Error in IoctlSocket FIOASYNC for TCP socket.");
  7401.   return(FALSE);
  7402. }
  7403.  
  7404. if (IoctlSocket(Socks.Socket,FIONBIO,(char *)&size) == -1) {
  7405.   HandleError(DBG_TCP_ERRS,"Error in IoctlSocket FIONBIO for TCP socket.");
  7406.   return(FALSE);
  7407. }
  7408.  
  7409. tv.tv_sec = 45;
  7410. tv.tv_usec = 0;
  7411.  
  7412. if (setsockopt(Socks.Socket,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv)) == -1) {
  7413.   HandleError(DBG_TCP_ERRS,"Could not setsockopt SO_SNDTIMEO for TCP socket.");
  7414. }
  7415.  
  7416. size = FILE_PKT_SIZE*2;
  7417.  
  7418. if (setsockopt(Socks.Socket,SOL_SOCKET,SO_SNDLOWAT,&size,sizeof(size)) == -1) {
  7419.   HandleError(DBG_TCP_ERRS,"Could not setsockopt SO_SNDLOWAT for TCP socket.");
  7420. }
  7421.  
  7422. if (connect(Socks.Socket,(struct sockaddr *)&Socks.Address,sizeof(Socks.Address)) == -1) {
  7423.   if (Errno() != EINPROGRESS) return(FALSE);
  7424.   else ret = -1;
  7425. }
  7426.  
  7427. Socks.UIN = user->UIN;
  7428. Socks.Dir = TCP_DIR_OUT;
  7429. Socks.IP = ip;
  7430. Socks.Port = port;
  7431. Socks.TCPLen = 0;
  7432. Socks.LastTCP = NULL;
  7433. Socks.ChatMode = Socks.FileMode = NULL;
  7434. Socks.RCObj = NULL;
  7435. Socks.Timehack = time(NULL);
  7436. Socks.Type = type;
  7437. Socks.HadInit = Socks.Hidden = Socks.Backward = Socks.Closing = FALSE;
  7438. Socks.CWin = NULL;
  7439. Socks.PktLen[0] = Socks.PktLen[1] = '\0';
  7440.  
  7441. if (ret == -1) Socks.Connecting = TRUE;
  7442. else Socks.Connecting = FALSE;
  7443.  
  7444. DoMethod(app->LV_SockList,MUIM_NList_InsertSingle,&Socks,MUIV_NList_Insert_Sorted);
  7445.  
  7446. //HandleError(DBG_TCP_DBUG,"created OUT entry for socket %d",Socks.Socket);
  7447.  
  7448. return(ret);
  7449.  
  7450. }
  7451.  
  7452.  
  7453. void SendTCPInit(UWORD sock, struct Contact *User, ULONG port)
  7454.  
  7455. {
  7456.  
  7457. char buf[256];
  7458.  
  7459. UBYTE ident, x3;
  7460.  
  7461. ULONG x1, uin, addr, port2;
  7462.  
  7463. UWORD revlen, len = 0;
  7464.  
  7465. struct Sockets *socks;
  7466.  
  7467. get(app->STR_ICQUIN,MUIA_String_Integer,&uin);
  7468.  
  7469. socks = GetSocketFmSocket(sock);
  7470.  
  7471. if (socks->HadInit) {
  7472.   HandleError(DBG_TCP_DBUG,"Aborting extraneous TCPInit for socket %d",sock);
  7473.   return;
  7474. }
  7475.  
  7476. HandleError(DBG_TCP_DBUG,"Sending TCPInit for socket %d",sock);
  7477.  
  7478. ident = 0xff;
  7479. x1 = 0x00000002;
  7480. addr = socks->LocalAddr.sin_addr.s_addr;
  7481. if (!port) port2 = socks->LocalAddr.sin_port;
  7482. x3 = 0x04;
  7483.  
  7484. revmemcpy(buf+len,(char *)&ident,1); len++;
  7485. revmemcpy(buf+len,(char *)&x1,4); len += 4;
  7486. revmemcpy(buf+len,(char *)&port,4); len += 4;
  7487. revmemcpy(buf+len,(char *)&uin,4); len += 4;
  7488.    memcpy(buf+len,(char *)&addr,4); len += 4;
  7489.    memcpy(buf+len,(char *)&addr,4); len += 4;
  7490. revmemcpy(buf+len,(char *)&x3,1); len++;
  7491. revmemcpy(buf+len,(char *)&port2,4); len += 4;
  7492.  
  7493. revmemcpy((char *)&revlen,(char *)&len,2);
  7494.  
  7495. send(sock,(char *)&revlen,2,0);
  7496. send(sock,buf,len,0);
  7497.  
  7498. if (socks->LastTCP) {
  7499.   revmemcpy((char *)&revlen,(char *)&socks->TCPLen,2);
  7500.   send(sock,(char *)&revlen,2,0);
  7501.   send(sock,socks->LastTCP,socks->TCPLen,0);
  7502.   socks->Timehack = time(NULL);
  7503. }
  7504.  
  7505. socks->HadInit = TRUE;
  7506.  
  7507. return;
  7508.  
  7509. }
  7510.  
  7511.  
  7512. void PrepNewContact(struct Contact *user)
  7513.  
  7514. {
  7515.  
  7516. memset((char *)user,0,sizeof(struct Contact));
  7517.  
  7518. user->Country = user->Age = 0xffff;
  7519.  
  7520. user->Type = TCP_MSG_MSG;
  7521.  
  7522. user->Status = STATUS_OFFLINE;
  7523.  
  7524. return;
  7525.  
  7526. }
  7527.  
  7528.  
  7529. APTR __asm AddSock(REG(a2) APTR pool, REG(a1) struct Sockets *socks)
  7530.  
  7531. {
  7532.  
  7533. struct Sockets *newsocks = NULL;
  7534.  
  7535. if (!(newsocks = AllocPooled(pool,sizeof(struct Sockets)))) return(NULL);
  7536.  
  7537. newsocks->Socket = socks->Socket;
  7538. newsocks->UIN = socks->UIN;
  7539. newsocks->Dir = socks->Dir;
  7540. newsocks->IP = socks->IP;
  7541. newsocks->Port = socks->Port;
  7542. newsocks->TCPLen = socks->TCPLen;
  7543. newsocks->LastTCP = socks->LastTCP;
  7544. newsocks->Timehack = socks->Timehack;
  7545. newsocks->Connecting = socks->Connecting;
  7546. newsocks->ChatMode = socks->ChatMode;
  7547. newsocks->FileMode = socks->FileMode;
  7548. newsocks->HadInit = socks->HadInit;
  7549. newsocks->Backward = socks->Backward;
  7550. newsocks->Hidden = socks->Hidden;
  7551. newsocks->Type = socks->Type;
  7552. newsocks->Closing = socks->Closing;
  7553. newsocks->PktLen[0] = newsocks->PktLen[1] = '\0';
  7554. newsocks->TCP_Version = socks->TCP_Version;
  7555. newsocks->TCP_Revision = socks->TCP_Revision;
  7556. newsocks->TCP_Listen_Msg_Port = socks->TCP_Listen_Msg_Port;
  7557. newsocks->TCP_Listen_Other_Port = socks->TCP_Listen_Other_Port;
  7558. newsocks->TCP_ChatData = socks->TCP_ChatData;
  7559. newsocks->RCObj = socks->RCObj;
  7560. newsocks->ConnectPort = socks->ConnectPort;
  7561. newsocks->CWin = socks->CWin;
  7562.  
  7563. memcpy((char *)&newsocks->Address,(char *)&socks->Address,sizeof(socks->Address));
  7564. memcpy((char *)&newsocks->LocalAddr,(char *)&socks->LocalAddr,sizeof(socks->LocalAddr));
  7565.  
  7566. return(newsocks);
  7567.  
  7568. }
  7569.  
  7570.  
  7571. void __asm RemSock(REG(a2) APTR pool, REG(a1) struct Sockets *newsocks)
  7572.  
  7573. {
  7574.  
  7575. if (newsocks->LastTCP) FreeVec(newsocks->LastTCP);
  7576. if (newsocks->RCObj) FreeVec(newsocks->RCObj);
  7577. if (newsocks->CWin) FreeVec(newsocks->CWin);
  7578.  
  7579. FreePooled(pool,newsocks,sizeof(struct Sockets));
  7580.  
  7581. return;
  7582.  
  7583. }
  7584.  
  7585.  
  7586. LONG __asm CmpSock(REG(a1) struct Sockets *s1, REG(a2) struct Sockets *s2)
  7587.  
  7588. {
  7589.  
  7590. if (s1->Socket < s2->Socket) return(-1);
  7591. if (s1->Socket > s2->Socket) return(1);
  7592.  
  7593. return(0);
  7594.  
  7595. }
  7596.  
  7597.  
  7598. void __asm DisplaySock(REG(a2) char **array, REG(a1) struct Sockets *socks)
  7599.  
  7600. {
  7601.  
  7602. static char sock[5], dir[7], ip[25], type[16];
  7603.  
  7604. if (socks) {
  7605.   sprintf(sock,"%d",socks->Socket);
  7606.   switch(socks->Dir) {
  7607.     case TCP_DIR_IN:
  7608.       strcpy(dir,"In");
  7609.       break;
  7610.     case TCP_DIR_OUT:
  7611.       strcpy(dir,"Out");
  7612.       break;
  7613.     case TCP_DIR_LISTEN:
  7614.       strcpy(dir,"Listen");
  7615.       break;
  7616.   }
  7617.   if (!socks->Hidden) sprintf(ip,"%s:%d",Inet_NtoA(socks->IP),socks->Port);
  7618.   else strcpy(ip,"Hidden");
  7619.   switch(socks->Type) {
  7620.     case SOCK_UDP:
  7621.       strcpy(type,"UDP");
  7622.       break;
  7623.     case SOCK_MESSAGE:
  7624.       strcpy(type,"Message");
  7625.       break;
  7626.     case SOCK_CHAT:
  7627.       strcpy(type,"Chat");
  7628.       break;
  7629.     case SOCK_FILE:
  7630.       strcpy(type,"File");
  7631.       break;
  7632.   }
  7633.   *array++ = sock;
  7634.   *array++ = GetNick(socks->UIN);
  7635.   *array++ = dir;
  7636.   *array++ = ip;
  7637.   *array   = type;
  7638. }
  7639. else {
  7640.   *array++ = "Socket";
  7641.   *array++ = "Nick";
  7642.   *array++ = "Dir";
  7643.   *array++ = "IP:Port";
  7644.   *array   = "Type";
  7645. }
  7646.  
  7647. return;
  7648.  
  7649. }
  7650.  
  7651.  
  7652. void DelSockets(UWORD sock)
  7653.  
  7654. {
  7655.  
  7656. BOOL flag = TRUE;
  7657.  
  7658. char msg[512];
  7659.  
  7660. int i;
  7661.  
  7662. LONG total;
  7663.  
  7664. struct Contact *user;
  7665. struct Sockets *socks;
  7666.  
  7667. get(app->LV_SockList,MUIA_NList_Entries,&total);
  7668.  
  7669. for(i = 0; i < total; i++) {
  7670.   DoMethod(app->LV_SockList,MUIM_NList_GetEntry,i,&socks);
  7671.   if (socks) {
  7672.     if (socks->Socket == sock) {
  7673.       user = GetContact(socks->UIN);
  7674.       if (socks->LastTCP) {
  7675.         if (Online) {
  7676.           if (user) {
  7677.             strcpy(msg,socks->LastTCP+18);
  7678.             DoMethod(app->LV_SockList,MUIM_NList_Remove,i);
  7679.             flag = FALSE;
  7680.             SendAMessage(NULL,user->UIN,msg,0x0001,MSG_REMOTE,MSG_VIA_UDP);
  7681.             if (user->UWin) {
  7682.               set(user->UWin->BB_WaitTCP,MUIA_Busy_Speed,MUIV_Busy_Speed_Off);
  7683.               set(user->UWin->BB_WaitTCP,MUIA_ShowMe,FALSE);
  7684.             }
  7685.             if (socks->RCObj) EndChat(socks->RCObj->GP_RemoteObj);
  7686. //          HandleError(DBG_TCP_DBUG,"TCP message being sent via UDP (%s)",user->Nick);
  7687. //          HandleError(DBG_TCP_DBUG,"%s",msg);
  7688.           }
  7689.         }
  7690.       }
  7691.       if (flag) DoMethod(app->LV_SockList,MUIM_NList_Remove,i);
  7692.       break;
  7693.     }
  7694.   }
  7695. }
  7696.  
  7697. FD_CLR(sock,&rset);
  7698. FD_CLR(sock,&wset);
  7699.  
  7700. //HandleError(DBG_TCP_DBUG,"Closing socket %d",sock);
  7701.  
  7702. CloseSocket(sock);
  7703.  
  7704. return;
  7705.  
  7706. }
  7707.  
  7708.  
  7709. char *FindCountryName(UWORD code)
  7710.  
  7711. {
  7712.  
  7713. int i = -1;
  7714.  
  7715. while(CountryCodes[++i] != 0) if (code == CountryCodes[i]) break;
  7716.  
  7717. return(CountryNames[i]);
  7718.  
  7719. }
  7720.  
  7721.  
  7722. void SendMessage2Script(char *msg, ULONG uin, UWORD type)
  7723.  
  7724. {
  7725.  
  7726. char *notifycmd, cmdln[MAXNAMLEN];
  7727.  
  7728. struct AsyncFile *savefh;
  7729.  
  7730. get(app->STR_MsgParse,MUIA_String_Contents,¬ifycmd);
  7731.  
  7732. if (!strlen(notifycmd)) return;
  7733.  
  7734. tmpnam(tmpmsg_fl);
  7735.  
  7736. if (!(savefh = OpenAsync(tmpmsg_fl,MODE_WRITE,AsyncBuf))) return;
  7737. WriteLineAsync(savefh,msg);
  7738. CloseAsync(savefh);
  7739.  
  7740. sprintf(cmdln,"%s %ld %d %s",notifycmd,uin,type,tmpmsg_fl);
  7741.  
  7742. System(cmdln,NULL);
  7743.  
  7744. return;
  7745.  
  7746. }
  7747.  
  7748.  
  7749. void AddUser2CList(struct Contact *user)
  7750.  
  7751. {
  7752.  
  7753. static ULONG lampnum = 0;
  7754.  
  7755. sprintf(user->LampTxt,"\033o[%ld]",lampnum);
  7756.  
  7757. user->LampNum = lampnum;
  7758.  
  7759. if (WhichLamp == 0) {
  7760.   user->LampObj = LampObject, End;
  7761. }
  7762. else {
  7763.   user->LampObj = TWFmultiLEDObject, End;
  7764. }
  7765.  
  7766. DoMethod(app->LV_OfflineList,MUIM_NList_UseImage,user->LampObj,lampnum++,0L);
  7767.  
  7768. DoMethod(app->LV_OfflineList,MUIM_NList_InsertSingle,user,MUIV_NList_Insert_Bottom);
  7769.  
  7770. return;
  7771.  
  7772. }
  7773.  
  7774.  
  7775. void CFWinOpen(ULONG uin, char *msg, UWORD mode, LONG seq, UWORD port)
  7776.  
  7777. {
  7778.  
  7779. char *c, *d;
  7780.  
  7781. static char title[25];
  7782.  
  7783. int i;
  7784.  
  7785. ULONG total;
  7786.  
  7787. struct ChatSession *session;
  7788. struct ChatFileReqIn *CFWin;
  7789. struct Contact *user;
  7790.  
  7791. if (!(user = GetContact(uin))) return;
  7792.  
  7793. if (user->CFWin) {
  7794.   set(user->CFWin->WI_ChatFileInWin,MUIA_Window_Open,TRUE);
  7795.   return;
  7796. }
  7797.  
  7798. if (!(CFWin = AllocVec(sizeof(struct ChatFileReqIn),MEMF_CLEAR))) {
  7799.   HandleError(DBG_OTH_FATL,"Failed to AllocVec %d bytes!",sizeof(struct ChatFileReqIn));
  7800.   return;
  7801. }
  7802.  
  7803. for(c = d = msg; *c; c++, d++) {
  7804.   if (*c == '\r') c++;
  7805.   *d = *c;
  7806. }
  7807. *d = '\0';
  7808.  
  7809. if (mode == TCP_MSG_CHAT) strcpy(title,"Reason For Chat Request");
  7810. else strcpy(title,"Reason For File Transfer");
  7811.  
  7812. CFWin->WI_ChatFileInWin = WindowObject,
  7813.   MUIA_Window_Title, user->Nick,
  7814.   MUIA_Window_CloseGadget, FALSE,
  7815.   MUIA_Window_ID, uin | 0x10000000,
  7816.   MUIA_UserData, seq,
  7817.   WindowContents, VGroup,
  7818.     Child, CFWin->GP_Message = GroupObject,
  7819.       MUIA_UserData, port,
  7820.       MUIA_Frame, MUIV_Frame_Group,
  7821.       MUIA_FrameTitle, title,
  7822.       Child, CFWin->TX_Request = TextObject,
  7823.         MUIA_Background, MUII_TextBack,
  7824.         MUIA_Frame, MUIV_Frame_Text,
  7825.         MUIA_Text_PreParse, "\033c",
  7826.         MUIA_Text_Contents, msg,
  7827.         MUIA_UserData, mode,
  7828.       End,
  7829.       Child, CFWin->LV_Sessions = NListviewObject,
  7830.         MUIA_NListview_NList, NListObject,
  7831.           MUIA_Frame, MUIV_Frame_String,
  7832.           MUIA_CycleChain, TRUE,
  7833.           MUIA_NList_Title, TRUE,
  7834.           MUIA_NList_Format, "BAR,",  //Port, Nicks
  7835.           MUIA_NList_CompareHook,   &CmpSessionHook,
  7836.           MUIA_NList_ConstructHook, &AddSessionHook,
  7837.           MUIA_NList_DestructHook,  &RemSessionHook,
  7838.           MUIA_NList_DisplayHook,   &DisplaySessionHook,
  7839.         End,
  7840.       End,
  7841.     End,
  7842.     Child, VGroup,
  7843.       MUIA_Frame, MUIV_Frame_Group,
  7844.       MUIA_FrameTitle, "Your Reason For Refusal",
  7845.       Child, CFWin->TI_Reason = TextinputObject,
  7846.         MUIA_Frame, MUIV_Frame_String,
  7847.         MUIA_CycleChain, TRUE,
  7848.         MUIA_Textinput_Multiline, TRUE,
  7849.         MUIA_Textinput_Contents, NULL,
  7850.         MUIA_Textinput_MaxLen, 512,
  7851.       End,
  7852.     End,
  7853.     Child, HGroup,
  7854.       Child, CFWin->BT_Accept = SimpleButton("Accept"),
  7855.       Child, CFWin->BT_Join   = SimpleButton("Join"),
  7856.       Child, HSpace(0),
  7857.       Child, CFWin->BT_Refuse = SimpleButton("Refuse"),
  7858.     End,
  7859.   End,
  7860. End;
  7861.  
  7862. if (!CFWin->WI_ChatFileInWin) {
  7863.   HandleError(DBG_OTH_FATL,"Could not create the chat/file response request window.");
  7864.   FreeVec(CFWin);
  7865.   CFWin = NULL;
  7866.   return;
  7867. }
  7868.  
  7869. user->CFWin = CFWin;
  7870.  
  7871. DoMethod(app->App,OM_ADDMEMBER,CFWin->WI_ChatFileInWin);
  7872.  
  7873. set(CFWin->BT_Accept,MUIA_UserData,uin);
  7874. set(CFWin->BT_Accept,MUIA_CycleChain,TRUE);
  7875. set(CFWin->BT_Refuse,MUIA_UserData,uin);
  7876. set(CFWin->BT_Refuse,MUIA_CycleChain,TRUE);
  7877. set(CFWin->BT_Join,MUIA_UserData,uin);
  7878. set(CFWin->BT_Join,MUIA_CycleChain,TRUE);
  7879.  
  7880. DoMethod(CFWin->BT_Accept, MUIM_Notify, MUIA_Pressed, FALSE, CFWin->BT_Accept, 2,
  7881.          MUIM_CallHook, &AcceptHook);
  7882.  
  7883. DoMethod(CFWin->BT_Join, MUIM_Notify, MUIA_Pressed, FALSE, CFWin->BT_Join, 2,
  7884.          MUIM_CallHook, &AcceptHook);
  7885.  
  7886. DoMethod(CFWin->BT_Refuse, MUIM_Notify, MUIA_Pressed, FALSE, CFWin->BT_Refuse, 2,
  7887.          MUIM_CallHook, &RefuseHook);
  7888.  
  7889. get(app->LV_Sessions,MUIA_NList_Entries,&total);
  7890.  
  7891. if (port != 0 || total == 0 || mode != MSG_CHAT) {
  7892.   set(CFWin->LV_Sessions,MUIA_ShowMe,FALSE);
  7893.   set(CFWin->BT_Join,MUIA_ShowMe,FALSE);
  7894. }
  7895. else {
  7896.   for(i = 0; i < total; i++) {
  7897.     DoMethod(app->LV_Sessions,MUIM_NList_GetEntry,i,&session);
  7898.     if (session) DoMethod(CFWin->LV_Sessions,MUIM_NList_InsertSingle,session,MUIV_NList_Insert_Sorted);
  7899.   }
  7900.   set(CFWin->LV_Sessions,MUIA_ShowMe,TRUE);
  7901.   set(CFWin->BT_Join,MUIA_ShowMe,TRUE);
  7902. }
  7903.  
  7904. set(CFWin->WI_ChatFileInWin,MUIA_Window_Open,TRUE);
  7905.  
  7906. return;
  7907.  
  7908. }
  7909.  
  7910.  
  7911. void __asm Accept(REG(a2) APTR obj)
  7912.  
  7913. {
  7914.  
  7915. LONG seq, sel;
  7916.  
  7917. ULONG uin, mode, port;
  7918.  
  7919. struct ChatSession *chat;
  7920. struct Contact *user;
  7921.  
  7922. get(obj,MUIA_UserData,&uin);
  7923.  
  7924. if (!(user = GetContact(uin))) return;
  7925.  
  7926. get(user->CFWin->GP_Message,MUIA_UserData,&port);
  7927. get(user->CFWin->TX_Request,MUIA_UserData,&mode);
  7928. get(user->CFWin->WI_ChatFileInWin,MUIA_UserData,&seq);
  7929.  
  7930. if (obj == user->CFWin->BT_Join) {
  7931.   get(user->CFWin->LV_Sessions,MUIA_NList_Active,&sel);
  7932.   if (sel == MUIV_NList_Active_Off) {
  7933.     HandleError(DBG_OTH_FATL,"You must choose a chat session to 'Join'.");
  7934.     return;
  7935.   }
  7936.   DoMethod(user->CFWin->LV_Sessions,MUIM_NList_GetEntry,sel,&chat);
  7937.   if (chat) user->ChatListen = chat->ChatListen;
  7938. }
  7939.  
  7940. set(user->CFWin->WI_ChatFileInWin,MUIA_Window_Open,FALSE);
  7941.  
  7942. if (mode == TCP_MSG_CHAT) {
  7943.   if (!user->ChatListen) user->ChatListen = OpenTCPListen(SOCK_CHAT);
  7944.   if (port) {
  7945.     HandleError(DBG_TCP_DBUG,"While accepting chat, port = %d",port);
  7946.     if (!OpenTCPSocket(user,SOCK_CHAT,user->IP,port)) {
  7947.       if (!OpenTCPSocket(user,SOCK_CHAT,user->RealIP,port)) HandleError(DBG_TCP_ERRS,"Could not open a chat connection to %s.",user->Nick);
  7948.     }
  7949.   }
  7950.   SendTCPMessage(uin,LINE,TCP_ACK,mode,TCP_MSG_AUTO,seq,LINE,0x00000000,TCP_STAT_ONLINE,user->ChatListen);
  7951. }
  7952. else {
  7953.   if (!FileListen) FileListen = OpenTCPListen(SOCK_FILE);
  7954.   SendTCPMessage(uin,LINE,TCP_ACK,mode,TCP_MSG_AUTO,seq,LINE,0x00000000,TCP_STAT_ONLINE,FileListen);
  7955. }
  7956.  
  7957. //DoMethod(app->App,OM_REMMEMBER,user->CFWin->WI_ChatFileInWin);
  7958.  
  7959. //MUI_DisposeObject(user->CFWin->WI_ChatFileInWin);
  7960.  
  7961. //FreeVec(user->CFWin);
  7962.  
  7963. //user->CFWin = NULL;
  7964.  
  7965. user->Type = mode;
  7966.  
  7967. return;
  7968.  
  7969. }
  7970.  
  7971.  
  7972. void __asm Refuse(REG(a2) APTR obj)
  7973.  
  7974. {
  7975.  
  7976. char *msg;
  7977.  
  7978. LONG seq;
  7979.  
  7980. ULONG uin, mode;
  7981.  
  7982. struct Contact *user;
  7983.  
  7984. get(obj,MUIA_UserData,&uin);
  7985.  
  7986. if (!(user = GetContact(uin))) return;
  7987.  
  7988. get(user->CFWin->TX_Request,MUIA_UserData,&mode);
  7989. get(user->CFWin->WI_ChatFileInWin,MUIA_UserData,&seq);
  7990. get(user->CFWin->TI_Reason,MUIA_Textinput_Contents,&msg);
  7991.  
  7992. SendTCPMessage(uin,msg,TCP_ACK,mode,TCP_MSG_AUTO,seq,LINE,0x00000000,TCP_STAT_REFUSE,0);
  7993.  
  7994. set(user->CFWin->WI_ChatFileInWin,MUIA_Window_Open,FALSE);
  7995.  
  7996. //DoMethod(app->App,OM_REMMEMBER,user->CFWin->WI_ChatFileInWin);
  7997.  
  7998. //MUI_DisposeObject(user->CFWin->WI_ChatFileInWin);
  7999.  
  8000. //FreeVec(user->CFWin);
  8001.  
  8002. //user->CFWin = NULL;
  8003.  
  8004. return;
  8005.  
  8006. }
  8007.  
  8008.  
  8009. APTR __asm AddCols(REG(a2) APTR pool, REG(a1) struct Column *col)
  8010.  
  8011. {
  8012.  
  8013. struct Column *newcol = NULL;
  8014.  
  8015. if (!(newcol = AllocPooled(pool,sizeof(struct Column)))) return(NULL);
  8016.  
  8017. if (!(newcol->Name = AllocPooled(pool,strlen(col->Name)+1))) {
  8018.   FreePooled(pool,newcol,sizeof(struct Column));
  8019.   return(NULL);
  8020. }
  8021. strcpy(newcol->Name,col->Name);
  8022.  
  8023. if (!(newcol->COL = AllocPooled(pool,strlen(col->COL)+1))) {
  8024.   FreePooled(pool,newcol->Name,strlen(newcol->Name)+1);
  8025.   FreePooled(pool,newcol,sizeof(struct Column));
  8026.   return(NULL);
  8027. }
  8028. strcpy(newcol->COL,col->COL);
  8029.  
  8030. return(newcol);
  8031.  
  8032. }
  8033.  
  8034.  
  8035. void __asm RemCols(REG(a2) APTR pool, REG(a1) struct Column *newcol)
  8036.  
  8037. {
  8038.  
  8039. FreePooled(pool,newcol->Name,strlen(newcol->Name)+1);
  8040. FreePooled(pool,newcol->COL,strlen(newcol->COL)+1);
  8041. FreePooled(pool,newcol,sizeof(struct Column));
  8042.  
  8043. return;
  8044.  
  8045. }
  8046.  
  8047.  
  8048. LONG __asm CmpCols(REG(a1) struct Column *c1, REG(a2) struct Column *c2)
  8049.  
  8050. {
  8051.  
  8052. return(strcmp(c1->Name,c2->Name));
  8053.  
  8054. }
  8055.  
  8056.  
  8057. void __asm DisplayCols(REG(a2) char **array, REG(a1) struct Column *col)
  8058.  
  8059. {
  8060.  
  8061. if (col) {
  8062.   *array = col->Name;
  8063. }
  8064. else {
  8065.   *array = "Columns";
  8066. }
  8067.  
  8068. return;
  8069.  
  8070. }
  8071.  
  8072.  
  8073. ULONG __asm ColsDispatcher(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg)
  8074.  
  8075. {
  8076.  
  8077. switch(msg->MethodID) {
  8078.   case MUIM_DragQuery:
  8079.     return(COLS_mDragQuery(cl,obj,(APTR)msg));
  8080.   case MUIM_DragDrop:
  8081.     return(COLS_mDragDrop(cl,obj,(APTR)msg));
  8082. }
  8083.  
  8084. return(DoSuperMethodA(cl,obj,msg));
  8085.  
  8086. }
  8087.  
  8088.  
  8089. ULONG COLS_mDragQuery(struct IClass *cl, Object *obj, struct MUIP_DragDrop *msg)
  8090.  
  8091. {
  8092.  
  8093. if (msg->obj == obj) return(DoSuperMethodA(cl,obj,(Msg)msg));
  8094. else {
  8095.   if (msg->obj == (Object *)muiUserData(obj)) return(MUIV_DragQuery_Accept);
  8096.   else return(MUIV_DragQuery_Refuse);
  8097. }
  8098.  
  8099. }
  8100.  
  8101.  
  8102. ULONG COLS_mDragDrop(struct IClass *cl, Object *obj, struct MUIP_DragDrop *msg)
  8103.  
  8104. {
  8105.  
  8106. APTR entry, parent;
  8107.  
  8108. LONG dropmark, sortable;
  8109.  
  8110. ULONG ret = 0;
  8111.  
  8112. if (obj == app->LV_StoreUser) parent = app->LV_ColsStore;
  8113. else parent = app->LV_ColsUse;
  8114.  
  8115. if (msg->obj == obj) ret = DoSuperMethodA(cl,obj,(Msg)msg);
  8116. else {
  8117.   DoMethod(msg->obj,MUIM_NList_GetEntry,MUIV_NList_GetEntry_Active,&entry);
  8118.   get(obj,MUIA_NList_DragSortable,&sortable);
  8119.   if (sortable) {
  8120.     get(obj,MUIA_NList_DropMark,&dropmark);
  8121.     DoMethod(parent,MUIM_NList_InsertSingle,entry,dropmark);
  8122.   }
  8123.   else DoMethod(parent,MUIM_NList_InsertSingle,entry,MUIV_NList_Insert_Sorted);
  8124.   DoMethod(msg->obj,MUIM_NList_Remove,MUIV_NList_Remove_Active);
  8125.   get(obj,MUIA_NList_InsertPosition,&dropmark);
  8126.   set(obj,MUIA_NList_Active,dropmark);
  8127.   set(msg->obj,MUIA_List_Active,MUIV_NList_Active_Off);
  8128. }
  8129.  
  8130. ReDrawCList();
  8131.  
  8132. return(ret);
  8133.  
  8134. }
  8135.  
  8136.  
  8137. void ReDrawCList(void)
  8138.  
  8139. {
  8140.  
  8141. char format[100];
  8142.  
  8143. int i;
  8144.  
  8145. LONG total;
  8146.  
  8147. struct Column *col;
  8148.  
  8149. format[0] = '\0';
  8150.  
  8151. get(app->LV_ColsUse,MUIA_NList_Entries,&total);
  8152.  
  8153. for(i = 0; i < total; i++) {
  8154.   DoMethod(app->LV_ColsUse,MUIM_NList_GetEntry,i,&col);
  8155.   strcat(format,col->COL);
  8156.   if (i < total-1) strcat(format," BAR,");
  8157. }
  8158.  
  8159. set(app->LV_OfflineList,MUIA_NList_Format,format);
  8160.  
  8161. return;
  8162.  
  8163. }
  8164.  
  8165.  
  8166. APTR __asm AddIgnore(REG(a2) APTR pool, REG(a1) struct IgnoreUIN *ignore)
  8167.  
  8168. {
  8169.  
  8170. struct IgnoreUIN *newignore = NULL;
  8171.  
  8172. if (!(newignore = AllocPooled(pool,sizeof(struct IgnoreUIN)))) return(NULL);
  8173.  
  8174. newignore->UIN = ignore->UIN;
  8175. newignore->Timehack = ignore->Timehack;
  8176. newignore->ExpireDays = ignore->ExpireDays;
  8177.  
  8178. strcpy(newignore->Nick,ignore->Nick);
  8179.  
  8180. return(newignore);
  8181.  
  8182. }
  8183.  
  8184.  
  8185. void __asm RemIgnore(REG(a2) APTR pool, REG(a1) struct IgnoreUIN *newignore)
  8186.  
  8187. {
  8188.  
  8189. FreePooled(pool,newignore,sizeof(struct IgnoreUIN));
  8190.  
  8191. return;
  8192.  
  8193. }
  8194.  
  8195.  
  8196. LONG __asm CmpIgnore(REG(a1) struct IgnoreUIN *i1, REG(a2) struct IgnoreUIN *i2)
  8197.  
  8198. {
  8199.  
  8200. if (i1->UIN < i2->UIN) return(-1);
  8201. if (i1->UIN > i2->UIN) return(1);
  8202.  
  8203. return(0);
  8204.  
  8205. }
  8206.  
  8207.  
  8208. void __asm DisplayIgnore(REG(a2) char **array, REG(a1) struct IgnoreUIN *ignore)
  8209.  
  8210. {
  8211.  
  8212. static char uin[32], tme[32], days[32];
  8213.  
  8214. struct tm *time_p;
  8215.  
  8216. if (ignore) {
  8217.   sprintf(uin,"%ld",ignore->UIN);
  8218.   time_p = localtime(&ignore->Timehack);
  8219.   strftime(tme,sizeof(tme),"%d %b %Y",time_p);
  8220.   if (ignore->ExpireDays == 0) strcpy(days,"Never Expire");
  8221.   else sprintf(days,"%d Days Remaining.",(ignore->ExpireDays-time(NULL))/86400);
  8222.   *array++ = uin;
  8223.   *array++ = ignore->Nick;
  8224.   *array++ = tme;
  8225.   *array   = days;
  8226. }
  8227. else {
  8228.   *array++ = "Ignored UIN";
  8229.   *array++ = "Nick";
  8230.   *array++ = "Date Ignored";
  8231.   *array   = "Days Remaining Ignored";
  8232. }
  8233.  
  8234. return;
  8235.  
  8236. }
  8237.  
  8238.  
  8239. void __asm Add2Ignore(REG(a2) APTR obj)
  8240.  
  8241. {
  8242.  
  8243. char uin_str[32];
  8244.  
  8245. ULONG uin;
  8246.  
  8247. if (obj == app->BT_AddIgnore) get(app->STR_UIN2Ignore,MUIA_String_Integer,&uin);
  8248. else get(obj,MUIA_UserData,&uin);
  8249.  
  8250. sprintf(uin_str,"%ld",uin);
  8251.  
  8252. set(app->TX_IgnoreUIN,MUIA_Text_Contents,uin_str);
  8253. set(app->TX_IgnoreNick,MUIA_Text_Contents,GetNick(uin));
  8254. set(app->NU_IgnoreDays,MUIA_Numeric_Value,30);
  8255.  
  8256. set(app->BT_IgnoreOK,MUIA_UserData,uin);
  8257.  
  8258. set(app->WI_EditIgnore,MUIA_Window_Open,TRUE);
  8259.  
  8260. return;
  8261.  
  8262. }
  8263.  
  8264.  
  8265. BOOL CheckIgnore(ULONG uin)
  8266.  
  8267. {
  8268.  
  8269. int i;
  8270.  
  8271. ULONG total;
  8272.  
  8273. struct IgnoreUIN *ignore;
  8274.  
  8275. get(app->LV_IgnoreUIN,MUIA_NList_Entries,&total);
  8276.  
  8277. if (total) {
  8278.   for(i = 0; i < total; i++) {
  8279.     DoMethod(app->LV_IgnoreUIN,MUIM_NList_GetEntry,i,&ignore);
  8280.     if (ignore) {
  8281.       if (ignore->UIN == uin) return(TRUE);
  8282.     }
  8283.   }
  8284. }
  8285.  
  8286. return(FALSE);
  8287.  
  8288. }
  8289.  
  8290.  
  8291. void Add2Log(UBYTE list, struct UDP_Header *Header, BOOL ack, UWORD len, char *pkt)
  8292.  
  8293.  
  8294. {
  8295.  
  8296. APTR LogList;
  8297.  
  8298. struct ICQLog Log;
  8299.  
  8300. Log.UIN = Header->UIN;
  8301. if (Header->Command == TCP_MESSAGE) Log.Seq = Header->TCP_Sequence;
  8302. else Log.Seq = Header->Sequence;
  8303. Log.Se2 = Header->Sequence2;
  8304. Log.Cmd = Header->Command;
  8305. Log.Ack = ack;
  8306. Log.Len = len;
  8307. Log.Pkt = pkt;
  8308. Log.Resend = 0;
  8309. Log.Timehack = time(NULL);
  8310.  
  8311. switch(list) {
  8312.   case LOG_CLIENT:
  8313.     LogList = app->LV_ICQCliLog;
  8314.     if (Log.Cmd != C_KEEP_ALIVE) LastSend = time(NULL);
  8315.     break;
  8316.   case LOG_SERVER:
  8317.     LogList = app->LV_ICQSrvLog;
  8318.     break;
  8319. }
  8320.  
  8321. DoMethod(LogList,MUIM_NList_InsertSingle,&Log,MUIV_NList_Insert_Bottom);
  8322.  
  8323.  
  8324. return;
  8325.  
  8326. }
  8327.  
  8328.  
  8329. void __asm ForwardMsg(REG(a2) APTR obj)
  8330.  
  8331. {
  8332.  
  8333. char *msg2;
  8334.  
  8335. LONG pos, sel = MUIV_NList_NextSelected_Start;
  8336.  
  8337. ULONG uin;
  8338.  
  8339. struct Contact    *user;
  8340. struct ICQMessage *msg, *desc;
  8341.  
  8342. get(obj,MUIA_UserData,&uin);
  8343.  
  8344. if (!(user = GetContact(uin))) return;
  8345.  
  8346. get(user->UWin->LV_Msgs,MUIA_NList_Active,&pos);
  8347.  
  8348. if (pos < 0) return;
  8349.  
  8350. DoMethod(user->UWin->LV_Msgs,MUIM_NList_GetEntry,pos,&msg);
  8351.  
  8352. if (msg->UIN == 0 && msg->Type != MSG_URL) return;
  8353.  
  8354. if (!(msg2 = AllocVec(strlen(msg->Msg)+0x100,MEMF_CLEAR))) return;
  8355.  
  8356. if (msg->Type == MSG_URL) {
  8357.   DoMethod(user->UWin->LV_Msgs,MUIM_NList_GetEntry,pos-1,&desc);
  8358.   sprintf(msg2,"Forwarded from %s: %s\xFE%s",GetNick(uin),desc->Msg,msg->Msg+2);
  8359. }
  8360. else sprintf(msg2,"Forwarded from %s: %s",GetNick(uin),msg->Msg);
  8361.  
  8362. DoMethod(app->LV_OfflineList,MUIM_NList_NextSelected,&sel);
  8363.  
  8364. while(sel != MUIV_NList_NextSelected_End) {
  8365.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,sel,&user);
  8366.   if (user->UIN != uin) SendAMessage(obj,user->UIN,msg2,msg->Type,MSG_BOTH,MSG_VIA_BEST);
  8367.   DoMethod(app->LV_OfflineList,MUIM_NList_NextSelected,&sel);
  8368. }
  8369.  
  8370. FreeVec(msg2);
  8371.  
  8372. return;
  8373.  
  8374. }
  8375.  
  8376.  
  8377. char *PreParseMsg(ULONG uin, UWORD type, char *msg)
  8378.  
  8379. {
  8380.  
  8381. char cmdln[MAXNAMLEN], *cmd;
  8382.  
  8383. struct AsyncFile *savefh;
  8384.  
  8385. get(app->STR_MsgPreParse,MUIA_String_Contents,&cmd);
  8386.  
  8387. if (!strlen(cmd)) return(msg);
  8388.  
  8389. tmpnam(tmpmsg_fl);
  8390.  
  8391. if (!(savefh = OpenAsync(tmpmsg_fl,MODE_WRITE,AsyncBuf))) return(msg);
  8392. WriteLineAsync(savefh,msg);
  8393. CloseAsync(savefh);
  8394.  
  8395. sprintf(cmdln,"%s %ld %d %s",cmd,uin,type,tmpmsg_fl);
  8396.  
  8397. System(cmdln,NULL);
  8398.  
  8399. return(LINE);
  8400.  
  8401. }
  8402.  
  8403.  
  8404. void __asm SetCountry(REG(a2) APTR obj)
  8405.  
  8406. {
  8407.  
  8408. APTR List, String;
  8409.  
  8410. char *country, tmp[128];
  8411.  
  8412. ULONG entry;
  8413.  
  8414. if (obj == app->POP_Country) {
  8415.   List = app->LV_Countries;
  8416.   String = app->STR_Country;
  8417. }
  8418. else {
  8419.   List = app->LV_WkCountries;
  8420.   String = app->STR_WkCountry;
  8421. }
  8422.  
  8423. get(List,MUIA_NList_EntryClick,&entry);
  8424.  
  8425. DoMethod(List,MUIM_NList_GetEntry,entry,&country);
  8426.  
  8427. sprintf(tmp,"%d %s",CountryCodes[entry],country);
  8428.  
  8429. set(String,MUIA_String_Contents,tmp);
  8430. set(String,MUIA_UserData,CountryCodes[entry]);
  8431.  
  8432. return;
  8433.  
  8434. }
  8435.  
  8436.  
  8437. UWORD MakeBeats(time_t time_norm)
  8438.  
  8439. {
  8440.  
  8441. float beatf;
  8442.  
  8443. LONG time_zone;
  8444.  
  8445. time_t t1;
  8446.  
  8447. ULONG time_diff, secs, micros;
  8448.  
  8449. UWORD beats;
  8450.  
  8451. WORD hour;
  8452.  
  8453. struct ClockData clock;
  8454.  
  8455. t1 = time(NULL);
  8456.  
  8457. CurrentTime(&secs,µs);
  8458.  
  8459. time_diff = t1 - secs;
  8460.  
  8461. time_norm -= time_diff;
  8462.  
  8463. get(app->NU_TimeZone,MUIA_Numeric_Value,&time_zone);
  8464.  
  8465. Amiga2Date(time_norm,&clock);
  8466.  
  8467. hour = (clock.hour - time_zone) + 1;
  8468.  
  8469. if (hour > 23) hour -= 24;
  8470. if (hour < 0)  hour += 24;
  8471.  
  8472. beatf = (float)((hour*60*60)+(clock.min*60)+clock.sec)/86.4;
  8473.  
  8474. beats = beatf;
  8475.  
  8476. return(beats);
  8477.  
  8478. }
  8479.  
  8480.  
  8481. APTR __asm AddAddUIN(REG(a2) APTR pool, REG(a1) struct MSG_AddUIN *adduin)
  8482.  
  8483. {
  8484.  
  8485. struct MSG_AddUIN *newadduin = NULL;
  8486.  
  8487. if (!(newadduin = AllocPooled(pool,sizeof(struct MSG_AddUIN)))) return(NULL);
  8488.  
  8489. if (!(newadduin->Nick = AllocPooled(pool,strlen(adduin->Nick)+1))) {
  8490.   FreePooled(pool,adduin,sizeof(struct MSG_AddUIN));
  8491.   return(NULL);
  8492. }
  8493. else strcpy(newadduin->Nick,adduin->Nick);
  8494.  
  8495. newadduin->UIN = adduin->UIN;
  8496.  
  8497. return(newadduin);
  8498.  
  8499. }
  8500.  
  8501.  
  8502. void __asm RemAddUIN(REG(a2) APTR pool, REG(a1) struct MSG_AddUIN *adduin)
  8503.  
  8504. {
  8505.  
  8506. FreePooled(pool,adduin->Nick,strlen(adduin->Nick)+1);
  8507. FreePooled(pool,adduin,sizeof(struct MSG_AddUIN));
  8508.  
  8509. return;
  8510.  
  8511. }
  8512.  
  8513.  
  8514. LONG __asm CmpAddUIN(REG(a1) struct MSG_AddUIN *a1, REG(a2) struct MSG_AddUIN *a2)
  8515.  
  8516. {
  8517.  
  8518. if (a1->UIN < a2->UIN) return(-1);
  8519. if (a1->UIN > a2->UIN) return(1);
  8520.  
  8521. return(0);
  8522.  
  8523. }
  8524.  
  8525.  
  8526. void __asm DisplayAddUIN(REG(a2) char **array, REG(a1) struct MSG_AddUIN *adduin)
  8527.  
  8528. {
  8529.  
  8530. static char buf[32], already[5];
  8531.  
  8532. if (adduin) {
  8533.   sprintf(buf,"%ld",adduin->UIN);
  8534.   if (GetContact(adduin->UIN)) strcpy(already,"Yes");
  8535.   else strcpy(already,"No");
  8536.   *array++ = buf;
  8537.   *array++ = adduin->Nick;
  8538.   *array   = already;
  8539. }
  8540. else {
  8541.   *array++ = "UIN";
  8542.   *array++ = "Nick";
  8543.   *array   = "Already have it?";
  8544. }
  8545.  
  8546. return;
  8547.  
  8548. }
  8549.  
  8550.  
  8551. void __asm GetAddUINInfo(REG(a2) APTR obj)
  8552.  
  8553. {
  8554.  
  8555. ULONG entry;
  8556.  
  8557. struct MSG_AddUIN *adduin;
  8558.  
  8559. get(app->LV_ToAddUIN,MUIA_NList_Active,&entry);
  8560.  
  8561. if (entry == MUIV_NList_Active_Off) return;
  8562.  
  8563. DoMethod(app->LV_ToAddUIN,MUIM_NList_GetEntry,entry,&adduin);
  8564.  
  8565. set(obj,MUIA_UserData,adduin->UIN);
  8566.  
  8567. GetUINInfo(obj);
  8568.  
  8569. return;
  8570.  
  8571. }
  8572.  
  8573.  
  8574. void __asm ShareContacts(REG(a2) APTR obj)
  8575.  
  8576. {
  8577.  
  8578. char msg[450], tmp[50];
  8579.  
  8580. int i = 0;
  8581.  
  8582. LONG sel = MUIV_NList_NextSelected_Start;
  8583.  
  8584. ULONG uin;
  8585.  
  8586. struct Contact *user;
  8587.  
  8588. get(obj,MUIA_UserData,&uin);
  8589.  
  8590. DoMethod(app->LV_OfflineList,MUIM_NList_NextSelected,&sel);
  8591.  
  8592. msg[0] = '\0';
  8593.  
  8594. while(sel != MUIV_NList_NextSelected_End) {
  8595.   DoMethod(app->LV_OfflineList,MUIM_NList_GetEntry,sel,&user);
  8596.   sprintf(tmp,"%ld\xFE%s\xFE",user->UIN,GetNick(user->UIN));
  8597.   if (strlen(msg) + strlen(tmp) + 4 < 450) {
  8598.     i++;
  8599.     strcat(msg,tmp);
  8600.   }
  8601.   DoMethod(app->LV_OfflineList,MUIM_NList_NextSelected,&sel);
  8602. }
  8603.  
  8604. if (i == 0) return;
  8605.  
  8606. sprintf(tmp,"%d\xFE",i);
  8607.  
  8608. strins(msg,tmp);
  8609.  
  8610. SendAMessage(obj,uin,msg,MSG_ADDUIN,MSG_REMOTE,MSG_VIA_BEST);
  8611.  
  8612. return;
  8613.  
  8614. }
  8615.  
  8616.  
  8617. APTR __asm AddErr(REG(a2) APTR pool, REG(a1) struct ErrorMsgs *err)
  8618.  
  8619. {
  8620.  
  8621. struct ErrorMsgs *newerr = NULL;
  8622.  
  8623. if (!(newerr = AllocPooled(pool,sizeof(struct ErrorMsgs)))) return(NULL);
  8624.  
  8625. if (!(newerr->Error = AllocPooled(pool,strlen(err->Error)+1))) {
  8626.   FreePooled(pool,err,sizeof(struct ErrorMsgs));
  8627.   return(NULL);
  8628. }
  8629. else strcpy(newerr->Error,err->Error);
  8630.  
  8631. newerr->Timehack = err->Timehack;
  8632.  
  8633. return(newerr);
  8634.  
  8635. }
  8636.  
  8637.  
  8638. void __asm RemErr(REG(a2) APTR pool, REG(a1) struct ErrorMsgs *err)
  8639.  
  8640. {
  8641.  
  8642. FreePooled(pool,err->Error,strlen(err->Error)+1);
  8643. FreePooled(pool,err,sizeof(struct ErrorMsgs));
  8644.  
  8645. return;
  8646.  
  8647. }
  8648.  
  8649.  
  8650. LONG __asm CmpErr(REG(a1) struct ErrorMsgs *a1, REG(a2) struct ErrorMsgs *a2)
  8651.  
  8652. {
  8653.  
  8654. if (a1->Timehack < a2->Timehack) return(-1);
  8655. if (a1->Timehack > a2->Timehack) return(1);
  8656.  
  8657. return(0);
  8658.  
  8659. }
  8660.  
  8661.  
  8662. void __asm DisplayErr(REG(a2) char **array, REG(a1) struct ErrorMsgs *err)
  8663.  
  8664. {
  8665.  
  8666. static char buf[10];
  8667.  
  8668. if (err) {
  8669.   strncpy(buf,ctime(&err->Timehack)+11,8);
  8670.   *array++ = buf;
  8671.   *array   = err->Error;
  8672. }
  8673. else {
  8674.   *array++ = "Time";
  8675.   *array   = "Error Msg";
  8676. }
  8677.  
  8678. return;
  8679.  
  8680. }
  8681.  
  8682.  
  8683. void HandleError(UBYTE type, char *ErrorMsg, ...)
  8684.  
  8685. {
  8686.  
  8687. BOOL *winopen, *option = NULL, flag = FALSE;
  8688.  
  8689. va_list ap;
  8690.  
  8691. struct ErrorMsgs Err;
  8692.  
  8693. va_start(ap,ErrorMsg);
  8694.  
  8695. vsprintf(err_buf,ErrorMsg,ap);
  8696.  
  8697. va_end(ap);
  8698.  
  8699. if (type != DBG_OTH_FATL && type != DBG_OTH_INFO && type != DBG_UDP_ERRS && type != DBG_TCP_ERRS) {
  8700.   if (type == DBG_UDP_PKTS) get(app->CH_UDPPkts,MUIA_Selected,&option);
  8701.   if (type == DBG_UDP_DBUG) get(app->CH_UDPDebug,MUIA_Selected,&option);
  8702.   if (type == DBG_TCP_PKTS) get(app->CH_TCPPkts,MUIA_Selected,&option);
  8703.   if (type == DBG_TCP_DBUG) get(app->CH_TCPDebug,MUIA_Selected,&option);
  8704.   if (!option) return;
  8705. }
  8706. else flag = TRUE;
  8707.  
  8708. Err.Timehack = time(NULL);
  8709. Err.Error = err_buf;
  8710.  
  8711. DoMethod(app->LV_Errors,MUIM_NList_InsertSingle,&Err,MUIV_NList_Insert_Bottom);
  8712. DoMethod(app->LV_Errors,MUIM_NList_Jump,MUIV_NList_Jump_Bottom);
  8713.  
  8714. if (flag) {
  8715.   get(app->WI_ErrorWin,MUIA_Window_Open,&winopen);
  8716.   if (!winopen) set(app->WI_ErrorWin,MUIA_Window_Open,TRUE);
  8717. }
  8718.  
  8719. return;
  8720.  
  8721. }
  8722.  
  8723.  
  8724. void PrepTCPMessage(struct TCP_Message *tcpmsg, ULONG ToUIN)
  8725.  
  8726. {
  8727.  
  8728. int i;
  8729.  
  8730. UWORD MsgStatus[] = {TCP_MSG_REAL, TCP_MSGF_S_INVISIBLE, TCP_MSGF_S_NA, TCP_MSG_REAL, TCP_MSGF_S_OCCUPIED, TCP_MSGF_S_AWAY, TCP_MSGF_S_DND, TCP_MSG_REAL};
  8731.  
  8732. ULONG index, total;
  8733.  
  8734. struct Contact *user;
  8735. struct Sockets *socks;
  8736.  
  8737. get(app->STR_ICQUIN,MUIA_String_Integer,&tcpmsg->UIN);
  8738.  
  8739. user = GetContact(ToUIN);
  8740.  
  8741. tcpmsg->Message = tcpmsg->Chat_Session = tcpmsg->File_Name = LINE;
  8742.  
  8743. tcpmsg->X1 = tcpmsg->Chat_X2 = tcpmsg->File_X3 = 0;
  8744. tcpmsg->Chat_RevPort = tcpmsg->File_RevPort = 0;
  8745. tcpmsg->Chat_Port = tcpmsg->File_Port = tcpmsg->File_Size = 0;
  8746.  
  8747. get(app->LV_SockList,MUIA_NList_Entries,&total);
  8748.  
  8749. for(i = 0; i < total; i++) {
  8750.   DoMethod(app->LV_SockList,MUIM_NList_GetEntry,i,&socks);
  8751.   if (socks) if (socks->Type == SOCK_MESSAGE && socks->Dir == TCP_DIR_LISTEN) break;
  8752. }
  8753.  
  8754. tcpmsg->TCP_MsgIP = socks->IP;
  8755. tcpmsg->TCP_RealIP = socks->IP;
  8756. tcpmsg->TCP_MsgPort = socks->Port;
  8757.  
  8758. get(app->CY_MyStatus,MUIA_Cycle_Active,&index);
  8759.  
  8760. tcpmsg->TCP_Status = TCPCodes[index];
  8761.  
  8762. if (tcpmsg->MsgCommand != TCP_MSG_AUTO) {
  8763.   MsgStatus[0] = MsgStatus[3] = MsgStatus[7] = tcpmsg->MsgCommand;
  8764.   tcpmsg->MsgCommand |= MsgStatus[index];
  8765. }
  8766.  
  8767. return;
  8768.  
  8769. }
  8770.  
  8771.  
  8772. LONG SendTCPPacket(ULONG to, UWORD cmd, char *buf, UWORD len, UWORD revlen)
  8773.  
  8774. {
  8775.  
  8776. LONG ret = -2;
  8777.  
  8778. struct Contact *user;
  8779. struct Sockets *socks;
  8780.  
  8781. if (!(user = GetContact(to))) return(FALSE);
  8782.  
  8783. if (!(socks = GetSocketFmContact(user,SOCK_MESSAGE))) {
  8784.   if (user->CanTCP != 4) return(FALSE);
  8785.   if (!(ret = OpenTCPSocket(user,SOCK_MESSAGE,user->IP,user->Port))) {
  8786.     if (!(ret = OpenTCPSocket(user,SOCK_MESSAGE,user->RealIP,user->Port))) return(FALSE);
  8787.   }
  8788.   socks = GetSocketFmContact(user,SOCK_MESSAGE);
  8789.   if (user->Status & STATUSF_HIDEIP) socks->Hidden = TRUE;
  8790. }
  8791.  
  8792. if (ret == -1) return(ret);
  8793.  
  8794. if (!socks->HadInit) SendTCPInit(socks->Socket,user,0);
  8795.  
  8796. if (cmd != TCP_ACK) {
  8797.   if (user->UWin) {
  8798.     set(user->UWin->BB_WaitTCP,MUIA_ShowMe,TRUE);
  8799.     set(user->UWin->BB_WaitTCP,MUIA_Busy_Speed,MUIV_Busy_Speed_User);
  8800.   }
  8801. }
  8802.  
  8803. send(socks->Socket,(char *)&revlen,2,0);
  8804. send(socks->Socket,buf,len,0);
  8805.  
  8806. socks->Timehack = time(NULL);
  8807.  
  8808. return(ret);
  8809.  
  8810. }
  8811.  
  8812.  
  8813. void SendTCPMsgViaUDP(ULONG UIN)
  8814.  
  8815. {
  8816.  
  8817. int i;
  8818.  
  8819. ULONG total, Seq;
  8820.  
  8821. struct ICQLog *log;
  8822. struct TCP_Message TCPMsg;
  8823.  
  8824. get(app->LV_ICQCliLog,MUIA_NList_Entries,&total);
  8825.  
  8826. if (!total) return;
  8827.  
  8828. for(i = 0; i < total; i++) {
  8829.   DoMethod(app->LV_ICQCliLog,MUIM_NList_GetEntry,i,&log);
  8830.   if (log) {
  8831.     if (log->Cmd == TCP_MESSAGE && log->UIN == UIN && log->Pkt) {
  8832.       TCP_ParseMsgPacket(&TCPMsg,log->Pkt,&Seq);
  8833.       SendAMessage(NULL,log->UIN,TCPMsg.Message,TCPMsg.Type,MSG_REMOTE,MSG_VIA_UDP);
  8834.       HandleError(DBG_TCP_DBUG,"Sending a message via UDP from a TCP packet to %s",GetNick(log->UIN));
  8835.       HandleError(DBG_TCP_DBUG,"> %s",TCPMsg.Message);
  8836.       FreeVec(log->Pkt);
  8837.       log->Pkt = NULL;
  8838.       log->UIN = 0;
  8839.       log->Len = 0;
  8840.       DoMethod(app->LV_ICQCliLog,MUIM_NList_Redraw,i);
  8841.     }
  8842.   }
  8843. }
  8844.     
  8845. return;
  8846.  
  8847. }
  8848.  
  8849.  
  8850. void __asm SaveErrors(REG(a2) APTR obj)
  8851.  
  8852. {
  8853.  
  8854. char save_fl[MAXNAMLEN], line[1024];
  8855.  
  8856. char title[] = "Save Error Log:";
  8857.  
  8858. int i;
  8859.  
  8860. LONG entries;
  8861.  
  8862. struct AsyncFile     *savefh;
  8863. struct ErrorMsgs     *errs;
  8864. struct FileRequester *myasl;
  8865. struct Window        *mywin = NULL;
  8866.  
  8867. struct TagItem MyASLTags[] = {
  8868.   {ASLFR_TitleText,    NULL},
  8869.   {ASLFR_Window,       NULL},
  8870.   {ASLFR_InitialDrawer,NULL},
  8871.   {ASLFR_DoSaveMode,   TRUE},
  8872.   {ASLFR_RejectIcons,  TRUE},
  8873.  
  8874.   {TAG_DONE,NULL},
  8875. };
  8876.  
  8877. get(app->LV_Errors,MUIA_NList_Entries,&entries);
  8878. get(app->WI_Main,MUIA_Window_Window,&mywin);
  8879.  
  8880. MyASLTags[0].ti_Data = (ULONG)title;
  8881. MyASLTags[1].ti_Data = (ULONG)mywin;
  8882. MyASLTags[2].ti_Data = (ULONG)currentdir;
  8883.  
  8884. if (entries < 1) return;
  8885.  
  8886. if (!(myasl = MUI_AllocAslRequest(ASL_FileRequest,MyASLTags))) return;
  8887.  
  8888. if (!MUI_AslRequest(myasl,NULL)) return;
  8889.  
  8890. if (LASTCHAR(myasl->fr_Drawer) != ':' && LASTCHAR(myasl->fr_Drawer) != '/') sprintf(save_fl,"%s/%s",myasl->fr_Drawer,myasl->fr_File);
  8891. else sprintf(save_fl,"%s%s",myasl->fr_Drawer,myasl->fr_File);
  8892.  
  8893. MUI_FreeAslRequest(myasl);
  8894.  
  8895. if (!(savefh = OpenAsync(save_fl,MODE_WRITE,AsyncBuf))) {
  8896.   HandleError(DBG_OTH_INFO,"Could not open the save file:  %s",save_fl);
  8897.   return;
  8898. }
  8899.  
  8900. for(i = 0; i < entries; i++) {
  8901.   DoMethod(app->LV_Errors,MUIM_NList_GetEntry,i,&errs);
  8902.   if (errs) {
  8903.     line[0] = '\0';
  8904.     sprintf(line,"%.8s  %s\n",ctime(&errs->Timehack)+11,errs->Error);
  8905.     WriteLineAsync(savefh,line);
  8906.   }
  8907. }
  8908.  
  8909. CloseAsync(savefh);
  8910.  
  8911. return;
  8912.  
  8913. }
  8914.  
  8915.  
  8916. void SendDelayedTCP(struct Sockets *socks)
  8917.  
  8918. {
  8919.  
  8920. int i;
  8921.  
  8922. ULONG total;
  8923.  
  8924. UWORD revlen;
  8925.  
  8926. struct ICQLog *log;
  8927.  
  8928. HandleError(DBG_TCP_DBUG,"SendDelayedTCP()");
  8929.  
  8930. get(app->LV_ICQCliLog,MUIA_NList_Entries,&total);
  8931.  
  8932. for(i = 0; i < total; i++) {
  8933.   DoMethod(app->LV_ICQCliLog,MUIM_NList_GetEntry,i,&log);
  8934.   if (log) {
  8935.     if (log->Cmd == TCP_MESSAGE && log->UIN == socks->UIN && log->Pkt) {
  8936.       HandleError(DBG_TCP_DBUG,"Sending a TCP packet...");
  8937.       revlen = BREV_W(log->Len);
  8938.       SendTCPPacket(log->UIN,log->Cmd,log->Pkt,log->Len,revlen);
  8939.       FreeVec(log->Pkt);
  8940.       log->Pkt = NULL;
  8941.       log->UIN = 0;
  8942.       log->Len = 0;
  8943.       DoMethod(app->LV_ICQCliLog,MUIM_NList_Redraw,i);
  8944.     }
  8945.   }
  8946. }
  8947.  
  8948. return;
  8949.  
  8950. }
  8951.  
  8952.  
  8953. void __asm SetUserVisPrefs(REG(a2) APTR obj)
  8954.  
  8955. {
  8956.  
  8957. BOOL *tick;
  8958.  
  8959. ULONG uin;
  8960.  
  8961. struct Contact *user;
  8962.  
  8963. get(obj,MUIA_UserData,&uin);
  8964.  
  8965. if (!(user = GetContact(uin))) return;
  8966.  
  8967. get(obj,MUIA_Selected,&tick);
  8968.  
  8969. if (obj == user->UWin->CH_SeeInvis) user->SeeInvis = BOOLP(tick);
  8970. if (obj == user->UWin->CH_BeInvis) user->BeInvis = BOOLP(tick);
  8971. if (obj == user->UWin->CH_EditEMail) user->EditEMail = BOOLP(tick);
  8972.  
  8973. user->Changed = TRUE;
  8974.  
  8975. return;
  8976.  
  8977. }
  8978.  
  8979.  
  8980. void __asm OpenEditIgnore(REG(a2) APTR obj)
  8981.  
  8982. {
  8983.  
  8984. char uin_str[32];
  8985.  
  8986. struct IgnoreUIN *ignore;
  8987.  
  8988. DoMethod(app->LV_IgnoreUIN,MUIM_NList_GetEntry,MUIV_NList_GetEntry_Active,&ignore);
  8989.  
  8990. if (!ignore) return;
  8991.  
  8992. sprintf(uin_str,"%ld",ignore->UIN);
  8993.  
  8994. set(app->TX_IgnoreUIN,MUIA_Text_Contents,uin_str);
  8995. set(app->TX_IgnoreNick,MUIA_Text_Contents,ignore->Nick);
  8996. set(app->NU_IgnoreDays,MUIA_Numeric_Value,(ignore->ExpireDays-ignore->Timehack)/86400);
  8997.  
  8998. set(app->BT_IgnoreOK,MUIA_UserData,ignore->UIN);
  8999.  
  9000. set(app->WI_EditIgnore,MUIA_Window_Open,TRUE);
  9001.  
  9002. return;
  9003.  
  9004. }
  9005.  
  9006.  
  9007. void __asm SetIgnoreEdits(REG(a2) APTR obj)
  9008.  
  9009. {
  9010.  
  9011. int i;
  9012.  
  9013. ULONG total, uin, days;
  9014.  
  9015. struct IgnoreUIN *ignore, Ignore;
  9016.  
  9017. get(obj,MUIA_UserData,&uin);
  9018.  
  9019. get(app->NU_IgnoreDays,MUIA_Numeric_Value,&days);
  9020.  
  9021. get(app->LV_IgnoreUIN,MUIA_NList_Entries,&total);
  9022.  
  9023. for(i = 0; i < total; i++) {
  9024.   DoMethod(app->LV_IgnoreUIN,MUIM_NList_GetEntry,i,&ignore);
  9025.   if (ignore) {
  9026.     if (ignore->UIN == uin) {
  9027.       if (days == -1) ignore->ExpireDays = 0;
  9028.       else ignore->ExpireDays = ignore->Timehack+(days*86400);
  9029.       DoMethod(app->LV_IgnoreUIN,MUIM_NList_Redraw,i);
  9030.       break;
  9031.     }
  9032.   }
  9033. }
  9034.  
  9035. if (i == total) {
  9036.   Ignore.UIN = uin;
  9037.   strcpy(Ignore.Nick,GetNick(uin));
  9038.   Ignore.Timehack = time(NULL);
  9039.   Ignore.ExpireDays = Ignore.Timehack+(days*86400);
  9040.   DoMethod(app->LV_IgnoreUIN,MUIM_NList_InsertSingle,&Ignore,MUIV_NList_Insert_Sorted);
  9041. }
  9042.  
  9043. set(app->WI_EditIgnore,MUIA_Window_Open,FALSE);
  9044.  
  9045. return;
  9046.  
  9047. }
  9048.  
  9049.  
  9050. void InfoView(APTR Data, UBYTE InfoType)
  9051.  
  9052. {
  9053.  
  9054. char uinstr[32], auth[5];
  9055.  
  9056. switch(InfoType) {
  9057.   case INFO_BASIC: {
  9058.     struct S_Basic_Info *Basic = Data;
  9059.     sprintf(uinstr,"%ld",Basic->UIN);
  9060.     set(app->STR_UserUIN,MUIA_Text_Contents,uinstr);
  9061.     set(app->STR_UserUIN,MUIA_UserData,Basic->UIN);
  9062.     set(app->STR_UserNick,MUIA_Textinput_Contents,Basic->Nick);
  9063.     set(app->STR_UserFirst,MUIA_Textinput_Contents,Basic->First);
  9064.     set(app->STR_UserLast,MUIA_Textinput_Contents,Basic->Last);
  9065.     set(app->STR_UserEMail,MUIA_Text_Contents,Basic->EMail);
  9066.     if (Basic->Authorize) strcpy(auth,"No");
  9067.     else strcpy(auth,"Yes");
  9068.     set(app->STR_UserAuth,MUIA_Text_Contents,auth);
  9069.     set(app->STR_UserAuth,MUIA_UserData,Basic->Authorize);
  9070.     break;
  9071.   }
  9072.   case INFO_EXTENDED: {
  9073.     char text[64];
  9074.     struct S_Ext_Info *Ext = Data;
  9075.     set(app->TX_UserCity,MUIA_Text_Contents,Ext->City);
  9076.     if (Ext->Country == 0xffff) strcpy(text,"Unspecified");
  9077.     else sprintf(text,"%s",FindCountryName(Ext->Country));
  9078.     set(app->TX_UserCountry,MUIA_Text_Contents,text);
  9079.     set(app->TX_UserCountry,MUIA_UserData,Ext->Country);
  9080.     Ext->Timezone = -(Ext->Timezone/2);
  9081.     set(app->NU_UserZone,MUIA_Numeric_Value,Ext->Timezone);
  9082.     set(app->NU_UserZone,MUIA_UserData,Ext->Timezone);
  9083.     set(app->TX_UserState,MUIA_Text_Contents,Ext->State);
  9084.     if (Ext->Age == 0xffff) strcpy(text,"Unspecified");
  9085.     else sprintf(text,"%d",Ext->Age);
  9086.     set(app->TX_UserAge,MUIA_Text_Contents,text);
  9087.     set(app->TX_UserAge,MUIA_UserData,Ext->Age);
  9088.     set(app->TX_UserSex,MUIA_Text_Contents,Sex[Ext->Sex]);
  9089.     set(app->TX_UserSex,MUIA_UserData,Ext->Sex);
  9090.     set(app->TX_UserPhone,MUIA_Text_Contents,Ext->Phone);
  9091.     set(app->TX_UserURL,MUIA_Text_Contents,Ext->URL);
  9092.     if (strlen(Ext->About)) DoMethod(app->LV_UserAbout,MUIM_NList_InsertWrap,Ext->About,-2,MUIV_NList_Insert_Bottom,WRAPCOL0,ALIGN_LEFT);
  9093.     break;
  9094.   }
  9095.   case INFO_META_HOME:
  9096.   case INFO_META_WORK:
  9097.   case INFO_META_MORE:
  9098.   case INFO_META_ABOUT:
  9099.   case INFO_META_INTERESTS:
  9100.   case INFO_META_AFFILIATIONS:
  9101.   case INFO_META_URLCATEGORY:
  9102.     break;
  9103. }
  9104.  
  9105. set(app->WI_Information,MUIA_Window_Open,TRUE);
  9106.  
  9107. return;
  9108.  
  9109. }
  9110.  
  9111.  
  9112. void InfoRefresh(APTR Data, UBYTE InfoType)
  9113.  
  9114. {
  9115.  
  9116. char tmp_nick[21];
  9117.  
  9118. struct Contact *user = NULL;
  9119.  
  9120. switch(InfoType) {
  9121.   case INFO_BASIC: {
  9122.     struct S_Basic_Info *Basic = Data;
  9123.     if (!(user = GetContact(Basic->UIN))) return;
  9124.     RefreshUInfo(&user->Nick,Basic->Nick);
  9125.     RefreshUInfo(&user->First,Basic->First);
  9126.     RefreshUInfo(&user->Last,Basic->Last);
  9127.     RefreshUInfo(&user->EMail,Basic->EMail);
  9128.     user->Authorize = Basic->Authorize;
  9129.     break;
  9130.   }
  9131.   case INFO_EXTENDED: {
  9132.     struct S_Ext_Info *Ext = Data;
  9133.     if (!(user = GetContact(Ext->UIN))) return;
  9134.     RefreshUInfo(&user->City,Ext->City);
  9135.     user->Country = Ext->Country;
  9136.     user->TimeZone = -(Ext->Timezone/2);
  9137.     RefreshUInfo(&user->State,Ext->State);
  9138.     user->Age = Ext->Age;
  9139.     user->Sex = Ext->Sex;
  9140.     RefreshUInfo(&user->Phone,Ext->Phone);
  9141.     RefreshUInfo(&user->HomePage,Ext->URL);
  9142.     RefreshUInfo(&user->About,Ext->About);
  9143.     break;
  9144.   }
  9145.   case INFO_META_HOME: {
  9146.     struct Meta_Info_Home *Home = Data;
  9147.     if (!(user = GetContact(UserInfoReqID[1]))) return;
  9148.     RefreshUInfo(&user->Nick,Home->Nick);
  9149.     RefreshUInfo(&user->First,Home->First);
  9150.     RefreshUInfo(&user->Last,Home->Last);
  9151.     RefreshUInfo(&user->EMail,Home->EMail_Primary);
  9152.     RefreshUInfo(&user->EMail_Secondary,Home->EMail_Secondary);
  9153.     RefreshUInfo(&user->EMail_Old,Home->EMail_Old);
  9154.     RefreshUInfo(&user->City,Home->City);
  9155.     RefreshUInfo(&user->State,Home->State);
  9156.     RefreshUInfo(&user->Phone,Home->Phone);
  9157.     RefreshUInfo(&user->FAX,Home->FAX);
  9158.     RefreshUInfo(&user->Street,Home->Street);
  9159.     RefreshUInfo(&user->Cellular,Home->Cellular);
  9160.     RefreshUInfo(&user->ZipCode,Home->ZipCode);
  9161.     user->Country = Home->Country;
  9162.     HandleError(DBG_UDP_DBUG,"Timezone = %d",Home->Timezone);
  9163.     user->TimeZone = -(Home->Timezone/2);
  9164.     user->Authorize = Home->Flag1;
  9165.     break;
  9166.   }
  9167.   case INFO_META_WORK: {
  9168.     struct Meta_Info_Work *Work = Data;
  9169.     if (!(user = GetContact(UserInfoReqID[1]))) return;
  9170.     RefreshUInfo(&user->Work_City,Work->City);
  9171.     RefreshUInfo(&user->Work_State,Work->State);
  9172.     RefreshUInfo(&user->Work_Phone,Work->Phone);
  9173.     RefreshUInfo(&user->Work_FAX,Work->FAX);
  9174.     RefreshUInfo(&user->Work_Address,Work->Address);
  9175.     RefreshUInfo(&user->Work_ZipCode,Work->ZipCode);
  9176.     user->Work_Country = Work->Country;
  9177.     RefreshUInfo(&user->Work_Company,Work->Company);
  9178.     RefreshUInfo(&user->Work_Department,Work->Department);
  9179.     RefreshUInfo(&user->Work_Position,Work->Position);
  9180.     user->Work_Occupation = Work->Occupation;
  9181.     RefreshUInfo(&user->Work_URL,Work->URL);
  9182.     break;
  9183.   }
  9184.   case INFO_META_MORE: {
  9185.     struct Meta_Info_More *More = Data;
  9186.     if (!(user = GetContact(UserInfoReqID[1]))) return;
  9187.     user->Age = More->Age;
  9188.     user->Sex = More->Sex;
  9189.     RefreshUInfo(&user->HomePage,More->URL);
  9190.     HandleError(DBG_UDP_DBUG,"BD_Year = %d",More->BDay_Year);
  9191.     HandleError(DBG_UDP_DBUG,"BD_Month = %d",More->BDay_Month);
  9192.     HandleError(DBG_UDP_DBUG,"BD_Day = %d",More->BDay_Day);
  9193.     user->BDay_Year = More->BDay_Year;
  9194.     user->BDay_Month = More->BDay_Month;
  9195.     user->BDay_Day = More->BDay_Day;
  9196.     if (More->Language1 == 0xFF) user->Language1 = 0x00;
  9197.     else user->Language1 = More->Language1;
  9198.     if (More->Language2 == 0xFF) user->Language2 = 0x00;
  9199.     else user->Language2 = More->Language2;
  9200.     if (More->Language3 == 0xFF) user->Language3 = 0x00;
  9201.     else user->Language3 = More->Language3;
  9202.     break;
  9203.   }
  9204.   case INFO_META_ABOUT: {
  9205.     struct Meta_Info_About *About = Data;
  9206.     if (!(user = GetContact(UserInfoReqID[1]))) return;
  9207.     RefreshUInfo(&user->About,About->About);
  9208.     break;
  9209.   }
  9210.   case INFO_META_INTERESTS:
  9211.   case INFO_META_AFFILIATIONS:
  9212.   case INFO_META_URLCATEGORY:
  9213.     break;
  9214. }
  9215.  
  9216. if (user) {
  9217.   if (!user->Nick) {
  9218.     sprintf(tmp_nick,"%ld",user->UIN);
  9219.     RefreshUInfo(&user->Nick,tmp_nick);
  9220.   }
  9221.   if (user->Status == STATUS_NEWUIN) {
  9222.     UWORD len;
  9223.     struct C_ContactList CList;
  9224.     user->Status = STATUS_OFFLINE;
  9225.     Header.Command = C_CONTACT_LIST;
  9226.     CList.UIN_Count = 1;
  9227.     CList.UIN[0] = user->UIN;
  9228.     len = UDP_CreatePacket(&Header,&CList,UDP_Buf);
  9229.     send_udp_pkt(UDP_Buf,len,Header.UIN);
  9230.     Add2Log(LOG_CLIENT,&Header,FALSE,len,UDP_Buf);
  9231.     sprintf(maintitle,"STRICQ (%d)",++contacts_cnt);
  9232.     set(app->WI_Main,MUIA_Window_Title,maintitle);
  9233.     DoMethod(app->LV_OfflineList,MUIM_NList_Sort);
  9234.   }
  9235. }
  9236.  
  9237. UpdateUserWin(user);
  9238.  
  9239. return;
  9240.  
  9241. }
  9242.  
  9243.  
  9244. BOOL RefreshUInfo(char **old, char *new)
  9245.  
  9246. {
  9247.  
  9248. char *tmp;
  9249.  
  9250. if (!new) {
  9251.   if (*old) FreeVec(*old);
  9252.   *old = NULL;
  9253.   return(TRUE);
  9254. }
  9255.  
  9256. if (*old) {
  9257.   if (!strcmp(*old,new)) return(TRUE);
  9258.   HandleError(DBG_UDP_DBUG,"RefreshUInfo() - old = %p, *old = %s, new = %s",old,*old,new);
  9259. }
  9260.  
  9261. if (strlen(new)) {
  9262.   tmp = *old;
  9263.   if (!(*old = AllocVec(strlen(new)+1,MEMF_CLEAR))) {
  9264.     HandleError(DBG_OTH_INFO,"RefreshUInfo() - Could not allocate %d bytes.",strlen(new)+1);
  9265.     *old = tmp;
  9266.     return(FALSE);
  9267.   }
  9268.   else if (tmp) FreeVec(tmp);
  9269.   strcpy(*old,new);
  9270. }
  9271. else {
  9272.   if (*old) FreeVec(*old);
  9273.   *old = NULL;
  9274. }
  9275.  
  9276. return(TRUE);
  9277.  
  9278. }
  9279.  
  9280.  
  9281. void InfoGrabMe(APTR Data, UBYTE InfoType)
  9282.  
  9283. {
  9284.  
  9285. char text[64];
  9286.  
  9287. switch(InfoType) {
  9288.   case INFO_BASIC: {
  9289.     struct S_Basic_Info *Basic = Data;
  9290.     set(app->STR_Nick,MUIA_String_Contents,Basic->Nick);
  9291.     set(app->STR_First,MUIA_String_Contents,Basic->First);
  9292.     set(app->STR_Last,MUIA_String_Contents,Basic->Last);
  9293.     set(app->STR_EMail,MUIA_String_Contents,Basic->EMail);
  9294.     Basic->Authorize = -Basic->Authorize + 1;
  9295.     set(app->RD_ReqAuth,MUIA_Radio_Active,Basic->Authorize);
  9296.     break;
  9297.   }
  9298.   case INFO_EXTENDED: {
  9299.     struct S_Ext_Info *Ext = Data;
  9300.     set(app->STR_City,MUIA_String_Contents,Ext->City);
  9301.     sprintf(text,"%d %s",Ext->Country,FindCountryName(Ext->Country));
  9302.     set(app->STR_Country,MUIA_String_Contents,text);
  9303.     set(app->STR_Country,MUIA_UserData,Ext->Country);
  9304.     Ext->Timezone = -(Ext->Timezone / 2);
  9305.     set(app->NU_TimeZone,MUIA_Numeric_Value,Ext->Timezone);
  9306.     set(app->STR_State,MUIA_String_Contents,Ext->State);
  9307.     set(app->STR_Age,MUIA_String_Integer,Ext->Age);
  9308.     set(app->CY_Sex,MUIA_Cycle_Active,Ext->Sex);
  9309.     set(app->STR_Phone,MUIA_String_Contents,Ext->Phone);
  9310.     set(app->STR_Page,MUIA_String_Contents,Ext->URL);
  9311.     set(app->TI_About,MUIA_Textinput_Contents,Ext->About);
  9312.     break;
  9313.   }
  9314.   case INFO_META_HOME: {
  9315.     struct Meta_Info_Home *Home = Data;
  9316.     set(app->STR_Nick,MUIA_String_Contents,Home->Nick);
  9317.     set(app->STR_First,MUIA_String_Contents,Home->First);
  9318.     set(app->STR_Last,MUIA_String_Contents,Home->Last);
  9319.     set(app->STR_EMail,MUIA_String_Contents,Home->EMail_Primary);
  9320.     set(app->STR_EMail2,MUIA_String_Contents,Home->EMail_Secondary);
  9321.     set(app->STR_EMailOld,MUIA_String_Contents,Home->EMail_Old);
  9322.     set(app->STR_City,MUIA_String_Contents,Home->City);
  9323.     set(app->STR_State,MUIA_String_Contents,Home->State);
  9324.     set(app->STR_Phone,MUIA_String_Contents,Home->Phone);
  9325.     set(app->STR_FAX,MUIA_String_Contents,Home->FAX);
  9326.     set(app->TI_StreetAd,MUIA_Textinput_Contents,Home->Street);
  9327.     set(app->STR_Cellular,MUIA_String_Contents,Home->Cellular);
  9328.     set(app->STR_ZipCode,MUIA_String_Contents,Home->ZipCode);
  9329.     sprintf(text,"%d %s",Home->Country,FindCountryName(Home->Country));
  9330.     set(app->STR_Country,MUIA_String_Contents,text);
  9331.     set(app->STR_Country,MUIA_UserData,Home->Country);
  9332.     Home->Timezone = -(Home->Timezone / 2);
  9333.     set(app->NU_TimeZone,MUIA_Numeric_Value,Home->Timezone);
  9334.     Home->Flag1 = -Home->Flag1 + 1;
  9335.     set(app->RD_ReqAuth,MUIA_Radio_Active,Home->Flag1);
  9336.     break;
  9337.   }
  9338.   case INFO_META_WORK: {
  9339.     struct Meta_Info_Work *Work = Data;
  9340.     set(app->STR_WkCity,MUIA_String_Contents,Work->City);
  9341.     set(app->STR_WkState,MUIA_String_Contents,Work->State);
  9342.     set(app->STR_WkPhone,MUIA_String_Contents,Work->Phone);
  9343.     set(app->STR_WkFAX,MUIA_String_Contents,Work->FAX);
  9344.     set(app->TI_WorkAd,MUIA_Textinput_Contents,Work->Address);
  9345.     set(app->STR_WkZipCode,MUIA_String_Contents,Work->ZipCode);
  9346.     sprintf(text,"%d %s",Work->Country,FindCountryName(Work->Country));
  9347.     set(app->STR_WkCountry,MUIA_String_Contents,text);
  9348.     set(app->STR_WkCountry,MUIA_UserData,Work->Country);
  9349.     set(app->STR_CoName,MUIA_String_Contents,Work->Company);
  9350.     set(app->STR_DivDept,MUIA_String_Contents,Work->Department);
  9351.     set(app->STR_Position,MUIA_String_Contents,Work->Position);
  9352.     set(app->CY_Occupation,MUIA_Cycle_Active,Work->Occupation);
  9353.     set(app->STR_WkURL,MUIA_String_Contents,Work->URL);
  9354.     break;
  9355.   }
  9356.   case INFO_META_MORE: {
  9357.     struct Meta_Info_More *More = Data;
  9358.     set(app->STR_Age,MUIA_String_Integer,More->Age);
  9359.     set(app->CY_Sex,MUIA_Cycle_Active,More->Sex);
  9360.     set(app->STR_Page,MUIA_String_Contents,More->URL);
  9361.     set(app->NU_BDYear,MUIA_Numeric_Value,More->BDay_Year);
  9362.     set(app->CY_BDMonth,MUIA_Cycle_Active,More->BDay_Month-1);
  9363.     set(app->STR_BDDay,MUIA_String_Integer,More->BDay_Day);
  9364.     if (More->Language1 == 0xFF) More->Language1 = 0x00;
  9365.     set(app->CY_Lang1,MUIA_Cycle_Active,More->Language1);
  9366.     if (More->Language2 == 0xFF) More->Language2 = 0x00;
  9367.     set(app->CY_Lang2,MUIA_Cycle_Active,More->Language2);
  9368.     if (More->Language3 == 0xFF) More->Language3 = 0x00;
  9369.     set(app->CY_Lang3,MUIA_Cycle_Active,More->Language3);
  9370.     break;
  9371.   }
  9372.   case INFO_META_ABOUT: {
  9373.     struct Meta_Info_About *About = Data;
  9374.     set(app->TI_About,MUIA_Textinput_Contents,About->About);
  9375.     break;
  9376.   }
  9377.   case INFO_META_INTERESTS:
  9378.   case INFO_META_AFFILIATIONS:
  9379.   case INFO_META_URLCATEGORY:
  9380.     break;
  9381. }
  9382.  
  9383. return;
  9384.  
  9385. }
  9386.  
  9387.  
  9388. void ChangeZodiacPic(struct Contact *user, BOOL ForOwner)
  9389.  
  9390. {
  9391.  
  9392. static char *Zodiacs[] = {"", "Capricorn", "Aquarius", "Pisces", "Aries", "Tarus", "Gemini",
  9393.                           "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarus", NULL};
  9394.  
  9395. APTR NewImgObj, GPObj, DTObj;
  9396.  
  9397. char zodiac_fl[MAXNAMLEN];
  9398.  
  9399. int index;
  9400.  
  9401. ULONG month, day;
  9402.  
  9403. if (ForOwner) {
  9404.   get(app->CY_BDMonth,MUIA_Cycle_Active,&month);
  9405.   get(app->STR_BDDay,MUIA_String_Integer,&day);
  9406.   GPObj = app->GP_DTGroup;
  9407.   DTObj = app->DT_Zodiac;
  9408. }
  9409. else {
  9410.   if (!user) return;
  9411.   if (!user->UWin) return;
  9412.   month = user->BDay_Month;
  9413.   day = user->BDay_Day;
  9414.   GPObj = user->UWin->GP_DTGroup;
  9415.   DTObj = user->UWin->DT_Zodiac;
  9416. }
  9417.  
  9418. switch(month) {
  9419.   case 0:
  9420.     index = 0;
  9421.     break;
  9422.   case 1:
  9423.     index = 1;
  9424.     if (day > 20) index = 2;
  9425.     break;
  9426.   case 2:
  9427.     index = 2;
  9428.     if (day > 18) index = 3;
  9429.     break;
  9430.   case 3:
  9431.     index = 3;
  9432.     if (day > 20) index = 4;
  9433.     break;
  9434.   case 4:
  9435.     index = 4;
  9436.     if (day > 20) index = 5;
  9437.     break;
  9438.   case 5:
  9439.     index = 5;
  9440.     if (day > 21) index = 6;
  9441.     break;
  9442.   case 6:
  9443.     index = 6;
  9444.     if (day > 21) index = 7;
  9445.     break;
  9446.   case 7:
  9447.     index = 7;
  9448.     if (day > 22) index = 8;
  9449.     break;
  9450.   case 8:
  9451.     index = 8;
  9452.     if (day > 23) index = 9;
  9453.     break;
  9454.   case 9:
  9455.     index = 9;
  9456.     if (day > 23) index = 10;
  9457.     break;
  9458.   case 10:
  9459.     index = 10;
  9460.     if (day > 23) index = 11;
  9461.     break;
  9462.   case 11:
  9463.     index = 11;
  9464.     if (day > 22) index = 12;
  9465.     break;
  9466.   case 12:
  9467.     index = 12;
  9468.     if (day > 21) index = 1;
  9469.     break;
  9470. }
  9471.  
  9472. sprintf(zodiac_fl,"%sImages/%s",currentdir,Zodiacs[index]);
  9473.  
  9474. if (!(NewImgObj = DatatypeObject, MUIA_Dtpic_Name, zodiac_fl, End)) {
  9475.   HandleError(DBG_OTH_INFO,"Error creating a new Zodiac Image");
  9476.   return;
  9477. }
  9478.  
  9479. DoMethod(GPObj,MUIM_Group_InitChange);
  9480.  
  9481. if (DTObj) {
  9482.   DoMethod(GPObj,OM_REMMEMBER,DTObj);
  9483.   MUI_DisposeObject(DTObj);
  9484. }
  9485.  
  9486. DTObj = NewImgObj;
  9487.  
  9488. DoMethod(GPObj,OM_ADDMEMBER,DTObj);
  9489.  
  9490. DoMethod(GPObj,MUIM_Group_ExitChange);
  9491.  
  9492. if (ForOwner) app->DT_Zodiac = DTObj;
  9493. else user->UWin->DT_Zodiac = DTObj;
  9494.  
  9495. return;
  9496.  
  9497. }
  9498.  
  9499.  
  9500. void __asm ChangeZodiac(REG(a2) APTR obj)
  9501.  
  9502. {
  9503.  
  9504. if (obj == app->CY_BDMonth) ChangeZodiacPic(NULL,TRUE);
  9505.  
  9506. return;
  9507.  
  9508. }
  9509.  
  9510.  
  9511. void __asm ResetSockets(REG(a2) APTR obj)
  9512.  
  9513. {
  9514.  
  9515. int i;
  9516.  
  9517. ULONG total;
  9518.  
  9519. struct Sockets *socks;
  9520.  
  9521. //HandleError(DBG_TCP_DBUG,"ResetSockets()");
  9522.  
  9523. if (Online) return;
  9524.  
  9525. get(app->LV_SockList,MUIA_NList_Entries,&total);
  9526.  
  9527. if (total) {
  9528.   for(i = total-1; i>-1; i--) {
  9529.     DoMethod(app->LV_SockList,MUIM_NList_GetEntry,i,&socks);
  9530.     if (socks) DelSockets(socks->Socket);
  9531.   }
  9532. }
  9533.  
  9534. CloseLibrary(SocketBase);
  9535.  
  9536. if (!(SocketBase = OpenLibrary("bsdsocket.library",3))) fail(NULL,"bsdsocket.library is no longer present!");
  9537. else HandleError(DBG_TCP_DBUG,"ResetSockets() - Success!");
  9538.  
  9539. return;
  9540.  
  9541. }
  9542.