1 /*
2  * Handles incoming and creates outgoing SNAC packets
3  * for the family 21 (old ICQ) commands.
4  *
5  * climm Copyright (C) © 2001-2010 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_oldicq.c 2864 2010-03-16 22:48:25Z 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_oldicq.h"
39 #include "oscar_roster.h"
40 #include "packet.h"
41 #include "contact.h"
42 #include "connection.h"
43 #include "preferences.h"
44 #include "conv.h"
45 #include "im_response.h"
46 #include "im_request.h"
47 #include "util_ui.h"
48 
49 static Packet *SnacMetaC (Server *serv, UWORD sub, UWORD type, UWORD ref);
50 static void SnacMetaSend (Server *serv, Packet *pak);
51 
52 #define PacketWriteMetaLNTS(p,t,s)  { PacketWrite2 (p, t); PacketWriteLen (p); PacketWriteLNTS (p, s); PacketWriteLenDone (p); }
53 #define PacketWriteMeta1(p,t,i)     { PacketWrite2 (p, t); PacketWrite2 (p, 1); PacketWrite1 (p, i); }
54 #define PacketWriteMeta2(p,t,i)     { PacketWrite2 (p, t); PacketWrite2 (p, 2); PacketWrite2 (p, i); }
55 #define PacketWriteMeta4(p,t,i)     { PacketWrite2 (p, t); PacketWrite2 (p, 4); PacketWrite4 (p, i); }
56 #define PacketWriteMeta6(p,t,i,j,k) { PacketWrite2 (p, t); PacketWrite2 (p, 6); PacketWrite2 (p, i); PacketWrite2 (p, j); PacketWrite2 (p, k); }
57 
58 #define META_TAG_UIN         310 /* LE32 */
59 #define META_TAG_FIRST       320
60 #define META_TAG_LAST        330
61 #define META_TAG_NICK        340
62 #define META_TAG_EMAIL       350 /* LNTS B */
63 #define META_TAG_AGERANGE    360 /* LE16 LE16 */
64 #define META_TAG_AGE         370 /* LE16 */
65 #define META_TAG_GENDER      380 /* B */
66 #define META_TAG_LANG        390 /* LE16 */
67 #define META_TAG_HOME_CITY   400
68 #define META_TAG_HOME_STATE  410
69 #define META_TAG_HOME_CTRY   420 /* LE16 */
70 #define META_TAG_WRK_COMP    430
71 #define META_TAG_WRK_DEPT    440
72 #define META_TAG_WRK_POS     450
73 #define META_TAG_WRK_OCC     460 /* LE16 */
74 #define META_TAG_AFFIL       470 /* LE16 LNTS */
75 
76 #define META_TAG_INTER       490 /* LE16 LNTS */
77 
78 #define META_TAG_PASTINFO    510 /* LE16 LNTS */
79 
80 #define META_TAG_HP_CAT      530 /* LE16 LNTS */
81 #define META_TAG_HP_URL      531 /* LE16 LNTS */
82 
83 #define META_TAG_SRCH_STRING 550
84 #define META_TAG_SRCH_ONLINE 560 /* B */
85 #define META_TAG_BIRTHDAY    570 /* LE16 LE16 LE16 */
86 
87 #define META_TAG_ABOUT       600
88 #define META_TAG_HOME_STREET 610
89 #define META_TAG_HOME_ZIP    620 /* LE32 */
90 #define META_TAG_HOME_PHONE  630
91 #define META_TAG_HOME_FAX    640
92 #define META_TAG_HOME_CELL   650
93 #define META_TAG_WRK_STREET  660
94 #define META_TAG_WRK_CITY    670
95 #define META_TAG_WRK_STATE   680
96 #define META_TAG_WRK_CTRY    690 /* LE16 */
97 #define META_TAG_WRK_ZIP     700 /* LE32 */
98 #define META_TAG_WRK_PHONE   710
99 #define META_TAG_WRK_FAX     720
100 #define META_TAG_WRK_URL     730
101 
102 #define META_TAG_AUTHREQ     760 /* B (yes, 760, NOT 780) */
103 #define META_TAG_WEBAWARE    780 /* B */
104 
105 #define META_TAG_TZ          790 /* SB */
106 #define META_TAG_ORIG_CITY   800
107 #define META_TAG_ORIG_STATE  810
108 #define META_TAG_ORIG_CTRY   820 /* LE16 */
109 
110 /*
111  * Create meta request package.
112  */
SnacMetaC(Server * serv,UWORD sub,UWORD type,UWORD ref)113 static Packet *SnacMetaC (Server *serv, UWORD sub, UWORD type, UWORD ref)
114 {
115     Packet *pak;
116 
117     serv->oscar_icq_seq = serv->oscar_icq_seq ? (serv->oscar_icq_seq + 1) % 0x7fff : 2;
118 
119     pak = SnacC (serv, 21, 2, 0, (ref ? ref : rand () % 0x7fff) + (serv->oscar_icq_seq << 16));
120     PacketWriteTLV (pak, 1);
121     PacketWriteLen (pak);
122     PacketWrite4   (pak, serv->oscar_uin);
123     PacketWrite2   (pak, sub);
124     PacketWrite2   (pak, serv->oscar_icq_seq);
125     if (type)
126         PacketWrite2 (pak, type);
127 
128     return pak;
129 }
130 
131 /*
132  * Complete & send meta request package.
133  */
SnacMetaSend(Server * serv,Packet * pak)134 static void SnacMetaSend (Server *serv, Packet *pak)
135 {
136     PacketWriteLenDone (pak);
137     PacketWriteTLVDone (pak);
138     SnacSend (serv, pak);
139 }
140 
141 /*
142  * SRV_TOICQERR - SNAC(15,1)
143  */
JUMP_SNAC_F(SnacSrvToicqerr)144 JUMP_SNAC_F(SnacSrvToicqerr)
145 {
146     Server *serv = event->conn->serv;
147     Packet *pak = event->pak;
148     if ((pak->ref & 0xffff) == 0x4231)
149     {
150         rl_print (i18n (2206, "The server doesn't want to give us offline messages.\n"));
151     }
152     else
153     {
154         UWORD err = PacketReadB2 (pak);
155         Event *oevent;
156 
157         if ((oevent = QueueDequeue (serv->conn, QUEUE_REQUEST_META, pak->ref)))
158         {
159             rl_printf (i18n (2207, "Protocol error in command to old ICQ server: %d.\n"), err);
160             if (err == 2)
161                 rl_printf (i18n (2515, "You queried already too many users today - come back tomorrow.\n"));
162             else if (err == 5)
163                 rl_printf (i18n (2516, "The query got stuck. Or somesuch. Try again later.\n"));
164             else
165                 rl_printf (i18n (2517, "I'm out of wisdom about the server's problem. It just didn't work out.\n"));
166             EventD (oevent);
167         }
168         else if ((pak->ref & 0xffff) != 0x4242)
169         {
170             rl_printf (i18n (2207, "Protocol error in command to old ICQ server: %d.\n"), err);
171             rl_print (s_dump (pak->data + pak->rpos, pak->len - pak->rpos));
172         }
173     }
174 }
175 
176 /*
177  * CLI_REQOFFLINEMSGS - SNAC(15,2) - 60
178  */
SnacCliReqofflinemsgs(Server * serv)179 void SnacCliReqofflinemsgs (Server *serv)
180 {
181     Packet *pak;
182 
183     pak = SnacMetaC (serv, 60, 0, 0x4231);
184     SnacMetaSend    (serv, pak);
185 }
186 
187 /*
188  * CLI_ACKOFFLINEMSGS - SNAC(15,2) - 62
189  */
SnacCliAckofflinemsgs(Server * serv)190 void SnacCliAckofflinemsgs (Server *serv)
191 {
192     Packet *pak;
193 
194     pak = SnacMetaC (serv, 62, 0, 0);
195     SnacMetaSend    (serv, pak);
196 }
197 
198 /*
199  * CLI_METASETGENERAL - SNAC(15,2) - 2000/1002
200  */
SnacCliMetasetgeneral(Server * serv,Contact * cont)201 void SnacCliMetasetgeneral (Server *serv, Contact *cont)
202 {
203     Packet *pak;
204 
205 #if 0
206     pak = SnacMetaC (serv, 2000, META_SET_GENERAL_INFO, 0);
207     if (cont->meta_general)
208     {
209         PacketWriteLNTS (pak, c_out (cont->meta_general->nick));
210         PacketWriteLNTS (pak, c_out (cont->meta_general->first));
211         PacketWriteLNTS (pak, c_out (cont->meta_general->last));
212         PacketWriteLNTS (pak, c_out (cont->meta_general->email));
213         PacketWriteLNTS (pak, c_out (cont->meta_general->city));
214         PacketWriteLNTS (pak, c_out (cont->meta_general->state));
215         PacketWriteLNTS (pak, c_out (cont->meta_general->phone));
216         PacketWriteLNTS (pak, c_out (cont->meta_general->fax));
217         PacketWriteLNTS (pak, c_out (cont->meta_general->street));
218         PacketWriteLNTS (pak, c_out (cont->meta_general->cellular));
219         PacketWriteLNTS (pak, c_out (cont->meta_general->zip));
220         PacketWrite2    (pak, cont->meta_general->country);
221         PacketWrite1    (pak, cont->meta_general->tz);
222         PacketWrite1    (pak, cont->meta_general->webaware);
223     }
224     else
225     {
226         PacketWriteLNTS (pak, c_out (cont->nick));
227         PacketWriteLNTS (pak, "<unset>");
228         PacketWriteLNTS (pak, "<unset>");
229         PacketWriteLNTS (pak, "");
230         PacketWriteLNTS (pak, "");
231         PacketWriteLNTS (pak, "");
232         PacketWriteLNTS (pak, "");
233         PacketWriteLNTS (pak, "");
234         PacketWriteLNTS (pak, "");
235         PacketWriteLNTS (pak, "");
236         PacketWriteLNTS (pak, "");
237         PacketWrite2    (pak, 0);
238         PacketWrite1    (pak, 0);
239         PacketWrite1    (pak, 0);
240     }
241 #else
242     pak = SnacMetaC (serv, 2000, META_SAVE_INFO, 0);
243     if (cont->meta_general)
244     {
245         ContactMeta *ml;
246 
247         PacketWriteMetaLNTS (pak, META_TAG_NICK, c_out (cont->meta_general->nick));
248         PacketWriteMetaLNTS (pak, META_TAG_FIRST, c_out (cont->meta_general->first));
249         PacketWriteMetaLNTS (pak, META_TAG_LAST, c_out (cont->meta_general->last));
250 
251         PacketWrite2 (pak, META_TAG_EMAIL);
252         PacketWriteLen (pak);
253         PacketWriteLNTS (pak, c_out (cont->meta_general->email));
254         PacketWrite1 (pak, 0);
255         PacketWriteLenDone  (pak);
256 
257         for (ml = cont->meta_email ; ml; ml = ml->next)
258         {
259             if (!ml->text || !*ml->text)
260                 continue;
261             PacketWrite2 (pak, META_TAG_EMAIL);
262             PacketWriteLen (pak);
263             PacketWriteLNTS (pak, c_out (ml->text));
264             PacketWrite1 (pak, ml->data);
265             PacketWriteLenDone  (pak);
266         }
267 
268         PacketWriteMetaLNTS (pak, META_TAG_HOME_CITY, c_out (cont->meta_general->city));
269         PacketWriteMetaLNTS (pak, META_TAG_HOME_STATE, c_out (cont->meta_general->state));
270         PacketWriteMetaLNTS (pak, META_TAG_HOME_PHONE, c_out (cont->meta_general->phone));
271         PacketWriteMetaLNTS (pak, META_TAG_HOME_FAX, c_out (cont->meta_general->fax));
272         PacketWriteMetaLNTS (pak, META_TAG_HOME_STREET, c_out (cont->meta_general->street));
273         PacketWriteMetaLNTS (pak, META_TAG_HOME_CELL, c_out (cont->meta_general->cellular));
274         PacketWriteMeta4    (pak, META_TAG_HOME_ZIP, atoi (cont->meta_general->zip));
275 
276         PacketWriteMeta2    (pak, META_TAG_HOME_CTRY, cont->meta_general->country);
277         PacketWriteMeta2    (pak, 835, 0);
278         PacketWriteMeta4    (pak, 621, 0);
279         PacketWriteMeta1    (pak, META_TAG_TZ, -cont->meta_general->tz/2);
280 
281         PacketWriteMeta1    (pak, META_TAG_WEBAWARE, cont->meta_general->webaware);
282         PacketWriteMeta1    (pak, META_TAG_AUTHREQ, !cont->meta_general->auth);
283     }
284     else
285     {
286         PacketWriteMetaLNTS (pak, META_TAG_NICK, c_out (cont->nick));
287         PacketWriteMetaLNTS (pak, META_TAG_FIRST, "<unset>");
288         PacketWriteMetaLNTS (pak, META_TAG_LAST, "<unset>");
289 
290         PacketWrite2 (pak, META_TAG_EMAIL);
291         PacketWriteLen (pak);
292         PacketWriteLNTS (pak, "");
293         PacketWrite1 (pak, 1);
294         PacketWriteLenDone  (pak);
295 
296         PacketWriteMetaLNTS (pak, META_TAG_HOME_CITY, "");
297         PacketWriteMetaLNTS (pak, META_TAG_HOME_STATE, "");
298         PacketWriteMetaLNTS (pak, META_TAG_HOME_PHONE, "");
299         PacketWriteMetaLNTS (pak, META_TAG_HOME_FAX, "");
300         PacketWriteMetaLNTS (pak, META_TAG_HOME_STREET, "");
301         PacketWriteMetaLNTS (pak, META_TAG_HOME_CELL, "");
302         PacketWriteMetaLNTS (pak, META_TAG_HOME_ZIP, "");
303         PacketWriteMeta2    (pak, META_TAG_HOME_CTRY, 0);
304         PacketWriteMeta1    (pak, META_TAG_TZ, 0);
305         PacketWriteMeta1    (pak, META_TAG_WEBAWARE, 0);
306         PacketWriteMeta1    (pak, META_TAG_AUTHREQ, 0);
307     }
308 
309 #if 0
310     PacketWriteMeta1    (pak, 760, 0);
311     PacketWriteMeta1    (pak, 780, 0);
312     PacketWriteMeta4    (pak, 620, 0);
313     PacketWriteMeta2    (pak, 420, 0);
314     PacketWriteMeta1    (pak, 790, -2);
315     PacketWriteMeta2    (pak, 820, 0);
316     PacketWriteMeta2    (pak, 370, 99);
317     PacketWriteMeta2    (pak, 380, 2);
318     PacketWriteMeta2    (pak, 531, 0);
319 
320     PacketWrite2 (pak, 570);
321     PacketWrite2 (pak, 6);
322     PacketWrite2 (pak, 0);
323     PacketWrite2 (pak, 0);
324     PacketWrite2 (pak, 0);
325 
326     PacketWrite2 (pak, 350);
327     PacketWriteLen (pak);
328     PacketWriteLNTS (pak, "email@adresse");
329     PacketWrite1 (pak, 1);
330     PacketWriteLenDone  (pak);
331 
332     PacketWriteMeta4    (pak, 690, 0);
333     PacketWriteMeta2    (pak, 460, 0);
334     PacketWriteMeta4    (pak, 490, 0);
335     PacketWriteMeta4    (pak, 490, 0);
336     PacketWriteMeta4    (pak, 490, 0);
337     PacketWriteMeta4    (pak, 470, 0);
338     PacketWriteMeta4    (pak, 470, 0);
339     PacketWriteMeta4    (pak, 470, 0);
340     PacketWriteMeta4    (pak, 510, 0);
341     PacketWriteMeta4    (pak, 510, 0);
342     PacketWriteMeta4    (pak, 510, 0);
343 #endif
344 
345 #endif
346     SnacMetaSend    (serv, pak);
347     SnacCliSetlastupdate (serv);
348 }
349 
350 /*
351  * CLI_METASETABOUT - SNAC(15,2) - 2000/1030
352  */
353 
SnacCliMetasetabout(Server * serv,const char * text)354 void SnacCliMetasetabout (Server *serv, const char *text)
355 {
356     Packet *pak;
357 #if 0
358     pak = SnacMetaC (serv, 2000, META_SET_ABOUT_INFO, 0);
359     PacketWriteLNTS (pak, c_out (text));
360 #else
361     pak = SnacMetaC (serv, 2000, META_SAVE_INFO, 0);
362     PacketWriteMetaLNTS (pak, META_TAG_ABOUT, c_out (text));
363 #endif
364     SnacMetaSend    (serv, pak);
365     SnacCliSetlastupdate (serv);
366 }
367 
368 /*
369  * CLI_METASETMORE - SNAC(15,2) - 2000/1021
370  */
SnacCliMetasetmore(Server * serv,Contact * cont)371 void SnacCliMetasetmore (Server *serv, Contact *cont)
372 {
373     Packet *pak;
374 
375 #if 0
376     pak = SnacMetaC (serv, 2000, META_SET_MORE_INFO, 0);
377     if (cont->meta_more)
378     {
379         PacketWrite2    (pak, cont->meta_more->age);
380         PacketWrite1    (pak, cont->meta_more->sex);
381         PacketWriteLNTS (pak, c_out (cont->meta_more->homepage));
382         PacketWrite2    (pak, cont->meta_more->year);
383         PacketWrite1    (pak, cont->meta_more->month);
384         PacketWrite1    (pak, cont->meta_more->day);
385         PacketWrite1    (pak, cont->meta_more->lang1);
386         PacketWrite1    (pak, cont->meta_more->lang2);
387         PacketWrite1    (pak, cont->meta_more->lang3);
388     }
389     else
390     {
391         PacketWrite2    (pak, 0);
392         PacketWrite1    (pak, 0);
393         PacketWriteLNTS (pak, "");
394         PacketWrite2    (pak, 0);
395         PacketWrite1    (pak, 0);
396         PacketWrite1    (pak, 0);
397         PacketWrite1    (pak, 0);
398         PacketWrite1    (pak, 0);
399         PacketWrite1    (pak, 0);
400     }
401 #else
402     pak = SnacMetaC (serv, 2000, META_SAVE_INFO, 0);
403     if (cont->meta_more)
404     {
405         PacketWriteMeta2    (pak, META_TAG_AGE, cont->meta_more->age);
406         PacketWriteMeta1    (pak, META_TAG_GENDER, cont->meta_more->sex);
407         PacketWriteMetaLNTS (pak, META_TAG_HP_URL, c_out (cont->meta_more->homepage));
408         PacketWriteMeta6    (pak, META_TAG_BIRTHDAY, cont->meta_more->year, cont->meta_more->month, cont->meta_more->day);
409         PacketWriteMeta1    (pak, META_TAG_LANG, cont->meta_more->lang1);
410         PacketWriteMeta1    (pak, META_TAG_LANG, cont->meta_more->lang2);
411         PacketWriteMeta1    (pak, META_TAG_LANG, cont->meta_more->lang3);
412     }
413     else
414     {
415         PacketWriteMeta2    (pak, META_TAG_AGE, 0);
416         PacketWriteMeta1    (pak, META_TAG_GENDER, 0);
417         PacketWriteMetaLNTS (pak, META_TAG_HP_URL, "");
418         PacketWriteMeta6    (pak, META_TAG_BIRTHDAY, 0, 0, 0);
419         PacketWriteMeta1    (pak, META_TAG_LANG, 0);
420         PacketWriteMeta1    (pak, META_TAG_LANG, 0);
421         PacketWriteMeta1    (pak, META_TAG_LANG, 0);
422     }
423 
424 
425 #endif
426     SnacMetaSend    (serv, pak);
427     SnacCliSetlastupdate (serv);
428 }
429 
430 /*
431  * CLI_METASETPASS - SNAC(15,2) - 2000/1070
432  */
SnacCliMetasetpass(Server * serv,const char * newpass)433 void SnacCliMetasetpass (Server *serv, const char *newpass)
434 {
435     Packet *pak;
436 
437     pak = SnacMetaC (serv, 2000, 1070, 0);
438     PacketWriteLNTS (pak, c_out (newpass));
439     SnacMetaSend    (serv, pak);
440 }
441 
442 /*
443  * CLI_METAREQINFO - SNAC(15,2) - 2000/1202
444  */
SnacCliMetareqmoreinfo(Server * serv,Contact * cont)445 UDWORD SnacCliMetareqmoreinfo (Server *serv, Contact *cont)
446 {
447     Packet *pak;
448     UDWORD ref;
449 
450     pak = SnacMetaC (serv, 2000, 1202, 0);
451     ref = pak->ref;
452     PacketWrite4    (pak, cont->uin);
453     SnacMetaSend    (serv, pak);
454     return ref;
455 }
456 
457 /*
458  * CLI_METAREQINFO - SNAC(15,2) - 2000/1232
459  */
SnacCliMetareqinfo(Server * serv,Contact * cont)460 UDWORD SnacCliMetareqinfo (Server *serv, Contact *cont)
461 {
462     Packet *pak;
463     UDWORD ref;
464 
465     pak = SnacMetaC (serv, 2000, META_REQ_INFO, 0);
466     ref = pak->ref;
467     PacketWrite4    (pak, cont->uin);
468     SnacMetaSend    (serv, pak);
469     return ref;
470 }
471 
472 /*
473  * CLI_SEARCHBYPERSINF - SNAC(15,2) - 2000/1375
474  */
SnacCliSearchbypersinf(Server * serv,const char * email,const char * nick,const char * name,const char * surname)475 void SnacCliSearchbypersinf (Server *serv, const char *email, const char *nick, const char *name, const char *surname)
476 {
477     Packet *pak;
478 
479     pak = SnacMetaC  (serv, 2000, META_SEARCH_PERSINFO, 0);
480     PacketWrite2     (pak, 320); /* key: first name */
481     PacketWriteLLNTS (pak, c_out (name));
482     PacketWrite2     (pak, 330); /* key: last name */
483     PacketWriteLLNTS (pak, c_out (surname));
484     PacketWrite2     (pak, 340); /* key: nick */
485     PacketWriteLLNTS (pak, c_out (nick));
486     PacketWrite2     (pak, 350); /* key: email address */
487     PacketWriteLLNTS (pak, c_out (email));
488     SnacMetaSend     (serv, pak);
489 }
490 
491 /*
492  * CLI_SEARCHBYMAIL - SNAC(15,2) - 2000/{1395,1321}
493  */
SnacCliSearchbymail(Server * serv,const char * email)494 void SnacCliSearchbymail (Server *serv, const char *email)
495 {
496     Packet *pak;
497 
498     pak = SnacMetaC  (serv, 2000, META_SEARCH_EMAIL, 0);
499     PacketWrite2     (pak, 350); /* key: email address */
500     PacketWriteLLNTS (pak, c_out (email));
501     SnacMetaSend     (serv, pak);
502 }
503 
504 /*
505  * CLI_SEARCHRANDOM - SNAC(15,2) - 2000/1870
506  */
SnacCliSearchrandom(Server * serv,UWORD group)507 UDWORD SnacCliSearchrandom (Server *serv, UWORD group)
508 {
509     Packet *pak;
510     UDWORD ref;
511 
512     pak = SnacMetaC (serv, 2000, META_SEARCH_RANDOM, 0);
513     ref = pak->ref;
514     PacketWrite2    (pak, group);
515     SnacMetaSend    (serv, pak);
516     return ref;
517 }
518 
519 /*
520  * CLI_SETRANDOM - SNAC(15,2) - 2000/1880
521  */
SnacCliSetrandom(Server * serv,UWORD group)522 void SnacCliSetrandom (Server *serv, UWORD group)
523 {
524     Packet *pak;
525 
526     pak = SnacMetaC (serv, 2000, META_SET_RANDOM, serv->conn->connect & CONNECT_OK ? 0 : 0x4242);
527     PacketWrite2    (pak, group);
528     if (group)
529     {
530         PacketWriteB4 (pak, 0x00000220);
531         PacketWriteB4 (pak, 0);
532         PacketWriteB4 (pak, 0);
533         PacketWriteB4 (pak, 0);
534         PacketWrite1  (pak, serv->oscar_dc && serv->oscar_dc->connect & CONNECT_OK
535                             ? ServerPrefVal (serv, CO_OSCAR_DC_MODE) & 15 : 0);
536         PacketWrite2  (pak, serv->oscar_dc && serv->oscar_dc->connect & CONNECT_OK
537                             ? serv->oscar_dc->version : 0);
538         PacketWriteB4 (pak, 0);
539         PacketWriteB4 (pak, 0x00005000);
540         PacketWriteB4 (pak, 0x00000300);
541         PacketWrite2  (pak, 0);
542     }
543     SnacMetaSend (serv, pak);
544 }
545 
546 /*
547  * CLI_SEARCHWP - SNAC(15,2) - 2000/1331
548  */
SnacCliSearchwp(Server * serv,const MetaWP * wp)549 void SnacCliSearchwp (Server *serv, const MetaWP *wp)
550 {
551     Packet *pak;
552 
553     pak = SnacMetaC (serv, 2000, META_SEARCH_WP, 0);
554     PacketWriteLNTS    (pak, c_out (wp->first));
555     PacketWriteLNTS    (pak, c_out (wp->last));
556     PacketWriteLNTS    (pak, c_out (wp->nick));
557     PacketWriteLNTS    (pak, c_out (wp->email));
558     PacketWrite2       (pak, wp->minage);
559     PacketWrite2       (pak, wp->maxage);
560     PacketWrite1       (pak, wp->sex);
561     PacketWrite1       (pak, wp->language);
562     PacketWriteLNTS    (pak, c_out (wp->city));
563     PacketWriteLNTS    (pak, c_out (wp->state));
564     PacketWriteB2      (pak, wp->country);
565     PacketWriteLNTS    (pak, c_out (wp->company));
566     PacketWriteLNTS    (pak, c_out (wp->department));
567     PacketWriteLNTS    (pak, c_out (wp->position));
568     PacketWrite1       (pak, 0);    /* occupation); */
569     PacketWriteB2      (pak, 0);    /* past information); */
570     PacketWriteLNTS    (pak, NULL); /* description); */
571     PacketWriteB2      (pak, 0);    /* interests-category); */
572     PacketWriteLNTS    (pak, NULL); /* interests-specification); */
573     PacketWriteB2      (pak, 0);    /* affiliation/organization); */
574     PacketWriteLNTS    (pak, NULL); /* description); */
575     PacketWriteB2      (pak, 0);    /* homepage category); */
576     PacketWriteLNTS    (pak, NULL); /* description); */
577     PacketWrite1       (pak, wp->online);
578     SnacMetaSend (serv, pak);
579 }
580 
581 /*
582  * CLI_SENDSMS - SNAC(15,2) - 2000/5250
583  */
SnacCliSendsms(Server * serv,const char * target,const char * text)584 void SnacCliSendsms (Server *serv, const char *target, const char *text)
585 {
586     Packet *pak;
587     char buf[2000];
588     time_t t = time (NULL);
589 
590     snprintf (buf, sizeof (buf), "<icq_sms_message><destination>%s</destination>"
591              "<text>%s (%s www.climm.org)</text><codepage>utf8</codepage><senders_UIN>%s</senders_UIN>"
592              "<senders_name>%s</senders_name><delivery_receipt>Yes</delivery_receipt>"
593              "<time>%s</time></icq_sms_message>",
594              target, text, serv->screen, serv->screen, "climm",
595              s_strftime (&t, "%a, %d %b %Y %H:%M:%S GMT", 1));
596 
597     pak = SnacMetaC (serv, 2000, META_SEND_SMS, 0);
598     PacketWriteB2      (pak, 1);
599     PacketWriteB2      (pak, 22);
600     PacketWriteB4      (pak, 0);
601     PacketWriteB4      (pak, 0);
602     PacketWriteB4      (pak, 0);
603     PacketWriteB4      (pak, 0);
604     PacketWriteTLVStr  (pak, 0, buf);
605     SnacMetaSend (serv, pak);
606 }
607 
608 /*
609  * SRV_FROMOLDICQ - SNAC(15,3)
610  */
JUMP_SNAC_F(SnacSrvFromicqsrv)611 JUMP_SNAC_F(SnacSrvFromicqsrv)
612 {
613     Server *serv = event->conn->serv;
614     TLV *tlv;
615     Packet *p, *pak;
616     UDWORD len, uin, type /*, id*/;
617 
618     pak = event->pak;
619     tlv = TLVRead (pak, PacketReadLeft (pak), -1);
620     if (tlv[1].str.len < 10)
621     {
622         SnacSrvUnknown (event);
623         TLVD (tlv);
624         return;
625     }
626     p = PacketCreate (&tlv[1].str);
627     p->ref = pak->ref; /* copy reference */
628     len = PacketRead2 (p);
629     uin = PacketRead4 (p);
630     type= PacketRead2 (p);
631 /*  id=*/ PacketRead2 (p);
632     if (uin != serv->oscar_uin)
633     {
634         if (prG->verbose & DEB_PROTOCOL)
635         {
636             rl_printf (i18n (1919, "UIN mismatch: %ld vs %ld.\n"), UD2UL (serv->oscar_uin), UD2UL (uin));
637             SnacSrvUnknown (event);
638         }
639         TLVD (tlv);
640         PacketD (p);
641         return;
642     }
643     else if (len != tlv[1].str.len - 2)
644     {
645         if (prG->verbose & DEB_PROTOCOL)
646         {
647             rl_print (i18n (1743, "Size mismatch in packet lengths.\n"));
648             SnacSrvUnknown (event);
649         }
650         TLVD (tlv);
651         PacketD (p);
652         return;
653     }
654 
655     TLVD (tlv);
656     switch (type)
657     {
658         case 65:
659             if (len >= 14)
660                 Recv_Message (serv, p);
661             break;
662 
663         case 66:
664             SnacCliAckofflinemsgs (serv);
665             break;
666 
667         case 2010:
668             Meta_User (serv, ContactUIN (serv, uin), p);
669             break;
670 
671         default:
672             SnacSrvUnknown (event);
673             break;
674     }
675     PacketD (p);
676 }
677 
678 #define META_SRV_GEN_UPDATE     100
679 #define META_SRV_OTHER_UPDATE   120
680 #define META_SRV_ABOUT_UPDATE   130
681 #define META_SRV_SMS_OK         150
682 #define META_SRV_PASS_UPDATE    170
683 #define META_SRV_GEN            200
684 #define META_SRV_WORK           210
685 #define META_SRV_MORE           220
686 #define META_SRV_ABOUT          230
687 #define META_SRV_INTEREST       240
688 #define META_SRV_BACKGROUND     250
689 #define META_SRV_MOREEMAIL      235
690 #define META_SRV_INFO           260
691 #define META_SRV_UNKNOWN_270    270
692 #define META_SRV_WP_FOUND       420
693 #define META_SRV_WP_LAST_USER   430
694 #define META_SRV_RANDOM         870
695 #define META_SRV_RANDOM_UPDATE  880
696 #define META_SRV_METATLV_UPDATE 3135
697 
Auto_Reply(Server * serv,Contact * cont)698 void Auto_Reply (Server *serv, Contact *cont)
699 {
700     const char *temp = NULL;
701 
702     if (!(prG->flags & FLAG_AUTOREPLY) || !cont)
703         return;
704 
705     switch (ContactClearInv (cont->status))
706     {
707         case imr_dnd:  temp = ContactPrefStr (cont, CO_TAUTODND);  break;
708         case imr_occ:  temp = ContactPrefStr (cont, CO_TAUTOOCC);  break;
709         case imr_na:   temp = ContactPrefStr (cont, CO_TAUTONA);   break;
710         case imr_away: temp = ContactPrefStr (cont, CO_TAUTOAWAY); break;
711         case imr_ffc:  temp = ContactPrefStr (cont, CO_TAUTOFFC);  break;
712         case imr_offline: return;
713         case imr_online:
714             if (ContactIsInv (cont->status))
715                        temp = ContactPrefStr (cont, CO_TAUTOINV);
716             else
717                 return;
718     }
719 
720     if (!temp || !*temp)
721     {
722         switch (ContactClearInv (cont->status))
723         {
724             case imr_dnd:  temp = ContactPrefStr (cont, CO_AUTODND);  break;
725             case imr_occ:  temp = ContactPrefStr (cont, CO_AUTOOCC);  break;
726             case imr_na:   temp = ContactPrefStr (cont, CO_AUTONA);   break;
727             case imr_away: temp = ContactPrefStr (cont, CO_AUTOAWAY); break;
728             case imr_ffc:  temp = ContactPrefStr (cont, CO_AUTOFFC);  break;
729             case imr_offline: assert (0);
730             case imr_online:
731                 assert (ContactIsInv (cont->status));
732                            temp = ContactPrefStr (cont, CO_AUTOINV);
733         }
734     }
735 
736     IMCliMsg (cont, MSG_AUTO, temp, NULL);
737 }
738 
739 #define s_read(s) s_repl (&s, ConvFromCont (PacketReadL2Str (pak, NULL), cont))
740 
Meta_Read_List(Packet * pak,ContactMeta ** list,Contact * cont)741 static BOOL Meta_Read_List (Packet *pak, ContactMeta **list, Contact *cont)
742 {
743     UBYTE i, j;
744     UWORD data;
745     const char *text;
746 
747     i = PacketRead1 (pak);
748     ContactMetaD (*list);
749     *list = NULL;
750     for (j = 0; j < i; j++)
751     {
752         data = PacketRead2 (pak);
753         text = ConvFromCont (PacketReadL2Str (pak, NULL), cont);
754         if (data && text && *text)
755             ContactMetaAdd (list, data, text);
756     }
757     return TRUE;
758 }
759 
Meta_User(Server * serv,Contact * cont,Packet * pak)760 void Meta_User (Server *serv, Contact *cont, Packet *pak)
761 {
762     UWORD subtype;
763     UDWORD result;
764     Event *event = NULL;
765 
766     if (!cont)
767         return;
768     subtype = PacketRead2 (pak);
769     result  = PacketRead1 (pak);
770 
771     switch (subtype)
772     {
773         case META_SRV_PASS_UPDATE:
774             rl_printf (i18n (2136, "Password change was %s%s%s.\n"),
775                      COLCLIENT, result == META_SUCCESS ? i18n (1393, "successful")
776                      : i18n (1394, "unsuccessful"), COLNONE);
777             break;
778         case META_SRV_ABOUT_UPDATE:
779             rl_printf (i18n (2137, "About info change was %s%s%s.\n"),
780                      COLCLIENT, result == META_SUCCESS ? i18n (1393, "successful")
781                      : i18n (1394, "unsuccessful"), COLNONE);
782             break;
783         case META_SRV_GEN_UPDATE:
784             rl_printf (i18n (2138, "Info change was %s%s%s.\n"),
785                      COLCLIENT, result == META_SUCCESS ? i18n (1393, "successful")
786                      : i18n (1394, "unsuccessful"), COLNONE);
787             break;
788         case META_SRV_OTHER_UPDATE:
789             rl_printf (i18n (2139, "Other info change was %s%s%s.\n"),
790                      COLCLIENT, result == META_SUCCESS ? i18n (1393, "successful")
791                      : i18n (1394, "unsuccessful"), COLNONE);
792             break;
793         case META_SRV_RANDOM_UPDATE:
794             if ((pak->ref & 0xffff) != 0x4242)
795                 rl_printf (i18n (2140, "Random chat group change was %s%s%s.\n"),
796                          COLCLIENT, result == META_SUCCESS ? i18n (1393, "successful")
797                          : i18n (1394, "unsuccessful"), COLNONE);
798             break;
799         case META_SRV_METATLV_UPDATE:
800             rl_printf (i18n (2690, "Meta info change was %s%s%s.\n"),
801                      COLCLIENT, result == META_SUCCESS ? i18n (1393, "successful")
802                      : i18n (1394, "unsuccessful"), COLNONE);
803             break;
804     }
805 
806     switch (result) /* default error handling */
807     {
808         case 0x32:
809         case 0x14:
810             if ((event = QueueDequeue (serv->conn, QUEUE_REQUEST_META, pak->ref)))
811                 EventD (event);
812             rl_printf ("%s ", s_now);
813             rl_printf (i18n (2141, "Search %sfailed%s.\n"), COLCLIENT, COLNONE);
814             return;
815         case META_READONLY:
816             rl_printf ("%s %s\n", s_now, i18n (1900, "It's readonly."));
817             return;
818         case META_SUCCESS:
819             break;
820         case 0x46:
821             rl_printf ("%s\n", pak->data + pak->rpos);
822             return;
823         default:
824             rl_printf (i18n (1940, "Unknown Meta User result %lx.\n"), UD2UL (result));
825             return;
826     }
827 
828     switch (subtype)
829     {
830         case META_SRV_ABOUT_UPDATE:
831         case META_SRV_OTHER_UPDATE:
832         case META_SRV_GEN_UPDATE:
833         case META_SRV_PASS_UPDATE:
834         case META_SRV_RANDOM_UPDATE:
835         case META_SRV_METATLV_UPDATE:
836             return;
837         case META_SRV_INFO:
838         case META_SRV_GEN:
839         case META_SRV_MORE:
840         case META_SRV_MOREEMAIL:
841         case META_SRV_WORK:
842         case META_SRV_ABOUT:
843         case META_SRV_INTEREST:
844         case META_SRV_BACKGROUND:
845         case META_SRV_UNKNOWN_270:
846         case META_SRV_RANDOM:
847             if (!(event = QueueDequeue (serv->conn, QUEUE_REQUEST_META, pak->ref)) || !event->callback)
848             {
849                 if (prG->verbose)
850                     rl_printf ("FIXME: meta reply ref %lx not found.\n", UD2UL (pak->ref));
851                 return;
852             }
853 
854             if (event->cont)
855                 cont = event->cont;
856     }
857 
858     switch (subtype)
859     {
860         strc_t data;
861         UWORD wdata, i, j;
862         UDWORD dwdata, uin;
863         MetaGeneral *mg;
864         MetaMore *mm;
865         MetaWork *mw;
866         MetaObsolete *mo;
867 
868         case META_SRV_SMS_OK:
869                    PacketRead4 (pak);
870                    PacketRead2 (pak);
871                    PacketReadB2Str (pak, NULL);
872             data = PacketReadB2Str (pak, NULL);
873             rl_printf (i18n (2080, "Server SMS delivery response:\n%s\n"), ConvFromServ (data));
874             break;
875         case META_SRV_INFO:
876             Display_Info_Reply (cont, pak, 0);
877             /* 3 unknown bytes ignored */
878 
879             event->callback (event);
880             break;
881         case META_SRV_GEN:
882             Display_Info_Reply (cont, pak, 0);
883 
884             if (!(mg = CONTACT_GENERAL (cont)))
885                 break;
886 
887             s_read (mg->city);
888             s_read (mg->state);
889             s_read (mg->phone);
890             s_read (mg->fax);
891             s_read (mg->street);
892             s_read (mg->cellular);
893             if (serv->type == TYPE_SERVER)
894                 s_read (mg->zip);
895             else
896             {
897                 dwdata = PacketRead4 (pak);
898                 s_repl (&mg->zip, dwdata ? s_sprintf ("%ld", UD2UL (dwdata)) : "");
899             }
900             mg->country = PacketRead2 (pak);
901             mg->tz      = PacketRead1 (pak);
902             mg->auth    = PacketRead1 (pak);
903             /* one unknown word ignored according to v7 doc */
904             /* probably more security settings? */
905 
906             cont->updated |= UPF_GENERAL_B;
907             event->callback (event);
908             break;
909         case META_SRV_MORE:
910             if (!(mm = CONTACT_MORE (cont)))
911                 break;
912 
913             mm->age = PacketRead2 (pak);
914             mm->sex = PacketRead1 (pak);
915             s_read (mm->homepage);
916             mm->year  = PacketRead2 (pak);
917             mm->month = PacketRead1 (pak);
918             mm->day   = PacketRead1 (pak);
919             mm->lang1 = PacketRead1 (pak);
920             mm->lang2 = PacketRead1 (pak);
921             mm->lang3 = PacketRead1 (pak);
922             /* one unknown word ignored according to v7 doc */
923 
924             cont->updated |= UPF_MORE;
925             event->callback (event);
926             break;
927         case META_SRV_MOREEMAIL:
928             ContactMetaD (cont->meta_email);
929             cont->meta_email = NULL;
930             if ((i = PacketRead1 (pak)))
931             {
932                 for (j = 0; j < i; j++)
933                 {
934                     int auth = PacketRead1 (pak);
935                     ContactMetaAdd (&cont->meta_email, auth, ConvFromCont (PacketReadL2Str (pak, NULL), cont));
936                 }
937             }
938             cont->updated |= UPF_EMAIL;
939             event->callback (event);
940             break;
941         case META_SRV_WORK:
942             if (!(mw = CONTACT_WORK (cont)))
943                 break;
944 
945             s_read (mw->wcity);
946             s_read (mw->wstate);
947             s_read (mw->wphone);
948             s_read (mw->wfax);
949             s_read (mw->waddress);
950             if (serv->type == TYPE_SERVER)
951                 s_read (mw->wzip);
952             else
953             {
954                 dwdata = PacketRead4 (pak);
955                 s_repl (&mw->wzip, dwdata ? s_sprintf ("%ld", UD2UL (dwdata)) : "");
956             }
957             mw->wcountry = PacketRead2 (pak);
958             s_read (mw->wcompany);
959             s_read (mw->wdepart);
960             s_read (mw->wposition);
961             mw->woccupation = PacketRead2 (pak);
962             s_read (mw->whomepage);
963 
964             cont->updated |= UPF_WORK;
965             event->callback (event);
966             break;
967         case META_SRV_ABOUT:
968             s_read (cont->meta_about);
969             cont->updated |= UPF_ABOUT;
970             event->callback (event);
971             break;
972         case META_SRV_INTEREST:
973             if (!Meta_Read_List (pak, &cont->meta_interest, cont))
974                 break;
975 
976             cont->updated |= UPF_INTEREST;
977             event->callback (event);
978             break;
979         case META_SRV_BACKGROUND:
980             if (!Meta_Read_List (pak, &cont->meta_background, cont))
981                 break;
982             if (!Meta_Read_List (pak, &cont->meta_affiliation, cont))
983                 break;
984 
985             cont->updated |= UPF_BACKGROUND | UPF_AFFILIATION;
986             event->callback (event);
987             break;
988         case META_SRV_WP_FOUND:
989         case META_SRV_WP_LAST_USER:
990             if (PacketRead2 (pak) < 19)
991             {
992                 rl_printf (i18n (2141, "Search %sfailed%s.\n"), COLCLIENT, COLNONE);
993                 break;
994             }
995             cont = ContactUIN (serv, PacketRead4 (pak));
996             if (!cont || !(mg = CONTACT_GENERAL (cont)) || !(mm = CONTACT_MORE (cont)))
997                 break;
998 
999             Display_Info_Reply (cont, pak, IREP_HASAUTHFLAG);
1000             mg->webaware = PacketRead2 (pak);
1001             mm->sex = PacketRead1 (pak);
1002             mm->age = PacketRead2 (pak);
1003 
1004             cont->updated |= UPF_GENERAL_C;
1005 
1006             UtilUIDisplayMeta (cont);
1007             PacketRead2 (pak);
1008             if (subtype == META_SRV_WP_LAST_USER && (wdata = PacketRead2 (pak)))
1009                 rl_printf ("%u %s\n", wdata, i18n (1621, "users not returned."));
1010             break;
1011         case META_SRV_RANDOM:
1012             uin = PacketRead4 (pak);
1013             event->cont = cont = ContactUIN (serv, uin);
1014             wdata = PacketRead2 (pak);
1015             rl_printf (i18n (2606, "Found random chat partner UIN %s in chat group %d.\n"),
1016                       cont->screen, wdata);
1017             if (!cont || !CONTACT_DC (cont))
1018                 break;
1019             if (~cont->updated & UP_INFO)
1020             {
1021                 if (serv->type == TYPE_SERVER)
1022                     event->seq = SnacCliMetareqinfo (serv, cont);
1023             }
1024             event->callback (event);
1025             cont->dc->ip_rem  = PacketReadB4 (pak);
1026             cont->dc->port    = PacketRead4  (pak);
1027             cont->dc->ip_loc  = PacketReadB4 (pak);
1028             cont->dc->type    = PacketRead1  (pak);
1029             cont->dc->version = PacketRead2  (pak);
1030             /* 14 unknown bytes ignored */
1031             break;
1032         case META_SRV_UNKNOWN_270:
1033             /* ignored - obsoleted as of ICQ 2002 */
1034             if (!(mo = CONTACT_OBSOLETE (cont)))
1035                 break;
1036 
1037             if ((mo->given = PacketRead1 (pak)))
1038             {
1039                 mo->unknown = PacketReadB2 (pak);
1040                 s_read (mo->description);
1041             }
1042             mo->empty = PacketRead1 (pak);
1043 
1044             cont->updated |= UPF_OBSOLETE;
1045             event->callback (event);
1046             break;
1047         default:
1048             rl_printf ("%s: %s%04x%s\n",
1049                      i18n (1945, "Unknown Meta User response"), COLSERVER, subtype, COLNONE);
1050             rl_print  (s_dump (pak->data + pak->rpos, pak->len - pak->rpos));
1051             break;
1052     }
1053 }
1054 
Display_Info_Reply(Contact * cont,Packet * pak,UBYTE flags)1055 void Display_Info_Reply (Contact *cont, Packet *pak, UBYTE flags)
1056 {
1057     MetaGeneral *mg;
1058 
1059     if (!(mg = CONTACT_GENERAL (cont)))
1060         return;
1061 
1062     s_read (mg->nick);
1063     s_read (mg->first);
1064     s_read (mg->last);
1065     s_read (mg->email);
1066     mg->auth = (flags & IREP_HASAUTHFLAG) ? PacketRead1 (pak) : 0;
1067 
1068     cont->updated |= UPF_GENERAL_A;
1069 }
1070 
Display_Ext_Info_Reply(Server * serv,Packet * pak)1071 void Display_Ext_Info_Reply (Server *serv, Packet *pak)
1072 {
1073     Contact *cont;
1074     MetaGeneral *mg;
1075     MetaMore *mm;
1076 
1077     if (!(cont = ContactUIN (serv, PacketRead4 (pak))))
1078         return;
1079 
1080     if (!(mg = CONTACT_GENERAL (cont)) || !(mm = CONTACT_MORE (cont)))
1081         return;
1082 
1083     s_read (mg->city);
1084     mg->country = PacketRead2 (pak);
1085     mg->tz      = PacketRead1 (pak);
1086     s_read (mg->state);
1087     mm->age     = PacketRead2 (pak);
1088     mm->sex     = PacketRead1 (pak);
1089     s_read (mg->phone);
1090     s_read (mg->fax);
1091     s_read (mm->homepage);
1092     s_read (cont->meta_about);
1093 
1094     cont->updated |= UPF_GENERAL_E;
1095 
1096     UtilUIDisplayMeta (cont);
1097 }
1098 
Recv_Message(Server * serv,Packet * pak)1099 void Recv_Message (Server *serv, Packet *pak)
1100 {
1101     struct tm stamp;
1102     Contact *cont;
1103     strc_t ctext;
1104     const char *text;
1105     UDWORD uin;
1106     UWORD type, len;
1107 
1108     uin            = PacketRead4 (pak);
1109     stamp.tm_sec   = 0;
1110     stamp.tm_year  = PacketRead2 (pak) - 1900;
1111     stamp.tm_mon   = PacketRead1 (pak) - 1;
1112     stamp.tm_mday  = PacketRead1 (pak);
1113     stamp.tm_hour  = PacketRead1 (pak);
1114     stamp.tm_min   = PacketRead1 (pak);
1115     stamp.tm_isdst = -1;
1116     type           = PacketRead2 (pak);
1117     len            = PacketReadAt2 (pak, pak->rpos);
1118     ctext          = PacketReadL2Str (pak, NULL);
1119 
1120     cont = ContactUIN (serv, uin);
1121     if (!cont)
1122         return;
1123 
1124     if (len == ctext->len + 1 && ConvIsUTF8 (ctext->txt))
1125         text = ConvFrom (ctext, ENC_UTF8)->txt;
1126     else if (len == ctext->len + 10 || len == strlen (ctext->txt) + 2)
1127         /* work around bug in Miranda < 0.3.1 */
1128         text = type == MSG_NORM ? ConvFromCont (ctext, cont) : c_in_to_split (ctext, cont);
1129     else if (len != ctext->len + 1 && type == MSG_NORM && len & 1)
1130         text = ConvFrom (ctext, ENC_UCS2BE)->txt;
1131     else
1132         text = type == MSG_NORM ? ConvFromCont (ctext, cont) : c_in_to_split (ctext, cont);
1133 
1134     uiG.last_rcvd = cont;
1135     IMSrvMsg (cont, timegm (&stamp), CV_ORIGIN_v5, type, text);
1136 }
1137