1 /*
2  * Handles incoming and creates outgoing SNAC packets
3  * for the family 4 (icbm) commands.
4  *
5  * climm Copyright (C) © 2001-2007 Rüdiger Kuhlmann
6  *
7  * climm is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; version 2 dated June, 1991.
10  *
11  * climm is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14  * License for more details.
15  *
16  * In addition, as a special exception permission is granted to link the
17  * code of this release of climm with the OpenSSL project's "OpenSSL"
18  * library, and distribute the linked executables.  You must obey the GNU
19  * General Public License in all respects for all of the code used other
20  * than "OpenSSL".  If you modify this file, you may extend this exception
21  * to your version of the file, but you are not obligated to do so.  If you
22  * do not wish to do so, delete this exception statement from your version
23  * of this file.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this package; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28  * 02111-1307, USA.
29  *
30  * $Id: oscar_icbm.c 2788 2009-04-11 22:05:30Z kuhlmann $
31  */
32 
33 #include "climm.h"
34 #include <assert.h>
35 #include "oscar_base.h"
36 #include "oscar_tlv.h"
37 #include "oscar_snac.h"
38 #include "oscar_icbm.h"
39 #include "oscar_oldicq.h"
40 #include "packet.h"
41 #include "contact.h"
42 #include "connection.h"
43 #include "conv.h"
44 #include "im_request.h"
45 #include "im_response.h"
46 #include "buildmark.h"
47 #include "oscar_dc.h"
48 #include "oscar_dc_file.h"
49 #include "util_ui.h"
50 #include "preferences.h"
51 
52 static void SnacCallbackType2Ack (Event *event);
53 static void SnacCallbackType2 (Event *event);
54 static void SnacCallbackType2Cancel (Event *event);
55 static void SnacCallbackIgnore (Event *event);
56 
57 #define PEEK_REFID 0x3d1db11f
58 
59 /*
60  * SRV_ICBMERR - SNAC(4,1)
61  */
JUMP_SNAC_F(SnacSrvIcbmerr)62 JUMP_SNAC_F(SnacSrvIcbmerr)
63 {
64     Connection *serv = event->conn;
65     UWORD err = PacketReadB2 (event->pak);
66 
67     if ((event->pak->ref == PEEK_REFID) && (err == 0xe || err == 4 || err == 9))
68     {
69         if (err == 0xe || err == 9)
70             rl_print (i18n (2017, "The user is online, but possibly invisible.\n"));
71         else
72             rl_print (i18n (2564, "The user couldn't be detected to be online.\n"));
73         return;
74     }
75 
76     event = QueueDequeue (serv, QUEUE_TYPE2_RESEND_ACK, event->pak->ref);
77     if (event && event->callback)
78         event->callback (event);
79     else if (err == 4)
80         rl_print (i18n (2022, "The user is offline.\n"));
81     else if (err != 0xd)
82         rl_printf (i18n (2191, "Instant message error: %d.\n"), err);
83 }
84 
85 /*
86  * CLI_SETICBM - SNAC(4,2)
87  */
SnacCliSeticbm(Server * serv)88 void SnacCliSeticbm (Server *serv)
89 {
90    Packet *pak;
91 
92    pak = SnacC (serv, 4, 2, 0, 0);
93    PacketWriteB2 (pak, 0);
94    PacketWriteB2 (pak, 0);
95    PacketWriteB2 (pak, 3);
96    PacketWriteB2 (pak, 8000);
97    PacketWriteB2 (pak, 999);
98    PacketWriteB2 (pak, 999);
99    PacketWriteB2 (pak, 0);
100    PacketWriteB2 (pak, 0);
101    SnacSend (serv, pak);
102 }
103 
104 /*
105  * CLI_REQICBM - SNAC(4,4)
106  */
107 
108 /* implemented as macro */
109 
110 /*
111  * SRV_REPLYICBM - SNAC(4,5)
112  */
JUMP_SNAC_F(SnacSrvReplyicbm)113 JUMP_SNAC_F(SnacSrvReplyicbm)
114 {
115     SnacCliSeticbm (event->conn->serv);
116 }
117 
JUMP_SNAC_F(SnacSrvAckmsg)118 JUMP_SNAC_F(SnacSrvAckmsg)
119 {
120     Server *serv = event->conn->serv;
121     /* UDWORD midtime, midrand; */
122     UWORD msgtype, seq_dc;
123     Contact *cont;
124     Packet *pak;
125     strc_t ctext;
126     char *text;
127 
128     pak = event->pak;
129     /*midtime*/PacketReadB4 (pak);
130     /*midrand*/PacketReadB4 (pak);
131               PacketReadB2 (pak);
132     cont =    PacketReadCont (pak, serv);
133               PacketReadB2 (pak);
134               PacketReadData (pak, NULL, PacketRead2 (pak));
135               PacketRead2 (pak);
136     seq_dc  = PacketRead2 (pak);
137               PacketRead4 (pak);
138               PacketRead4 (pak);
139               PacketRead4 (pak);
140     msgtype = PacketRead2 (pak);
141               PacketRead2 (pak);
142               PacketRead2 (pak);
143     ctext   = PacketReadL2Str (pak, NULL);
144 
145     if (!cont)
146         return;
147 
148     text = strdup (c_in_to_split (ctext, cont));
149     if (msgtype == MSG_NORM)
150     {
151         strc_t cctmp;
152         PacketRead4 (pak);
153         PacketRead4 (pak);
154         cctmp = PacketReadL2Str (pak, NULL);
155         if (!strcmp (cctmp->txt, CAP_GID_UTF8))
156         {
157             free (text);
158             text = strdup (ctext->txt);
159         }
160     }
161 
162     event = QueueDequeue (serv->conn, QUEUE_TYPE2_RESEND, seq_dc);
163     if (!event)
164         event = QueueDequeue2 (serv->conn, QUEUE_TYPE2_RESEND, 0, cont);
165 
166     if ((msgtype & 0x300) == 0x300)
167         IMSrvMsg (cont, NOW, CV_ORIGIN_v8, msgtype, text);
168     if (event)
169     {
170         Message *msg = event->data;
171         assert (msg);
172         assert (msg->cont == cont);
173         if ((msg->plain_message || msg->send_message) && !msg->otrinjected && (msgtype & 0x300) != 0x300)
174         {
175             msg->type = INT_MSGACK_TYPE2;
176             IMIntMsgMsg (msg, NOW, ims_offline);
177             if ((~cont->oldflags & CONT_SEENAUTO) && strlen (text) && msg->send_message && strcmp (text, msg->send_message))
178             {
179                 IMSrvMsg (cont, NOW, CV_ORIGIN_v8, MSG_AUTO, text);
180                 cont->oldflags |= CONT_SEENAUTO;
181             }
182         }
183         MsgD (msg);
184         event->data = NULL;
185         EventD (event);
186     }
187     free (text);
188 }
189 
SnacCallbackIgnore(Event * event)190 void SnacCallbackIgnore (Event *event)
191 {
192     EventD (event);
193 }
194 
195 /*
196  * CLI_SENDMSG - SNAC(4,6)
197  */
SnacCliSendmsg1(Server * serv,Message * msg)198 static UBYTE SnacCliSendmsg1 (Server *serv, Message *msg)
199 {
200     Packet *pak;
201     Event *event;
202     Contact *cont;
203     UDWORD mtime = rand() % 0xffff, mid = rand() % 0xffff;
204     int remenc;
205     strc_t str;
206     int enc = ENC_LATIN1, icqenc = 0, icqcol;
207 
208     assert (serv);
209     assert (msg);
210     cont = msg->cont;
211     assert (cont);
212 
213     remenc = ContactPrefVal (cont, CO_ENCODING);
214 
215     if (cont->status != ims_offline &&
216         HAS_CAP (cont->caps, CAP_UTF8) &&
217         !ConvFits (msg->send_message, ENC_ASCII) &&
218         !(cont->dc && cont->dc->id1 == (time_t)0xffffff42 &&
219           (cont->dc->id2 & 0x7fffffff) < (time_t)0x00040c00)) /* exclude old mICQ */
220     {
221         enc = ENC_UCS2BE;
222         icqenc = 2;
223     }
224     else
225     {
226         /* too bad, there's nothing we can do */
227         enc = remenc;
228         icqenc = 3;
229     }
230     if (msg->type != 1)
231     {
232         icqenc = msg->type;
233         enc = ENC_LATIN9;
234     }
235 
236     icqcol = atoi (msg->send_message); /* FIXME FIXME WIXME */
237     str = ConvTo (msg->send_message, enc);
238     if (str->len > 700)
239     {
240         msg->maxsize = 700; /* FIXME: not 450? What is the real max? */
241         msg->maxenc = enc;
242         return RET_DEFER;
243     }
244 
245     pak = SnacC (serv, 4, 6, 0, 0);
246     PacketWriteB4 (pak, mtime);
247     PacketWriteB4 (pak, mid);
248     PacketWriteB2 (pak, 1 /* format */);
249     PacketWriteCont (pak, cont);
250 
251     PacketWriteTLV     (pak, 2);
252     PacketWriteTLV     (pak, 1281);
253     if (icqenc == 2)
254         PacketWriteB2  (pak, 0x0106);
255     else
256         PacketWrite1   (pak, 0x01);
257     PacketWriteTLVDone (pak);
258     PacketWriteTLV     (pak, 257);
259     PacketWriteB2      (pak, icqenc);
260     PacketWriteB2      (pak, icqcol);
261     PacketWriteData    (pak, str->txt, str->len);
262     PacketWriteTLVDone (pak);
263     PacketWriteTLVDone (pak);
264     PacketWriteB2 (pak, 3);
265     PacketWriteB2 (pak, 0);
266     PacketWriteB2 (pak, 6);
267     PacketWriteB2 (pak, 0);
268 
269     event = QueueEnqueueData2 (serv->conn, QUEUE_TYPE1_RESEND_ACK, pak->ref, 120, msg, &SnacCallbackIgnore, NULL);
270     event->cont = cont;
271 
272     SnacSend (serv, pak);
273 
274     return RET_OK;
275 }
276 
SnacCliSendmsg4(Server * serv,Message * msg)277 static UBYTE SnacCliSendmsg4 (Server *serv, Message *msg)
278 {
279     Packet *pak;
280     Event *event;
281     const char *text;
282     Contact *cont;
283     UDWORD mtime = rand() % 0xffff, mid = rand() % 0xffff;
284 
285     assert (serv);
286     assert (msg);
287     cont = msg->cont;
288     assert (cont);
289 
290     text = c_out_to_split (msg->send_message, cont);
291     if (strlen (text) > 3 * 1024)
292     {
293         msg->maxsize = 3 * 1024;
294         msg->maxenc = ContactPrefVal (cont, CO_ENCODING);
295         return RET_DEFER;
296     }
297 
298     pak = SnacC (serv, 4, 6, 0, 0);
299     PacketWriteB4 (pak, mtime);
300     PacketWriteB4 (pak, mid);
301     PacketWriteB2 (pak, 4 /* format */);
302     PacketWriteCont (pak, cont);
303 
304     PacketWriteTLV     (pak, 5);
305     PacketWrite4       (pak, serv->oscar_uin);
306     PacketWrite1       (pak, msg->type % 256);
307     PacketWrite1       (pak, msg->type / 256);
308     PacketWriteLNTS    (pak, text);
309     PacketWriteTLVDone (pak);
310     PacketWriteB2 (pak, 6);
311     PacketWriteB2 (pak, 0);
312 
313     event = QueueEnqueueData2 (serv->conn, QUEUE_TYPE4_RESEND_ACK, pak->ref, 120, msg, &SnacCallbackIgnore, NULL);
314     event->cont = cont;
315 
316     SnacSend (serv, pak);
317 
318     return RET_OK;
319 }
320 
SnacCallbackType2Cancel2(Event * event)321 static void SnacCallbackType2Cancel2 (Event *event)
322 {
323     assert (event);
324     assert (event->conn);
325     assert (!event->data);
326     EventD (event);
327 }
328 
SnacCallbackType2Ack(Event * event)329 static void SnacCallbackType2Ack (Event *event)
330 {
331     Connection *conn = event->conn;
332     Contact *cont = event->cont;
333     Event *aevent;
334     UDWORD opt_ref;
335     Message *msg;
336 
337     if (!OptGetVal (event->opt, CO_REF, &opt_ref))
338     {
339         EventD (event);
340         return;
341     }
342     aevent = QueueDequeue (conn, QUEUE_TYPE2_RESEND, opt_ref);
343     assert (aevent);
344     assert (cont);
345     ASSERT_SERVER_CONN (conn);
346 
347     msg = aevent->data;
348     assert (msg);
349     assert (msg->cont == cont);
350     aevent->data = NULL;
351     EventD (aevent);
352     EventD (event);
353     IMCliReMsg (cont, msg);
354 }
355 
SnacCallbackType2Cancel(Event * event)356 static void SnacCallbackType2Cancel (Event *event)
357 {
358     Message *msg = event->data;
359     if (msg->send_message && !msg->otrinjected)
360         rl_printf (i18n (2234, "Message %s discarded - lost session.\n"),
361             msg->plain_message ? msg->plain_message : msg->send_message);
362     MsgD (event->data);
363     event->data = NULL;
364     EventD (event);
365 }
366 
SnacCallbackType2(Event * event)367 static void SnacCallbackType2 (Event *event)
368 {
369     Server *serv = event->conn->serv;
370     Contact *cont = event->cont;
371     Packet *pak = event->pak;
372     Message *msg = event->data;
373     Event *event2;
374 
375     ASSERT_SERVER (serv);
376     assert (pak);
377     assert (event->cont);
378     assert (event->data);
379     assert (!event->opt);
380 
381     if (event->attempts < MAX_RETRY_TYPE2_ATTEMPTS && serv->conn->connect & CONNECT_MASK)
382     {
383         if (serv->conn->connect & CONNECT_OK)
384         {
385             if (event->attempts > 1)
386                 IMIntMsg (cont, NOW, ims_offline, INT_MSGTRY_TYPE2, msg->plain_message ? msg->plain_message : msg->send_message);
387             SnacSend (serv, PacketClone (pak));
388             event->attempts++;
389             /* allow more time for the peer's ack than the server's ack */
390             event->due = time (NULL) + RETRY_DELAY_TYPE2 + 5;
391 
392             event2 = QueueEnqueueData2 (serv->conn, QUEUE_TYPE2_RESEND_ACK, pak->ref, RETRY_DELAY_TYPE2, NULL, &SnacCallbackType2Ack, &SnacCallbackType2Cancel2);
393             event2->cont = cont;
394             event2->opt = OptSetVals (NULL, CO_REF, event->seq, 0);
395         }
396         else
397             event->due = time (NULL) + 1;
398         QueueEnqueue (event);
399         return;
400     }
401 
402     event->data = NULL;
403     IMCliReMsg (cont, msg);
404     EventD (event);
405 }
406 
SnacCliSendIP(Server * serv,Contact * cont)407 void SnacCliSendIP (Server *serv, Contact *cont)
408 {
409     Packet *pak;
410     UDWORD mtime = rand() % 0xffff, mid = rand() % 0xffff;
411 
412     assert (serv);
413     assert (cont);
414 
415     serv->oscar_type2_seq--;
416 
417     pak = SnacC (serv, 4, 6, 0, 0);
418     PacketWriteB4        (pak, mtime);
419     PacketWriteB4        (pak, mid);
420     PacketWriteB2        (pak, 2);
421     PacketWriteCont      (pak, cont);
422     PacketWriteTLV       (pak, 5);
423       PacketWrite2       (pak, 0);
424       PacketWriteB4      (pak, mtime);
425       PacketWriteB4      (pak, mid);
426       PacketWriteCapID   (pak, CAP_REVCONNREQ);
427       PacketWriteTLV2    (pak, 10, 1);
428       PacketWriteB4      (pak, 0x000f0000); /* empty TLV(15) */
429       PacketWriteTLV     (pak, 10001);
430         PacketWrite4     (pak, serv->conn->cont->uin);
431         PacketWriteB4    (pak, serv->conn->our_local_ip);
432         PacketWrite4     (pak, serv->oscar_dc->port);
433         PacketWrite1     (pak, 4);
434         PacketWrite4     (pak, serv->conn->our_outside_ip);
435         PacketWrite4     (pak, serv->oscar_dc->port);
436         PacketWrite2     (pak, serv->oscar_dc->version);
437         PacketWrite4     (pak, 0x0000002f);
438       PacketWriteTLVDone (pak);
439     PacketWriteTLVDone   (pak);
440     PacketWriteTLV       (pak, 19);
441       PacketWrite1       (pak, 1);
442     PacketWriteTLVDone   (pak);
443     SnacSend (serv, pak);
444 }
445 
SnacCliSendmsg2(Server * serv,Message * msg)446 static UBYTE SnacCliSendmsg2 (Server *serv, Message *msg)
447 {
448     Packet *pak;
449     UDWORD mtime = rand() % 0xffff, mid = rand() % 0xffff;
450     BOOL peek = 0;
451     Contact *cont;
452     const char *text;
453 
454     assert (serv);
455     assert (msg);
456     cont = msg->cont;
457     assert (cont);
458 
459     if (msg->type == MSG_GET_PEEK)
460     {
461         peek = 1;
462         msg->type = MSG_GET_AWAY | MSGF_GETAUTO;
463     }
464 
465     text = c_out_for (msg->send_message, cont, msg->type);
466     if (strlen (text) > 3 * 1024)
467     {
468         msg->maxsize = 3 * 1024;
469         msg->maxenc = CONT_UTF8 (cont, msg->type) ? ENC_UTF8 : ContactPrefVal (cont, CO_ENCODING);
470         return RET_DEFER;
471     }
472 
473     serv->oscar_type2_seq--;
474     msg->trans &= ~CV_MSGTRANS_TYPE2;
475 
476     pak = SnacC (serv, 4, 6, 0, peek ? PEEK_REFID : 0);
477     PacketWriteB4 (pak, mtime);
478     PacketWriteB4 (pak, mid);
479     PacketWriteB2 (pak, 2);
480     PacketWriteCont (pak, cont);
481 
482     PacketWriteTLV     (pak, 5);
483      PacketWrite2       (pak, 0);
484      PacketWriteB4      (pak, mtime);
485      PacketWriteB4      (pak, mid);
486 
487      PacketWriteCapID   (pak, peek ? CAP_NONE : CAP_SRVRELAY);
488      PacketWriteTLV2    (pak, 10, 1);
489      PacketWriteB4      (pak, 0x000f0000); /* empty TLV(15) */
490      if (!peek) {
491      PacketWriteTLV     (pak, 10001);
492       PacketWriteLen     (pak);
493        PacketWrite2       (pak, serv->oscar_dc && serv->oscar_dc->connect & CONNECT_OK
494                               ? serv->oscar_dc->version : 8);
495        PacketWriteCapID   (pak, CAP_NONE);
496        PacketWrite2       (pak, 0);
497        PacketWrite4       (pak, 3);
498        PacketWrite1       (pak, 0);
499        PacketWrite2       (pak, peek ? 0 : serv->oscar_type2_seq);
500       PacketWriteLenDone (pak);
501       if (peek)
502       {
503           PacketWriteLen    (pak);
504            PacketWrite2      (pak, serv->oscar_type2_seq);       /* sequence number */
505            PacketWrite4      (pak, 0);
506            PacketWrite4      (pak, 0);
507            PacketWrite4      (pak, 0);
508           PacketWriteLenDone (pak);
509           PacketWrite2      (pak, MSG_GET_DND | MSGF_GETAUTO);    /* message type    */
510           PacketWrite2      (pak, 0);     /* status          */
511           PacketWrite2      (pak, 0);      /* flags           */
512           PacketWrite2      (pak, 0x7fff);
513           PacketWrite1      (pak, 0);
514       }
515       else
516       {
517           SrvMsgAdvanced     (pak, serv->oscar_type2_seq, msg->type, serv->status, cont->status, -1, text);
518           PacketWrite4       (pak, TCP_COL_FG);
519           PacketWrite4       (pak, TCP_COL_BG);
520           if (CONT_UTF8 (cont, msg->type))
521               PacketWriteDLStr     (pak, CAP_GID_UTF8);
522       }
523      PacketWriteTLVDone (pak);
524      }
525     PacketWriteTLVDone (pak);
526 
527     if (peek)
528     {
529         PacketWriteB4  (pak, 0x00060000);
530         SnacSend (serv, pak);
531         MsgD (msg);
532     }
533     else
534     {
535         Event *event;
536 
537         PacketWriteB4      (pak, 0x00030000); /* empty TLV(3) */
538         event = QueueEnqueueData2 (serv->conn, QUEUE_TYPE2_RESEND, serv->oscar_type2_seq, 0, msg, &SnacCallbackType2, &SnacCallbackType2Cancel);
539         event->cont = cont;
540         event->pak = pak;
541     }
542     return RET_INPR;
543 }
544 
545 
546 /*
547  * CLI_SENDMSG - SNAC(4,6) - all
548  */
SnacCliSendmsg(Server * serv,Contact * cont,UBYTE format,Message * msg)549 UBYTE SnacCliSendmsg (Server *serv, Contact *cont, UBYTE format, Message *msg)
550 {
551     assert (serv);
552     assert (cont);
553     assert (msg);
554     assert (msg->cont == cont);
555 
556     if (format == 2 && !msg->force)
557     {
558         switch (msg->type & 0xff)
559         {
560             case MSG_AUTO:
561             case MSG_AUTH_REQ:
562             case MSG_AUTH_GRANT:
563             case MSG_AUTH_DENY:
564             case MSG_AUTH_ADDED:
565                 return RET_DEFER;
566             case MSG_GET_PEEK:
567             case MSG_GET_VER:
568                 break;
569             default:
570                 if (!HAS_CAP (cont->caps, CAP_SRVRELAY) || !HAS_CAP (cont->caps, CAP_REVCONNREQ))
571                     return RET_DEFER;
572         }
573     }
574     else if (format == 1 && !msg->force)
575     {
576         if ((msg->type & 0xff) != MSG_NORM)
577             return RET_DEFER;
578     }
579     else if (format == 4 && !msg->force)
580     {
581         switch (msg->type & 0xff)
582         {
583             case MSG_AUTO:
584             case MSG_URL:
585             case MSG_AUTH_REQ:
586             case MSG_AUTH_GRANT:
587             case MSG_AUTH_DENY:
588             case MSG_AUTH_ADDED:
589                 if (!cont->uin)
590                     return RET_DEFER;
591                 break;
592             case MSG_NORM:
593             default:
594             case MSG_GET_AWAY:
595             case MSG_GET_DND:
596             case MSG_GET_OCC:
597             case MSG_GET_FFC:
598             case MSG_GET_NA:
599             case MSG_GET_VER:
600             case MSG_GET_PEEK:
601                 return RET_DEFER;
602         }
603     }
604     else if (!format || format == 0xff)
605     {
606         switch (msg->type & 0xff)
607         {
608             case MSG_AUTO:
609             case MSG_URL:
610             case MSG_AUTH_REQ:
611             case MSG_AUTH_GRANT:
612             case MSG_AUTH_DENY:
613             case MSG_AUTH_ADDED:
614                 if (!cont->uin)
615                     return RET_DEFER;
616                 format = 4;
617                 break;
618             case MSG_NORM:
619                 format = 1;
620                 break;
621             default:
622             case MSG_GET_AWAY:
623             case MSG_GET_DND:
624             case MSG_GET_OCC:
625             case MSG_GET_FFC:
626             case MSG_GET_NA:
627             case MSG_GET_VER:
628             case MSG_GET_PEEK:
629                 format = 2;
630         }
631     }
632 
633     if (format == 1)
634         return SnacCliSendmsg1 (serv, msg);
635     else if (format == 4)
636         return SnacCliSendmsg4 (serv, msg);
637     else if (format == 2)
638         return SnacCliSendmsg2 (serv, msg);
639     return RET_DEFER;
640 }
641 
SnacSrvCallbackSendack(Event * event)642 static void SnacSrvCallbackSendack (Event *event)
643 {
644     if (!event || !event->conn)
645     {
646         EventD (event);
647         return;
648     }
649     ASSERT_SERVER_CONN (event->conn);
650     if (event->pak)
651     {
652         SnacSend (event->conn->serv, event->pak);
653         event->pak = NULL;
654     }
655     EventD (event);
656 }
657 
658 /*
659  * SRV_RECVMSG - SNAC(4,7)
660  */
JUMP_SNAC_F(SnacSrvRecvmsg)661 JUMP_SNAC_F(SnacSrvRecvmsg)
662 {
663     Server *serv = event->conn->serv;
664     Contact *cont;
665     Event *newevent;
666     Cap *cap1, *cap2;
667     Packet *p = NULL, *pp = NULL, *pak;
668     TLV *tlv, *tlvs;
669     Opt *opt;
670     UDWORD midtim, midrnd, midtime, midrand, unk, tmp, type1enc, tlvc;
671     UWORD seq1, tcpver, len, i, msgtyp, type;
672     const char *txt = NULL;
673     strc_t ctext;
674     str_s str = { NULL, 0, 0 };
675 
676     pak = event->pak;
677 
678     midtime = PacketReadB4 (pak);
679     midrand = PacketReadB4 (pak);
680     type    = PacketReadB2 (pak);
681     cont    = PacketReadCont (pak, serv);
682               PacketReadB2 (pak); /* WARNING */
683     tlvc    = PacketReadB2 (pak); /* COUNT */
684 
685     if (!cont)
686         return;
687 
688     tlv = TLVRead (pak, PacketReadLeft (pak), tlvc);
689 
690 #ifdef WIP
691     if (tlv[6].str.len && tlv[6].nr != cont->nativestatus)
692         rl_printf ("FIXMEWIP: status for %s embedded in message 0x%08lx different from server status 0x%08lx.\n", cont->screen, UD2UL (tlv[6].nr), UD2UL (cont->nativestatus));
693 #endif
694 
695     if (tlv[6].str.len)
696         event->opt = OptSetVals (event->opt, CO_STATUS, tlv[6].nr, 0);
697 
698     TLVD (tlv);
699     tlv = TLVRead (pak, PacketReadLeft (pak), -1);
700 
701     if (type == 1 && tlv[2].str.len)
702         tlvs = &tlv[2];
703     else if (type == 2 && tlv[5].str.len)
704         tlvs = &tlv[5];
705     else if (type == 4 && tlv[5].str.len)
706         tlvs = &tlv[5];
707     else
708     {
709         SnacSrvUnknown (event);
710         TLVD (tlv);
711         return;
712     }
713     p = PacketCreate (&tlvs->str);
714     TLVD (tlv);
715 
716     switch (type)
717     {
718         case 1:
719             PacketReadB2 (p);
720             PacketReadData (p, NULL, PacketReadB2 (p));
721                        PacketReadB2 (p);
722             len      = PacketReadB2 (p);
723 
724             type1enc = PacketReadB4 (p);
725             if (len < 4)
726             {
727                 SnacSrvUnknown (event);
728                 PacketD (p);
729                 return;
730             }
731             PacketReadData (p, &str, len - 4);
732             PacketD (p);
733             /* TLV 1, 2(!), 3, 4, f ignored */
734             switch (type1enc & 0xf0000)
735             {
736                 case 0x00020000:
737                     txt = ConvFrom (&str, ENC_UCS2BE)->txt;
738                     break;
739                 case 0x00030000:
740                     txt = ConvFromCont (&str, cont);
741                     break;
742                 case 0x00000000:
743                     if (ConvIsUTF8 (str.txt) && len == strlen (str.txt) + 4)
744                         txt = ConvFrom (&str, ENC_UTF8)->txt;
745                     else
746                         txt = ConvFromCont (&str, cont);
747                     break;
748                 default:
749                     SnacSrvUnknown (event);
750                     txt = ConvFromCont (&str, cont);
751                     break;
752             }
753             opt = OptSetVals (event->opt, CO_ORIGIN, CV_ORIGIN_v5, CO_MSGTYPE, MSG_NORM, CO_MSGTEXT, txt, 0);
754             event->opt = NULL;
755             IMSrvMsgFat (cont, NOW, opt);
756             Auto_Reply (serv, cont);
757             s_done (&str);
758             break;
759         case 2:
760             type   = PacketReadB2 (p);
761             midtim = PacketReadB4 (p);
762             midrnd = PacketReadB4 (p);
763             cap1   = PacketReadCap (p);
764 
765             ContactSetCap (cont, cap1);
766             if (midtim != midtime || midrnd != midrand)
767             {
768                 SnacSrvUnknown (event);
769                 PacketD (p);
770                 return;
771             }
772 
773             tlv = TLVRead (p, PacketReadLeft (p), -1);
774             PacketD (p);
775 
776             if ((i = TLVGet (tlv, 0x2711)) == (UWORD)-1)
777             {
778                 if (TLVGet (tlv, 11) == (UWORD)-1)
779                     SnacSrvUnknown (event);
780 #ifdef WIP
781                 else
782                 {
783                     rl_log_for (cont->nick, COLCONTACT);
784                     rl_printf ("FIXMEWIP: tlv(b)-only packet.\n");
785                 }
786 #endif
787                 TLVD (tlv);
788                 return;
789             }
790 
791             switch (cap1->id)
792             {
793                 case CAP_REVCONNREQ:
794                     if (tlv[i].str.len != 0x1b)
795                     {
796                         SnacSrvUnknown (event);
797                         TLVD (tlv);
798                         return;
799                     }
800                     pp = PacketCreate (&tlv[i].str);
801                     {
802                         UDWORD suin = PacketRead4  (pp);
803                         UDWORD sip  = PacketReadB4 (pp);
804                         UDWORD sp1  = PacketRead4  (pp);
805                         UBYTE  scon = PacketRead1  (pp);
806                         UDWORD sop  = PacketRead4  (pp);
807                         UDWORD sp2  = PacketRead4  (pp);
808                         UWORD  sver = PacketRead2  (pp);
809                         UDWORD sunk = PacketRead4  (pp);
810                         if (suin != cont->uin)
811                         {
812                             SnacSrvUnknown (event);
813                             TLVD (tlv);
814                             return;
815                         }
816 
817                         if (prG->verbose)
818                         {
819                             char *ip = strdup (s_ip (sip));
820                             rl_log_for (cont->nick, COLCONTACT);
821                             rl_printf (i18n (2742, "Incoming reverse connection request to %s.\n"),
822                                 s_sprintf ("%s:%ld|%ld|%ld v%d %d seq %ld",
823                                     ip, UD2UL (sp1), UD2UL (sp2), UD2UL (sop), sver, scon, UD2UL (sunk)));
824                             free (ip);
825                         }
826                         CONTACT_DC (cont)->ip_rem = sip;
827                         cont->dc->port = sp1;
828                         cont->dc->type = scon;
829                         cont->dc->version = sver;
830                     }
831                     PacketD (pp);
832                     TLVD (tlv);
833                     TCPDirectOpen (serv->oscar_dc, cont);
834                     return;
835 
836                 case CAP_SRVRELAY:
837                     if (tlv[i].str.txt[0] != 0x1b)
838                     {
839                         SnacSrvUnknown (event);
840                         TLVD (tlv);
841                         return;
842                     }
843                     pp = PacketCreate (&tlv[i].str);
844 
845                     p = SnacC (serv, 4, 11, 0, 0);
846                     PacketWriteB4 (p, midtim);
847                     PacketWriteB4 (p, midrnd);
848                     PacketWriteB2 (p, 2);
849                     PacketWriteCont (p, cont);
850                     PacketWriteB2 (p, 3);
851 
852                     len    = PacketRead2 (pp);      PacketWrite2 (p, len);
853                     tcpver = PacketRead2 (pp);      PacketWrite2 (p, tcpver);
854                     cap2   = PacketReadCap (pp);    PacketWriteCap (p, cap2);
855                     tmp    = PacketRead2 (pp);      PacketWrite2 (p, tmp);
856                     tmp    = PacketRead4 (pp);      PacketWrite4 (p, tmp);
857                     tmp    = PacketRead1 (pp);      PacketWrite1 (p, tmp);
858                     seq1   = PacketRead2 (pp);      PacketWrite2 (p, seq1);
859 
860                     ContactSetCap (cont, cap2);
861                     ContactSetVersion (cont);
862 
863                     if (cap2->id != CAP_STR_2001 && cap2->id != CAP_STR_2002)
864                     {
865                         event->opt = OptSetVals (event->opt, CO_ORIGIN, CV_ORIGIN_v8, 0);
866                         event->cont = cont;
867                         newevent = QueueEnqueueData (serv->conn, QUEUE_ACKNOWLEDGE, seq1,
868                                      (time_t)-1, p, cont, NULL, &SnacSrvCallbackSendack);
869                         SrvReceiveAdvanced (serv, event, pp, newevent);
870                     }
871                     else
872                         PacketD (p);
873                     PacketD (pp);
874                     TLVD (tlv);
875                     return;
876 
877                 default:
878                     SnacSrvUnknown (event);
879                     TLVD (tlv);
880                     return;
881             }
882             /* TLV 1, 2(!), 3, 4, f ignored */
883             break;
884         case 4:
885             unk    = PacketRead4 (p);
886             msgtyp = PacketRead2 (p);
887             if (unk != cont->uin)
888             {
889                 PacketD (p);
890                 SnacSrvUnknown (event);
891                 return;
892             }
893             ctext = PacketReadL2Str (p, NULL);
894             PacketD (p);
895             /* FOREGROUND / BACKGROUND ignored */
896             /* TLV 1, 2(!), 3, 4, f ignored */
897 
898             opt = OptSetVals (event->opt, CO_ORIGIN, CV_ORIGIN_v5, CO_MSGTYPE, msgtyp,
899                       CO_MSGTEXT, msgtyp == MSG_NORM ? ConvFromCont (ctext, cont) : c_in_to_split (ctext, cont), 0);
900             event->opt = NULL;
901             IMSrvMsgFat (cont, NOW, opt);
902             Auto_Reply (serv, cont);
903             break;
904     }
905 }
906 
907 /*
908  * SRV_ACKMSG - SNAC(4,C)
909  */
JUMP_SNAC_F(SnacSrvSrvackmsg)910 JUMP_SNAC_F(SnacSrvSrvackmsg)
911 {
912     Server *serv = event->conn->serv;
913     Event *event2 = NULL;
914     Packet *pak;
915     Message *msg;
916     Contact *cont;
917     /* UDWORD mid1, mid2; */
918     UWORD format;
919 
920     pak = event->pak;
921 
922     /*mid1=*/PacketReadB4 (pak);
923     /*mid2=*/PacketReadB4 (pak);
924     format = PacketReadB2 (pak);
925 
926     cont = PacketReadCont (pak, serv);
927 
928     if (!cont)
929         return;
930 
931 
932     switch (format)
933     {
934         case 1:
935             event2 = QueueDequeue (serv->conn, QUEUE_TYPE1_RESEND_ACK, pak->ref);
936             if (!event2 || !(msg = event2->data))
937                 break;
938             msg->type = INT_MSGACK_V8;
939             if ((msg->send_message || msg->plain_message) && !msg->otrinjected)
940                 IMIntMsgMsg (msg, NOW, ims_offline);
941             break;
942         case 4:
943             event2 = QueueDequeue (serv->conn, QUEUE_TYPE4_RESEND_ACK, pak->ref);
944             if (!event2 || !(msg = event2->data))
945                 break;
946             msg->type = INT_MSGACK_V8;
947             if ((msg->send_message || msg->plain_message) && !msg->otrinjected)
948                 IMIntMsgMsg (msg, NOW, ims_offline);
949             break;
950         case 2: /* msg was received by server */
951             event2 = QueueDequeue (serv->conn, QUEUE_TYPE2_RESEND_ACK, pak->ref);
952             if (!event2 || !(msg = event2->data))
953                 break;
954             if (pak->ref == PEEK_REFID)
955                 rl_print (i18n (2573, "The user is probably offline.\n"));
956             break;
957     }
958     if (event2)
959     {
960         MsgD (event2->data);
961         event2->data = NULL;
962         EventD (event2);
963     }
964 }
965 
SrvMsgAdvanced(Packet * pak,UDWORD seq,UWORD msgtype,status_t status,status_t deststatus,UWORD flags,const char * msg)966 void SrvMsgAdvanced (Packet *pak, UDWORD seq, UWORD msgtype, status_t status,
967                      status_t deststatus, UWORD flags, const char *msg)
968 {
969     if (msgtype == MSG_SSL_OPEN)
970         status = ims_online;
971 
972     if (flags == (UWORD)-1)
973     {
974         switch (ContactClearInv (deststatus))
975         {
976             case imr_offline: /* keep */ break;
977             case imr_dnd:
978             case imr_occ:     flags = TCP_MSGF_CLIST; break;
979             case imr_na:
980             case imr_away:    flags = TCP_MSGF_1; break;
981             case imr_ffc:
982             case imr_online:  flags = TCP_MSGF_LIST | TCP_MSGF_1; break;
983         }
984     }
985 
986     PacketWriteLen    (pak);
987      PacketWrite2      (pak, seq);       /* sequence number */
988      PacketWrite4      (pak, 0);
989      PacketWrite4      (pak, 0);
990      PacketWrite4      (pak, 0);
991     PacketWriteLenDone (pak);
992     PacketWrite2      (pak, msgtype);    /* message type    */
993     PacketWrite2      (pak, IcqFromStatus (status));
994                                          /* status          */
995     PacketWrite2      (pak, flags);      /* flags           */
996     PacketWriteLNTS   (pak, msg);        /* the message     */
997 }
998 
999 /*
1000  * Append the "geeting" part to an advanced message packet.
1001  */
SrvMsgGreet(Packet * pak,UWORD cmd,const char * reason,UWORD port,UDWORD len,const char * msg)1002 void SrvMsgGreet (Packet *pak, UWORD cmd, const char *reason, UWORD port, UDWORD len, const char *msg)
1003 {
1004     PacketWrite2     (pak, cmd);
1005     switch (cmd)
1006     {
1007         case 0x2d:
1008         default:
1009             PacketWriteB4  (pak, 0xbff720b2);
1010             PacketWriteB4  (pak, 0x378ed411);
1011             PacketWriteB4  (pak, 0xbd280004);
1012             PacketWriteB4  (pak, 0xac96d905);
1013             break;
1014         case 0x29:
1015         case 0x32:
1016             PacketWriteB4  (pak, 0xf02d12d9);
1017             PacketWriteB4  (pak, 0x3091d311);
1018             PacketWriteB4  (pak, 0x8dd70010);
1019             PacketWriteB4  (pak, 0x4b06462e);
1020     }
1021     PacketWrite2     (pak, 0);
1022     switch (cmd)
1023     {
1024         case 0x29:  PacketWriteDLStr (pak, "File");          break;
1025         case 0x2d:  PacketWriteDLStr (pak, "ICQ Chat");      break;
1026         case 0x32:  PacketWriteDLStr (pak, "File Transfer"); break;
1027         default:    PacketWriteDLStr (pak, "");
1028     }
1029     PacketWrite2     (pak, 0);
1030     PacketWrite1     (pak, 1);
1031     switch (cmd)
1032     {
1033         case 0x29:
1034         case 0x2d:  PacketWriteB4    (pak, 0x00000100);      break;
1035         case 0x32:  PacketWriteB4    (pak, 0x01000000);      break;
1036         default:    PacketWriteB4    (pak, 0);
1037     }
1038     PacketWriteB4    (pak, 0);
1039     PacketWriteB4    (pak, 0);
1040     PacketWriteLen4  (pak);
1041     PacketWriteDLStr (pak, c_out (reason));
1042     PacketWriteB2    (pak, port);
1043     PacketWriteB2    (pak, 0);
1044     PacketWriteLNTS  (pak, c_out (msg));
1045     PacketWrite4     (pak, len);
1046     if (cmd != 0x2d)
1047         PacketWrite4     (pak, port);
1048     PacketWriteLen4Done (pak);
1049 }
1050 
1051 /*
1052  * Process an advanced message.
1053  *
1054  * Note: swallows only acknowledge event/packet;
1055  * the caller destructs inc_event after return.
1056  */
SrvReceiveAdvanced(Server * serv,Event * inc_event,Packet * inc_pak,Event * ack_event)1057 void SrvReceiveAdvanced (Server *serv, Event *inc_event, Packet *inc_pak, Event *ack_event)
1058 {
1059 #ifdef ENABLE_PEER2PEER
1060     Connection *flist;
1061     Event *e1;
1062     UDWORD opt_acc;
1063 #endif
1064     Contact *cont = inc_event->cont;
1065     Opt *opt = inc_event->opt, *opt2;
1066     Packet *ack_pak = ack_event->pak;
1067     const char *txt, *ack_msg = "", *tauto;
1068     strc_t text, cname, ctext, reason, cctmp;
1069     char *name;
1070     UDWORD tmp, cmd, flen;
1071     UWORD unk, seq, msgtype, unk2, pri;
1072     UWORD ack_flags, ack_status, accept;
1073 
1074     unk     = PacketRead2    (inc_pak);  PacketWrite2 (ack_pak, unk);
1075     seq     = PacketRead2    (inc_pak);  PacketWrite2 (ack_pak, seq);
1076     tmp     = PacketRead4    (inc_pak);  PacketWrite4 (ack_pak, tmp);
1077     tmp     = PacketRead4    (inc_pak);  PacketWrite4 (ack_pak, tmp);
1078     tmp     = PacketRead4    (inc_pak);  PacketWrite4 (ack_pak, tmp);
1079     msgtype = PacketRead2    (inc_pak);  PacketWrite2 (ack_pak, msgtype);
1080 
1081     unk2    = PacketRead2    (inc_pak);
1082     pri     = PacketRead2    (inc_pak);
1083     text    = PacketReadL2Str (inc_pak, NULL);
1084 
1085 #ifdef WIP
1086     if (prG->verbose)
1087     rl_printf ("FIXMEWIP: Starting advanced message: events %p, %p; type %d, seq %x.\n",
1088               inc_event, ack_event, msgtype, seq);
1089 #endif
1090 
1091     OptSetVal (opt, CO_MSGTYPE, msgtype);
1092     OptSetStr (opt, CO_MSGTEXT, msgtype == MSG_NORM ? ConvFromCont (text, cont) : c_in_to_split (text, cont));
1093 
1094     accept = FALSE;
1095 
1096 /*
1097  * Don't refuse until we have sensible preferences for that
1098  */
1099     switch (ContactClearInv (serv->status))
1100     {
1101         case imr_dnd:  ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTODND))  && *tauto ?
1102                        tauto : ContactPrefStr (cont, CO_AUTODND);  ack_status = TCP_ACK_ONLINE; break;
1103         case imr_occ:  ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTOOCC))  && *tauto ?
1104                        tauto : ContactPrefStr (cont, CO_AUTOOCC);  ack_status = TCP_ACK_ONLINE; break;
1105         case imr_na:   ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTONA))   && *tauto ?
1106                        tauto : ContactPrefStr (cont, CO_AUTONA);   ack_status = TCP_ACK_NA;     break;
1107         case imr_away: ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTOAWAY)) && *tauto ?
1108                        tauto : ContactPrefStr (cont, CO_AUTOAWAY); ack_status = TCP_ACK_AWAY;   break;
1109         default:       ack_status  = TCP_ACK_ONLINE;
1110     }
1111 
1112     ack_flags = 0;
1113     if (ContactIsInv (serv->status))  ack_flags |= TCP_MSGF_INV;
1114 
1115     switch (msgtype & ~MSGF_MASS)
1116     {
1117         /* Requests for auto-response message */
1118         do  {
1119                 val_t val;
1120 
1121         case MSGF_GETAUTO | MSG_GET_AWAY:
1122             ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTOAWAY)) && *tauto ? tauto : ContactPrefStr (cont, CO_AUTOAWAY);
1123             break;
1124         case MSGF_GETAUTO | MSG_GET_OCC:
1125             ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTOOCC))  && *tauto ? tauto : ContactPrefStr (cont, CO_AUTOOCC);
1126             break;
1127         case MSGF_GETAUTO | MSG_GET_NA:
1128             ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTONA))   && *tauto ? tauto : ContactPrefStr (cont, CO_AUTONA);
1129             break;
1130         case MSGF_GETAUTO | MSG_GET_DND:
1131             ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTODND))  && *tauto ? tauto : ContactPrefStr (cont, CO_AUTODND);
1132             break;
1133         case MSGF_GETAUTO | MSG_GET_FFC:   ack_msg = ContactPrefStr (cont, CO_AUTOFFC);  break;
1134         case MSGF_GETAUTO | MSG_GET_VER:
1135                 if (!OptGetVal (&prG->copts, CO_ENCODING, &val))
1136                     val = -1;
1137                 ack_msg = s_sprintf ("%s\nLocale: %s %s %s %s %d %s", BuildVersionText,
1138                                      prG->locale, prG->locale_orig, prG->locale_full,
1139                                      ConvEncName (prG->enc_loc), prG->locale_broken, ConvEncName (val));
1140             } while (0);
1141 
1142 #ifdef WIP
1143             if (1)
1144 #else
1145             if (msgtype != 1012)
1146 #endif
1147             {
1148                 if (((ack_flags & TCP_MSGF_INV) && !ContactPrefVal (cont, CO_INTIMATE)) || ContactPrefVal (cont, CO_HIDEFROM))
1149                 {
1150                     if (ContactPrefVal (cont, CO_SHOWCHANGE))
1151                     {
1152                         rl_log_for (cont->nick, COLCONTACT);
1153                         rl_printf (i18n (2568, "Ignored request for auto-response from %s%s%s.\n"),
1154                                    COLCONTACT, cont->nick, COLNONE);
1155                     }
1156                     ack_event->due = 0;
1157                     ack_event->callback = NULL;
1158                     QueueDequeueEvent (ack_event);
1159                     EventD (ack_event);
1160                     return;
1161                 }
1162                 if (ContactPrefVal (cont, CO_SHOWCHANGE))
1163                 {
1164                     rl_log_for (cont->nick, COLCONTACT);
1165                     rl_printf (i18n (1814, "Sent auto-response message to %s%s%s.\n"),
1166                                COLCONTACT, cont->nick, COLNONE);
1167                 }
1168             }
1169 
1170             accept = TRUE;
1171             ack_flags = pri;
1172             ack_status = 0;
1173             break;
1174 
1175         case MSG_FILE:
1176 #ifdef ENABLE_PEER2PEER
1177             cmd     = PacketRead4 (inc_pak);
1178             cname   = PacketReadL2Str (inc_pak, NULL);
1179             flen    = PacketRead4 (inc_pak);
1180             msgtype = PacketRead4 (inc_pak);
1181 
1182             name = strdup (ConvFromCont (cname, cont));
1183 
1184             flist = PeerFileCreate (serv);
1185             OptSetVal (opt, CO_FILEACCEPT, 0);
1186             OptSetVal (opt, CO_BYTES, flen);
1187             OptSetStr (opt, CO_MSGTEXT, name);
1188             OptSetVal (opt, CO_REF, ack_event->seq);
1189             if (!OptGetVal (opt, CO_FILEACCEPT, &opt_acc) && flen)
1190             {
1191                 opt2 = OptC ();
1192                 OptSetVal (opt2, CO_BYTES, flen);
1193                 OptSetStr (opt2, CO_MSGTEXT, name);
1194                 OptSetVal (opt2, CO_REF, ack_event->seq);
1195                 OptSetVal (opt2, CO_MSGTYPE, msgtype);
1196                 IMSrvMsgFat (cont, NOW, opt2);
1197                 opt2 = OptC ();
1198                 OptSetVal (opt2, CO_FILEACCEPT, 0);
1199                 OptSetStr (opt2, CO_REFUSE, i18n (2514, "refused (ignored)"));
1200                 e1 = QueueEnqueueData (serv->conn, QUEUE_USERFILEACK, ack_event->seq, time (NULL) + 120,
1201                                        NULL, inc_event->cont, opt2, &PeerFileTO);
1202                 QueueEnqueueDep (inc_event->conn, inc_event->type, ack_event->seq, e1,
1203                                  inc_event->pak, inc_event->cont, opt, inc_event->callback);
1204                 inc_event->pak->rpos = inc_event->pak->tpos;
1205                 inc_event->opt = NULL;
1206                 inc_event->pak = NULL;
1207                 ack_event->due = 0;
1208                 ack_event->callback = NULL;
1209                 QueueDequeueEvent (ack_event);
1210                 EventD (ack_event);
1211                 free (name);
1212 #ifdef WIP
1213                 rl_printf ("FIXMEWIP: Delaying advanced message: events %p, %p.\n", inc_event, ack_event);
1214 #endif
1215                 return;
1216             }
1217             free (name);
1218             if (serv->oscar_dc && PeerFileIncAccept (serv->oscar_dc, inc_event))
1219             {
1220                 PacketWrite2    (ack_pak, ack_status);
1221                 PacketWrite2    (ack_pak, ack_flags);
1222                 PacketWriteLNTS (ack_pak, c_out (ack_msg));
1223                 PacketWriteB2   (ack_pak, flist->port);
1224                 PacketWrite2    (ack_pak, 0);
1225                 PacketWriteStr  (ack_pak, "");
1226                 PacketWrite4    (ack_pak, 0);
1227                 if (serv->oscar_dc->version > 6)
1228                     PacketWrite4 (ack_pak, 0x20726f66);
1229                 PacketWrite4    (ack_pak, flist->port);
1230             }
1231             else
1232 #endif
1233             {
1234                 if (!OptGetStr (inc_event->wait->opt, CO_REFUSE, &txt))
1235                     txt = "";
1236                 PacketWrite2    (ack_pak, TCP_ACK_REFUSE);
1237                 PacketWrite2    (ack_pak, ack_flags);
1238                 PacketWriteLNTS (ack_pak, c_out (ack_msg));
1239                 PacketWriteB2   (ack_pak, 0);
1240                 PacketWrite2    (ack_pak, 0);
1241                 PacketWriteStr  (ack_pak, txt);
1242                 PacketWrite4    (ack_pak, 0);
1243                 if (serv->oscar_dc->version > 6)
1244                     PacketWrite4 (ack_pak, 0x20726f66);
1245                 PacketWrite4    (ack_pak, 0);
1246             }
1247             EventD (QueueDequeueEvent (inc_event->wait));
1248             inc_event->wait = NULL;
1249             accept = -1;
1250             break;
1251         case MSG_EXTENDED:
1252             {
1253                 /* UWORD port, port2, pad; */
1254                 char *gtext;
1255                 char id[20];
1256                 cmd    = PacketRead2 (inc_pak);
1257                 {
1258                     str_s t = { 0, 0, 0 };
1259                     s_init (&t, "", 20);
1260                          PacketReadData (inc_pak, &t, 16);
1261                     memcpy (id, t.txt, 16);
1262                     id[17] = 0;
1263                     s_done (&t);
1264                 }
1265                          PacketRead2 (inc_pak);
1266                 ctext  = PacketReadL4Str (inc_pak, NULL);
1267                          PacketReadData (inc_pak, NULL, 15);
1268                          PacketRead4 (inc_pak);
1269                 reason = PacketReadL4Str (inc_pak, NULL);
1270                 /*port=*/PacketReadB2 (inc_pak);
1271                 /*pad=*/ PacketRead2 (inc_pak);
1272                 cname  = PacketReadL2Str (inc_pak, NULL);
1273                 flen   = PacketRead4 (inc_pak);
1274                 /*port2*/PacketRead4 (inc_pak);
1275 
1276                 gtext = strdup (ConvFromCont (ctext, cont));
1277                 name = strdup (ConvFromCont (cname, cont));
1278 
1279                 switch (cmd)
1280                 {
1281                     case 0x0029:
1282 #ifdef ENABLE_PEER2PEER
1283                         flist = PeerFileCreate (serv);
1284                         OptSetVal (opt, CO_FILEACCEPT, 0);
1285                         OptSetVal (opt, CO_BYTES, flen);
1286                         OptSetStr (opt, CO_MSGTEXT, name);
1287                         OptSetVal (opt, CO_REF, ack_event->seq);
1288                         if (!inc_event->wait)
1289                         {
1290                             opt2 = OptC ();
1291                             OptSetVal (opt2, CO_BYTES, flen);
1292                             OptSetStr (opt2, CO_MSGTEXT, name);
1293                             OptSetVal (opt2, CO_REF, ack_event->seq);
1294                             OptSetVal (opt2, CO_MSGTYPE, MSG_FILE);
1295                             IMSrvMsgFat (cont, NOW, opt2);
1296                             opt2 = OptC ();
1297                             OptSetVal (opt2, CO_FILEACCEPT, 0);
1298                             OptSetStr (opt2, CO_REFUSE, i18n (2514, "refused (ignored)"));
1299                             e1 = QueueEnqueueData (serv->conn, QUEUE_USERFILEACK, ack_event->seq, time (NULL) + 120,
1300                                                    NULL, inc_event->cont, opt2, &PeerFileTO);
1301                             QueueEnqueueDep (inc_event->conn, inc_event->type, ack_event->seq, e1,
1302                                              inc_event->pak, inc_event->cont, opt, inc_event->callback);
1303                             inc_event->pak->rpos = inc_event->pak->tpos;
1304                             inc_event->opt = NULL;
1305                             inc_event->pak = NULL;
1306                             ack_event->callback = NULL;
1307                             ack_event->due = 0;
1308                             QueueDequeueEvent (ack_event);
1309                             EventD (ack_event);
1310                             free (name);
1311                             free (gtext);
1312 #ifdef WIP
1313                             rl_printf ("FIXMEWIP: Delaying advanced message: events %p, %p.\n", inc_event, ack_event);
1314 #endif
1315                             return;
1316                         }
1317                         if (serv->oscar_dc && PeerFileIncAccept (serv->oscar_dc, inc_event))
1318                         {
1319                             PacketWrite2    (ack_pak, ack_status);
1320                             PacketWrite2    (ack_pak, ack_flags);
1321                             PacketWriteLNTS (ack_pak, "");
1322                             SrvMsgGreet     (ack_pak, cmd, "", flist->port, 0, "");
1323                         }
1324                         else
1325 #endif
1326                         {
1327                             if (!OptGetStr (inc_event->wait->opt, CO_REFUSE, &txt))
1328                                 txt = "";
1329                             PacketWrite2    (ack_pak, TCP_ACK_REFUSE);
1330                             PacketWrite2    (ack_pak, ack_flags);
1331                             PacketWriteLNTS (ack_pak, txt);
1332                             SrvMsgGreet     (ack_pak, cmd, "", 0, 0, "");
1333                         }
1334                         EventD (QueueDequeueEvent (inc_event->wait));
1335                         inc_event->wait = NULL;
1336                         break;
1337 
1338                     case 0x002d:
1339                         if (id[0] == (char)0xbf)
1340                         {
1341                             IMSrvMsg (cont, NOW, 0, msgtype, c_in_to_split (text, cont));
1342                             IMSrvMsg (cont, NOW, 0, MSG_CHAT, name);
1343                             opt2 = OptC ();
1344                             OptSetVal (opt2, CO_MSGTYPE, MSG_CHAT);
1345                             OptSetStr (opt2, CO_MSGTEXT, reason->txt);
1346                             PacketWrite2    (ack_pak, TCP_ACK_REFUSE);
1347                             PacketWrite2    (ack_pak, ack_flags);
1348                             PacketWriteLNTS (ack_pak, "");
1349                             SrvMsgGreet     (ack_pak, cmd, "", 0, 0, "");
1350                             break;
1351                         }
1352                         else if (id[0] == (char)0x2a)
1353                         {
1354                             IMSrvMsg (cont, NOW, 0, MSG_CONTACT, c_in_to_split (reason, cont));
1355                             PacketWrite2    (ack_pak, ack_status);
1356                             PacketWrite2    (ack_pak, ack_flags);
1357                             PacketWriteLNTS (ack_pak, "");
1358                             SrvMsgGreet     (ack_pak, cmd, "", 0, 0, "");
1359                             break;
1360                         }
1361 
1362                     case 0x0032:
1363                     default:
1364                         if (prG->verbose & DEB_PROTOCOL)
1365                             rl_printf (i18n (2065, "Unknown TCP_MSG_GREET_ command %04x.\n"), msgtype);
1366                         PacketWrite2    (ack_pak, TCP_ACK_REFUSE);
1367                         PacketWrite2    (ack_pak, ack_flags);
1368                         PacketWriteLNTS (ack_pak, "");
1369                         SrvMsgGreet     (ack_pak, cmd, "", 0, 0, "");
1370                         break;
1371 
1372                 }
1373                 free (name);
1374                 free (gtext);
1375                 accept = -1;
1376             }
1377             break;
1378 #ifdef ENABLE_SSL
1379         case MSG_SSL_OPEN:  /* Licq compatible SSL handshake */
1380             if (!unk2)
1381             {
1382                 PacketWrite2     (ack_pak, ack_status);
1383                 PacketWrite2     (ack_pak, ack_flags);
1384                 PacketWriteLNTS  (ack_pak, c_out ("1"));
1385                 accept = -1;
1386                 ack_event->conn->ssl_status = SSL_STATUS_INIT;
1387             }
1388             break;
1389         case MSG_SSL_CLOSE:
1390             if (!unk2)
1391             {
1392                 PacketWrite2     (ack_pak, ack_status);
1393                 PacketWrite2     (ack_pak, ack_flags);
1394                 PacketWriteLNTS  (ack_pak, c_out (""));
1395                 accept = -1;
1396                 ack_event->conn->ssl_status = SSL_STATUS_CLOSE;
1397             }
1398             break;
1399 #endif
1400         default:
1401             if (prG->verbose & DEB_PROTOCOL)
1402                 rl_printf (i18n (2066, "Unknown TCP_MSG_ command %04x.\n"), msgtype);
1403             /* fall-through */
1404         case MSG_CHAT:
1405             /* chat ist not implemented, so reject chat requests */
1406             accept = FALSE;
1407             break;
1408 
1409         /* Regular messages */
1410         case MSG_AUTO:
1411         case MSG_NORM:
1412         case MSG_URL:
1413         case MSG_AUTH_REQ:
1414         case MSG_AUTH_DENY:
1415         case MSG_AUTH_GRANT:
1416         case MSG_AUTH_ADDED:
1417         case MSG_WEB:
1418         case MSG_EMAIL:
1419         case MSG_CONTACT:
1420             /**/    PacketRead4 (inc_pak);
1421             /**/    PacketRead4 (inc_pak);
1422             cctmp = PacketReadL4Str (inc_pak, NULL);
1423             if (!strcmp (cctmp->txt, CAP_GID_UTF8))
1424                 OptSetStr (opt, CO_MSGTEXT, text->txt);
1425             if (*text->txt)
1426                 IMSrvMsgFat (cont, NOW, opt);
1427             inc_event->opt = NULL;
1428             PacketWrite2     (ack_pak, ack_status);
1429             PacketWrite2     (ack_pak, ack_flags);
1430             PacketWriteLNTS  (ack_pak, c_out_for (ack_msg, cont, msgtype));
1431             if (msgtype == MSG_NORM)
1432             {
1433                 PacketWrite4 (ack_pak, TCP_COL_FG);
1434                 PacketWrite4 (ack_pak, TCP_COL_BG);
1435             }
1436             if (CONT_UTF8 (cont, msgtype))
1437                 PacketWriteDLStr     (ack_pak, CAP_GID_UTF8);
1438             accept = -1;
1439             break;
1440     }
1441     switch (accept)
1442     {
1443         case FALSE:
1444             PacketWrite2      (ack_pak, TCP_ACK_REFUSE);
1445             PacketWrite2      (ack_pak, ack_flags);
1446             PacketWriteLNTS   (ack_pak, c_out_to (ack_msg, cont));
1447             break;
1448 
1449         case TRUE:
1450             PacketWrite2      (ack_pak, ack_status);
1451             PacketWrite2      (ack_pak, ack_flags);
1452             PacketWriteLNTS   (ack_pak, c_out_to (ack_msg, cont));
1453     }
1454 #ifdef WIP
1455     if (prG->verbose)
1456     rl_printf ("FIXMEWIP: Finishing advanced message: events %p, %p.\n", inc_event, ack_event);
1457 #endif
1458     QueueDequeueEvent (ack_event);
1459     ack_event->callback (ack_event);
1460 }
1461 
1462