root/climm/src/oscar_service.c

Revision 2825, 10.7 kB (checked in by kuhlmann, 1 year ago)

ignore families 36 and 37 - whatever service they may provide

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2  * Handles incoming and creates outgoing SNAC packets
3  * for the family 1 (service) 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$
31  */
32
33 #include "climm.h"
34 #include "oscar_base.h"
35 #include "oscar_tlv.h"
36 #include "oscar_snac.h"
37 #include "oscar_service.h"
38 #include "oscar_location.h"
39 #include "oscar_contact.h"
40 #include "oscar_icbm.h"
41 #include "oscar_bos.h"
42 #include "oscar_roster.h"
43 #include "oscar_oldicq.h"
44 #include "packet.h"
45 #include "contact.h"
46 #include "connection.h"
47 #include "preferences.h"
48 #include "buildmark.h"
49 #include "util_ui.h"
50 #include "util_rl.h"
51 #include <assert.h>
52
53 static void SrvCallBackKeepalive (Event *event);
54
55 static SNAC SNACv[] = {
56     {  1,  4, NULL, NULL},
57     {  2,  1, NULL, NULL},
58     {  3,  1, NULL, NULL},
59     {  4,  1, NULL, NULL},
60     {  6,  1, NULL, NULL},
61     {  8,  0, NULL, NULL},
62     {  9,  1, NULL, NULL},
63     { 10,  1, NULL, NULL},
64     { 11,  1, NULL, NULL},
65     { 12,  1, NULL, NULL},
66     { 19,  4, NULL, NULL}, /* 5 */
67     { 21,  1, NULL, NULL},
68     { 34,  0, NULL, NULL},
69     { 36,  0, NULL, NULL},
70     { 37,  0, NULL, NULL},
71     {  0,  0, NULL, NULL}
72 };
73
74
75 /*
76  * Keeps track of sending a keep alive every 30 seconds.
77  */
78 static void SrvCallBackKeepalive (Event *event)
79 {
80     if (!event || !event->conn)
81     {
82         EventD (event);
83         return;
84     }
85     ASSERT_SERVER_CONN (event->conn);
86     if (event->conn->connect & CONNECT_OK)
87     {
88         FlapCliKeepalive (event->conn->serv);
89         event->due = time (NULL) + 30;
90         QueueEnqueue (event);
91         return;
92     }
93     EventD (event);
94 }
95
96 void CliFinishLogin (Server *serv)
97 {
98     Event *event;
99
100     /* Step 4: (13,6)=(19,6) received */
101     serv->conn->connect += 16;
102     /* SnacCliAddcontact (serv, NULL, serv->contacts); */
103     SnacCliSetstatus (serv, serv->status, 3);
104     SnacCliReady (serv);
105     SnacCliReqofflinemsgs (serv);
106     if (prG->chat > 0)
107         SnacCliSetrandom (serv, prG->chat);
108     serv->conn->connect = CONNECT_OK | CONNECT_SELECT_R;
109     QueueEnqueueData (serv->conn, QUEUE_SRV_KEEPALIVE, 0, time (NULL) + 30,
110         NULL, serv->conn->cont, NULL, &SrvCallBackKeepalive);
111     if ((event = QueueDequeue2 (serv->conn, QUEUE_DEP_WAITLOGIN, 0, NULL)))
112     {
113         event->due = time (NULL) + 5;
114         QueueEnqueue (event);
115     }
116 }
117
118 /*
119  * SRV_SERVICEERR - SNAC(1,1)
120  */
121 JUMP_SNAC_F (SnacSrvServiceerr)
122 {
123     UWORD err;
124     TLV *tlv;
125    
126     err = PacketReadB2 (event->pak);
127     tlv = TLVRead (event->pak, PacketReadLeft (event->pak), -1);
128    
129     if (tlv[8].str.len)
130         DebugH (DEB_PROTOCOL, "Server returned error code %d, sub code %ld for service family.", err, UD2UL (tlv[8].nr));
131     else
132         DebugH (DEB_PROTOCOL, "Server returned error %d for service family.", err);
133     TLVD (tlv);
134 }
135
136 /*
137  * CLI_READY - SNAC(1,2)
138  */
139 void SnacCliReady (Server *serv)
140 {
141     Packet *pak;
142     SNAC *s;
143
144     pak = SnacC (serv, 1, 2, 0, 0);
145    
146     for (s = SNACv; s->fam; s++)
147     {
148         if (!s->cmd || s->fam == 12)
149             continue;
150
151         PacketWriteB2 (pak, s->fam);
152         PacketWriteB2 (pak, s->cmd);
153         PacketWriteB4 (pak, s->fam == 2 ? 0x0101047B : 0x0110047B);
154     }
155     SnacSend (serv, pak);
156 }
157
158 /*
159  * SRV_FAMILIES - SNAC(1,3)
160  */
161 JUMP_SNAC_F(SnacSrvFamilies)
162 {
163     Server *serv = event->conn->serv;
164     Packet *pak;
165     SNAC *s;
166     UWORD fam;
167
168     pak = event->pak;
169     while (PacketReadLeft (pak) >= 2)
170     {
171         fam = PacketReadB2 (pak);
172        
173         for (s = SNACv; s->fam; s++)
174             if (s->fam == fam && !s->f)
175                 break;
176         if (!s->fam)
177         {
178             rl_printf (i18n (1899, "Unknown family requested: %d\n"), fam);
179             continue;
180         }
181     }
182     if (serv->conn->connect & CONNECT_OK)
183         return;
184     /* Step 1: (1,3) received) */
185     serv->conn->connect += 16;
186     SnacCliFamilies (serv);
187     SnacCliRatesrequest (serv); /* triggers step 2 */
188 }
189
190 /*
191  * SRV_RATES - SNAC(1,7)
192  * CLI_ACKRATES - SNAC(1,8)
193  */
194 JUMP_SNAC_F(SnacSrvRates)
195 {
196     Server *serv = event->conn->serv;
197     UWORD nr, grp;
198     Packet *pak;
199    
200     pak = SnacC (serv, 1, 8, 0, 0);
201     nr = PacketReadB2 (event->pak); /* ignore the remainder */
202     while (nr--)
203     {
204         grp = PacketReadB2 (event->pak);
205         event->pak->rpos += 33;
206         PacketWriteB2 (pak, grp);
207     }
208     SnacSend (serv, pak);
209 }
210
211
212 /*
213  * SRV_RATEEXCEEDED - SNAC(1,10)
214  */
215 JUMP_SNAC_F(SnacSrvRateexceeded)
216 {
217     Packet *pak = event->pak;
218     UWORD code = PacketReadB2 (pak);
219     if (code != 1)
220         rl_print (i18n (2188, "You're sending data too fast - stop typing now, or the server will disconnect!\n"));
221 }
222
223 /*
224  * SRV_SERVERPAUSE - SNAC(1,11)
225  * SRV_MIGRATIONREQ - SNAC(1,18)
226  */
227 JUMP_SNAC_F(SnacServerpause)
228 {
229     Server *serv = event->conn->serv;
230     ContactGroup *cg = serv->contacts;
231     Contact *cont;
232     int i;
233
234 #ifdef WIP
235     rl_printf ("%s WIP: reconnecting because of serverpause.\n", s_time (NULL));
236 #endif
237     OscarLogin (serv);
238     for (i = 0; (cont = ContactIndex (cg, i)); i++)
239         cont->status = ims_offline;
240 }
241
242 /*
243  * SRV_MOTD - SNAC(1,13)
244  */
245 JUMP_SNAC_F(SnacSrvMotd)
246 {
247     /* ignore */
248 }
249
250 /*
251  * SRV_REPLYINFO - SNAC(1,15)
252  */
253 JUMP_SNAC_F(SnacSrvReplyinfo)
254 {
255     Server *serv = event->conn->serv;
256     Contact *cont;
257     Packet *pak;
258     TLV *tlv;
259     UDWORD ostat, tlvc;
260     status_t status;
261    
262     pak = event->pak;
263     cont = PacketReadCont (pak, serv);
264    
265     if (strcmp (cont->screen, serv->screen))
266         rl_printf (i18n (2609, "Warning: Server thinks our UIN is %s, when it is %s.\n"),
267                   cont->screen, serv->screen);
268     PacketReadB2 (pak);
269     tlvc = PacketReadB2 (pak);
270     tlv = TLVRead (pak, PacketReadLeft (pak), tlvc);
271     if (tlv[10].str.len)
272     {
273         serv->conn->our_outside_ip = tlv[10].nr;
274         if (prG->verbose)
275             rl_printf (i18n (1915, "Server says we're at %s.\n"), s_ip (serv->conn->our_outside_ip));
276     }
277     if (tlv[6].str.len)
278     {
279         ostat = tlv[6].nr;
280         status = IcqToStatus (ostat);
281         if (status != serv->status)
282         {
283             serv->status = status;
284             serv->nativestatus = ostat;
285             ReadLinePromptReset ();
286             rl_printf ("%s %s\n", s_now, s_status (serv->status, ostat));
287         }
288     }
289     /* TLV 1 c f 2 3 ignored */
290     TLVD (tlv);
291 }
292
293 /*
294  * CLI_FAMILIES - SNAC(1,17)
295  */
296 void SnacCliFamilies (Server *serv)
297 {
298     Packet *pak;
299     SNAC *s;
300
301     pak = SnacC (serv, 1, 0x17, 0, 0);
302    
303     for (s = SNACv; s->fam; s++)
304     {
305         if (!s->cmd || s->fam == 12)
306             continue;
307
308         PacketWriteB2 (pak, s->fam);
309         PacketWriteB2 (pak, s->cmd);
310     }
311     SnacSend (serv, pak);
312 }
313
314 /*
315  * SRV_FAMILIES2 - SNAC(1,18)
316  */
317 JUMP_SNAC_F(SnacSrvFamilies2)
318 {
319     Server *serv = event->conn->serv;
320     Packet *pak;
321     SNAC *s;
322     UWORD fam, ver;
323    
324     pak = event->pak;
325     while (PacketReadLeft (pak) >= 4)
326     {
327         fam = PacketReadB2 (pak);
328         ver = PacketReadB2 (pak);
329         for (s = SNACv; s->fam; s++)
330             if (s->fam == fam)
331                 break;
332         if (!s->fam)
333             continue;
334         if (s->cmd > ver)
335             rl_printf (i18n (1904, "Server doesn't understand ver %d (only %d) for family %d!\n"), s->cmd, ver, fam);
336     }
337
338     if (serv->conn->connect & CONNECT_OK)
339         return;
340     /* Step 2: (1,24)=(1,18) received */
341     serv->conn->connect += 16;
342     SnacCliReqlocation  (serv);
343     SnacCliReqbuddy     (serv);
344     SnacCliReqicbm      (serv);
345     SnacCliReqinfo      (serv);
346     SnacCliReqbos       (serv); /* triggers step 3 */
347 }
348
349 /*
350  * CLI_SETSTATUS - SNAC(1,1E)
351  *
352  * action: 1 = send status 2 = send connection info (3 = both)
353  */
354 void SnacCliSetstatus (Server *serv, status_t status, UWORD action)
355 {
356     Packet *pak;
357     UDWORD ostat = IcqFromStatus (status);
358     statusflag_t flags = imf_none;
359    
360     if (ConnectionPrefVal (serv, CO_WEBAWARE))
361         flags |= imf_web;
362     if (ConnectionPrefVal (serv, CO_DCAUTH))
363         flags |= imf_dcauth;
364     if (ConnectionPrefVal (serv, CO_DCCONT))
365         flags |= imf_dccont;
366    
367     ostat |= IcqFromFlags (flags);
368    
369     if (serv->oscar_privacy_value != 1 && serv->oscar_privacy_value != 2 && serv->oscar_privacy_value != 5)
370     {
371         if (ContactIsInv (status) && serv->oscar_privacy_value != 3)
372             SnacCliSetvisibility (serv, 3, 0);
373         else if (!ContactIsInv (status) && serv->oscar_privacy_value != 4)
374             SnacCliSetvisibility (serv, 4, 0);
375     }
376    
377     pak = SnacC (serv, 1, 0x1e, 0, 0);
378     if ((action & 1) && ContactIsInv (status))
379         SnacCliAddvisible (serv, 0);
380     if (action & 1)
381         PacketWriteTLV4 (pak, 6, ostat);
382     if (action & 2)
383     {
384         PacketWriteB2 (pak, 0x0c); /* TLV 0C */
385         PacketWriteB2 (pak, 0x25);
386         PacketWriteB4 (pak, ConnectionPrefVal (serv, CO_HIDEIP) ? 0 : serv->conn->our_local_ip);
387         if (serv->oscar_dc && serv->oscar_dc->connect & CONNECT_OK)
388         {
389             PacketWriteB4 (pak, serv->oscar_dc->port);
390             PacketWrite1  (pak, ConnectionPrefVal (serv, CO_OSCAR_DC_MODE) & 15);
391             PacketWriteB2 (pak, serv->oscar_dc->version);
392             PacketWriteB4 (pak, serv->oscar_dc->oscar_our_session);
393         }
394         else
395         {
396             PacketWriteB4 (pak, 0);
397             PacketWrite1  (pak, 1);
398             PacketWriteB2 (pak, 8);
399             PacketWriteB4 (pak, 0);
400         }
401         PacketWriteB2 (pak, 0);
402         PacketWriteB2 (pak, 80);
403         PacketWriteB2 (pak, 0);
404         PacketWriteB2 (pak, 3);
405         PacketWriteB4 (pak, BUILD_CLIMM);
406         PacketWriteB4 (pak, BuildVersionNum);
407         PacketWriteB4 (pak, BuildPlatformID);
408         PacketWriteB2 (pak, 0);
409         PacketWriteTLV2 (pak, 8, 0);
410     }
411     SnacSend (serv, pak);
412     if ((action & 1) && !ContactIsInv (status))
413         SnacCliAddinvis (serv, 0);
414 }
Note: See TracBrowser for help on using the browser.