| 42 #endif |
38 #endif |
| 43 |
39 |
| 44 /** |
40 /** |
| 45 * In OSCAR, every connection has a set of SNAC groups associated |
41 * In OSCAR, every connection has a set of SNAC groups associated |
| 46 * with it. These are the groups that you can send over this connection |
42 * with it. These are the groups that you can send over this connection |
| 47 * without being guaranteed a "Not supported" SNAC error. |
43 * without being guaranteed a "Not supported" SNAC error. |
| 48 * |
44 * |
| 49 * The grand theory of things says that these associations transcend |
45 * The grand theory of things says that these associations transcend |
| 50 * what libfaim calls "connection types" (conn->type). You can probably |
46 * what libfaim calls "connection types" (conn->type). You can probably |
| 51 * see the elegance here, but since I want to revel in it for a bit, you |
47 * see the elegance here, but since I want to revel in it for a bit, you |
| 52 * get to hear it all spelled out. |
48 * get to hear it all spelled out. |
| 53 * |
49 * |
| 54 * So let us say that you have your core BOS connection running. One |
50 * So let us say that you have your core BOS connection running. One |
| 55 * of your modules has just given you a SNAC of the group 0x0004 to send |
51 * of your modules has just given you a SNAC of the group 0x0004 to send |
| 56 * you. Maybe an IM destined for some twit in Greenland. So you start |
52 * you. Maybe an IM destined for some twit in Greenland. So you start |
| 57 * at the top of your connection list, looking for a connection that |
53 * at the top of your connection list, looking for a connection that |
| 58 * claims to support group 0x0004. You find one. Why, that neat BOS |
54 * claims to support group 0x0004. You find one. Why, that neat BOS |
| 59 * connection of yours can do that. So you send it on its way. |
55 * connection of yours can do that. So you send it on its way. |
| 60 * |
56 * |
| 61 * Now, say, that fellow from Greenland has friends and they all want to |
57 * Now, say, that fellow from Greenland has friends and they all want to |
| 62 * meet up with you in a lame chat room. This has landed you a SNAC |
58 * meet up with you in a lame chat room. This has landed you a SNAC |
| 70 * marked the need for a connection supporting group 0x000e. A few seconds |
66 * marked the need for a connection supporting group 0x000e. A few seconds |
| 71 * later, you receive a service redirect with an IP address and a cookie in |
67 * later, you receive a service redirect with an IP address and a cookie in |
| 72 * it. Great, you say. Now I have something to do. Off you go, making |
68 * it. Great, you say. Now I have something to do. Off you go, making |
| 73 * that connection. One of the first things you get from this new server |
69 * that connection. One of the first things you get from this new server |
| 74 * is a message saying that indeed it does support the group you were looking |
70 * is a message saying that indeed it does support the group you were looking |
| 75 * for. So you continue and send rate confirmation and all that. |
71 * for. So you continue and send rate confirmation and all that. |
| 76 * |
72 * |
| 77 * Then you remember you had that SNAC to send, and now you have a means to |
73 * Then you remember you had that SNAC to send, and now you have a means to |
| 78 * do it, and you do, and everyone is happy. Except the Greenlander, who is |
74 * do it, and you do, and everyone is happy. Except the Greenlander, who is |
| 79 * still stuck in the bitter cold. |
75 * still stuck in the bitter cold. |
| 80 * |
76 * |
| 81 * Oh, and this is useful for building the Migration SNACs, too. In the |
77 * Oh, and this is useful for building the Migration SNACs, too. In the |
| 84 * |
80 * |
| 85 * Just to make me look better, I'll say that I've known about this great |
81 * Just to make me look better, I'll say that I've known about this great |
| 86 * scheme for quite some time now. But I still haven't convinced myself |
82 * scheme for quite some time now. But I still haven't convinced myself |
| 87 * to make libfaim work that way. It would take a fair amount of effort, |
83 * to make libfaim work that way. It would take a fair amount of effort, |
| 88 * and probably some client API changes as well. (Whenever I don't want |
84 * and probably some client API changes as well. (Whenever I don't want |
| 89 * to do something, I just say it would change the client API. Then I |
85 * to do something, I just say it would change the client API. Then I |
| 90 * instantly have a couple of supporters of not doing it.) |
86 * instantly have a couple of supporters of not doing it.) |
| 91 * |
87 * |
| 92 * Generally, addgroup is only called by the internal handling of the |
88 * Generally, addgroup is only called by the internal handling of the |
| 93 * server ready SNAC. So if you want to do something before that, you'll |
89 * server ready SNAC. So if you want to do something before that, you'll |
| 94 * have to be more creative. That is done rather early, though, so I don't |
90 * have to be more creative. That is done rather early, though, so I don't |
| 95 * think you have to worry about it. Unless you're me. I care deeply |
91 * think you have to worry about it. Unless you're me. I care deeply |
| 96 * about such inane things. |
92 * about such inane things. |
| 97 * |
93 * |
| 98 */ |
94 */ |
| 99 faim_internal void aim_conn_addgroup(OscarConnection *conn, guint16 group) |
95 void |
| |
96 aim_conn_addgroup(OscarConnection *conn, guint16 group) |
| 100 { |
97 { |
| 101 aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside; |
98 aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside; |
| 102 struct snacgroup *sg; |
99 struct snacgroup *sg; |
| 103 |
100 |
| 104 if (!(sg = malloc(sizeof(struct snacgroup)))) |
101 sg = malloc(sizeof(struct snacgroup)); |
| 105 return; |
|
| 106 |
102 |
| 107 gaim_debug_misc("oscar", "adding group 0x%04x\n", group); |
103 gaim_debug_misc("oscar", "adding group 0x%04x\n", group); |
| 108 sg->group = group; |
104 sg->group = group; |
| 109 |
105 |
| 110 sg->next = ins->groups; |
106 sg->next = ins->groups; |
| 111 ins->groups = sg; |
107 ins->groups = sg; |
| 112 |
108 } |
| 113 return; |
109 |
| 114 } |
110 OscarConnection * |
| 115 |
111 aim_conn_findbygroup(OscarSession *sess, guint16 group) |
| 116 faim_export OscarConnection *aim_conn_findbygroup(OscarSession *sess, guint16 group) |
|
| 117 { |
112 { |
| 118 OscarConnection *cur; |
113 OscarConnection *cur; |
| 119 |
114 |
| 120 for (cur = sess->connlist; cur; cur = cur->next) { |
115 for (cur = sess->connlist; cur; cur = cur->next) |
| |
116 { |
| 121 aim_conn_inside_t *ins = (aim_conn_inside_t *)cur->inside; |
117 aim_conn_inside_t *ins = (aim_conn_inside_t *)cur->inside; |
| 122 struct snacgroup *sg; |
118 struct snacgroup *sg; |
| 123 |
119 |
| 124 for (sg = ins->groups; sg; sg = sg->next) { |
120 for (sg = ins->groups; sg; sg = sg->next) |
| |
121 { |
| 125 if (sg->group == group) |
122 if (sg->group == group) |
| 126 return cur; |
123 return cur; |
| 127 } |
124 } |
| 128 } |
125 } |
| 129 |
126 |
| 130 return NULL; |
127 return NULL; |
| 131 } |
128 } |
| 132 |
129 |
| 133 static void connkill_snacgroups(struct snacgroup **head) |
130 static void |
| |
131 connkill_snacgroups(struct snacgroup *head) |
| 134 { |
132 { |
| 135 struct snacgroup *sg; |
133 struct snacgroup *sg; |
| 136 |
134 |
| 137 for (sg = *head; sg; ) { |
135 for (sg = head; sg; ) |
| |
136 { |
| 138 struct snacgroup *tmp; |
137 struct snacgroup *tmp; |
| 139 |
138 |
| 140 tmp = sg->next; |
139 tmp = sg->next; |
| 141 free(sg); |
140 free(sg); |
| 142 sg = tmp; |
141 sg = tmp; |
| 143 } |
142 } |
| 144 |
143 } |
| 145 *head = NULL; |
144 |
| 146 |
145 static void |
| 147 return; |
146 connkill_rates(struct rateclass *head) |
| 148 } |
|
| 149 |
|
| 150 static void connkill_rates(struct rateclass **head) |
|
| 151 { |
147 { |
| 152 struct rateclass *rc; |
148 struct rateclass *rc; |
| 153 |
149 |
| 154 for (rc = *head; rc; ) { |
150 for (rc = head; rc; ) |
| |
151 { |
| 155 struct rateclass *tmp; |
152 struct rateclass *tmp; |
| 156 struct snacpair *sp; |
153 struct snacpair *sp; |
| 157 |
154 |
| 158 tmp = rc->next; |
155 tmp = rc->next; |
| 159 |
156 |
| 166 } |
163 } |
| 167 free(rc); |
164 free(rc); |
| 168 |
165 |
| 169 rc = tmp; |
166 rc = tmp; |
| 170 } |
167 } |
| 171 |
168 } |
| 172 *head = NULL; |
169 |
| 173 |
170 static void |
| 174 return; |
171 connkill_real(OscarSession *sess, OscarConnection *conn) |
| 175 } |
172 { |
| 176 |
173 |
| 177 static void connkill_real(OscarSession *sess, OscarConnection **deadconn) |
174 aim_rxqueue_cleanbyconn(sess, conn); |
| 178 { |
175 aim_tx_cleanqueue(sess, conn); |
| 179 |
176 |
| 180 aim_rxqueue_cleanbyconn(sess, *deadconn); |
177 if (conn->fd != -1) |
| 181 aim_tx_cleanqueue(sess, *deadconn); |
178 aim_conn_close(conn); |
| 182 |
|
| 183 if ((*deadconn)->fd != -1) |
|
| 184 aim_conn_close(*deadconn); |
|
| 185 |
179 |
| 186 /* |
180 /* |
| 187 * This will free ->internal if it necessary... |
181 * This will free ->internal if it necessary... |
| 188 */ |
182 */ |
| 189 if ((*deadconn)->type == AIM_CONN_TYPE_CHAT) |
183 if (conn->type == AIM_CONN_TYPE_CHAT) |
| 190 aim_conn_kill_chat(sess, *deadconn); |
184 aim_conn_kill_chat(sess, conn); |
| 191 |
185 |
| 192 if ((*deadconn)->inside) { |
186 if (conn->inside) |
| 193 aim_conn_inside_t *inside = (aim_conn_inside_t *)(*deadconn)->inside; |
187 { |
| 194 |
188 aim_conn_inside_t *inside = (aim_conn_inside_t *)conn->inside; |
| 195 connkill_snacgroups(&inside->groups); |
189 |
| 196 connkill_rates(&inside->rates); |
190 connkill_snacgroups(inside->groups); |
| |
191 connkill_rates(inside->rates); |
| 197 |
192 |
| 198 free(inside); |
193 free(inside); |
| 199 } |
194 } |
| 200 |
195 |
| 201 free(*deadconn); |
196 gaim_circ_buffer_destroy(conn->buffer_outgoing); |
| 202 *deadconn = NULL; |
197 free(conn); |
| 203 |
|
| 204 return; |
|
| 205 } |
198 } |
| 206 |
199 |
| 207 /** |
200 /** |
| 208 * This sends an empty channel 4 SNAC. This is sent to signify |
201 * This sends an empty channel 4 SNAC. This is sent to signify |
| 209 * that we're logging off. This shouldn't really be necessary-- |
202 * that we're logging off. This shouldn't really be necessary-- |
| 216 FlapFrame *fr; |
209 FlapFrame *fr; |
| 217 |
210 |
| 218 if (!sess || !conn) |
211 if (!sess || !conn) |
| 219 return -EINVAL; |
212 return -EINVAL; |
| 220 |
213 |
| 221 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x04, 0))) |
214 if (!(fr = flap_frame_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x04, 0))) |
| 222 return -ENOMEM; |
215 return -ENOMEM; |
| 223 |
216 |
| 224 aim_tx_enqueue(sess, fr); |
217 aim_tx_enqueue(sess, fr); |
| 225 |
218 |
| 226 return 0; |
219 return 0; |
| 227 } |
220 } |
| 228 |
221 |
| 229 /** |
222 /** |
| 230 * Clears out the connection list, killing remaining connections. |
|
| 231 * |
|
| 232 * @param sess Session to be cleared. |
|
| 233 */ |
|
| 234 static void aim_connrst(OscarSession *sess) |
|
| 235 { |
|
| 236 |
|
| 237 if (sess->connlist) { |
|
| 238 OscarConnection *cur = sess->connlist, *tmp; |
|
| 239 |
|
| 240 /* Attempt to send the log-off packet */ |
|
| 241 if (cur->type == AIM_CONN_TYPE_BOS) |
|
| 242 aim_flap_close(sess, cur); |
|
| 243 |
|
| 244 while (cur) { |
|
| 245 tmp = cur->next; |
|
| 246 aim_conn_close(cur); |
|
| 247 connkill_real(sess, &cur); |
|
| 248 cur = tmp; |
|
| 249 } |
|
| 250 } |
|
| 251 |
|
| 252 sess->connlist = NULL; |
|
| 253 |
|
| 254 return; |
|
| 255 } |
|
| 256 |
|
| 257 /** |
|
| 258 * Initializes and/or resets a connection structure to the default values. |
|
| 259 * |
|
| 260 * @param deadconn Connection to be reset. |
|
| 261 */ |
|
| 262 static void aim_conn_init(OscarConnection *deadconn) |
|
| 263 { |
|
| 264 |
|
| 265 if (!deadconn) |
|
| 266 return; |
|
| 267 |
|
| 268 deadconn->fd = -1; |
|
| 269 deadconn->subtype = -1; |
|
| 270 deadconn->type = -1; |
|
| 271 deadconn->seqnum = 0; |
|
| 272 deadconn->lastactivity = 0; |
|
| 273 deadconn->forcedlatency = 0; |
|
| 274 deadconn->handlerlist = NULL; |
|
| 275 deadconn->priv = NULL; |
|
| 276 memset(deadconn->inside, 0, sizeof(aim_conn_inside_t)); |
|
| 277 |
|
| 278 return; |
|
| 279 } |
|
| 280 |
|
| 281 /** |
|
| 282 * Allocate a new empty connection structure. |
223 * Allocate a new empty connection structure. |
| 283 * |
224 * |
| 284 * @param sess Session |
225 * @param sess The oscar session associated with this connection. |
| 285 * @return Returns the new connection structure. |
226 * @return Returns the new connection structure. |
| 286 */ |
227 */ |
| 287 static OscarConnection *aim_conn_getnext(OscarSession *sess) |
228 static OscarConnection * |
| 288 { |
229 aim_conn_getnext(OscarSession *sess) |
| 289 OscarConnection *newconn; |
230 { |
| 290 |
231 OscarConnection *conn; |
| 291 if (!(newconn = malloc(sizeof(OscarConnection)))) |
232 |
| 292 return NULL; |
233 conn = g_new0(OscarConnection, 1); |
| 293 memset(newconn, 0, sizeof(OscarConnection)); |
234 conn->inside = g_new0(aim_conn_inside_t, 1); |
| 294 |
235 conn->buffer_outgoing = gaim_circ_buffer_new(-1); |
| 295 if (!(newconn->inside = malloc(sizeof(aim_conn_inside_t)))) { |
236 conn->fd = -1; |
| 296 free(newconn); |
237 conn->subtype = -1; |
| 297 return NULL; |
238 conn->type = -1; |
| 298 } |
239 conn->seqnum = 0; |
| 299 memset(newconn->inside, 0, sizeof(aim_conn_inside_t)); |
240 conn->lastactivity = 0; |
| 300 |
241 conn->forcedlatency = 0; |
| 301 aim_conn_init(newconn); |
242 conn->handlerlist = NULL; |
| 302 |
243 |
| 303 newconn->next = sess->connlist; |
244 conn->next = sess->connlist; |
| 304 sess->connlist = newconn; |
245 sess->connlist = conn; |
| 305 |
246 |
| 306 return newconn; |
247 return conn; |
| 307 } |
248 } |
| 308 |
249 |
| 309 /** |
250 /** |
| 310 * Close, clear, and free a connection structure. Should never be |
251 * Close, clear, and free a connection structure. Should never be |
| 311 * called from within libfaim. |
252 * called from within libfaim. |
| 312 * |
253 * |
| 313 * @param sess Session for the connection. |
254 * @param sess Session for the connection. |
| 314 * @param deadconn Connection to be freed. |
255 * @param deadconn Connection to be freed. |
| 315 */ |
256 */ |
| 316 faim_export void aim_conn_kill(OscarSession *sess, OscarConnection **deadconn) |
257 void |
| |
258 aim_conn_kill(OscarSession *sess, OscarConnection **deadconn) |
| 317 { |
259 { |
| 318 OscarConnection *cur, **prev; |
260 OscarConnection *cur, **prev; |
| 319 |
261 |
| 320 if (!deadconn || !*deadconn) |
262 if (!deadconn || !*deadconn) |
| 321 return; |
263 return; |
| 329 } |
271 } |
| 330 |
272 |
| 331 if (!cur) |
273 if (!cur) |
| 332 return; /* oops */ |
274 return; /* oops */ |
| 333 |
275 |
| 334 connkill_real(sess, &cur); |
276 connkill_real(sess, cur); |
| 335 |
|
| 336 return; |
|
| 337 } |
277 } |
| 338 |
278 |
| 339 /** |
279 /** |
| 340 * Close (but not free) a connection. |
280 * Close (but not free) a connection. |
| 341 * |
281 * |
| 342 * This leaves everything untouched except for clearing the |
282 * This leaves everything untouched except for clearing the |
| 343 * handler list and setting the fd to -1 (used to recognize |
283 * handler list and setting the fd to -1 (used to recognize |
| 344 * dead connections). It will also remove cookies if necessary. |
284 * dead connections). It will also remove cookies if necessary. |
| 345 * |
285 * |
| 346 * Why only if fd >= 3? Seems rather implementation specific... |
286 * Why only if fd >= 3? Seems rather implementation specific... |
| 347 * fd's do not have to be distributed in a particular order, do they? |
287 * fd's do not have to be distributed in a particular order, do they? |
| 348 * |
288 * |
| 349 * @param deadconn The connection to close. |
289 * @param deadconn The connection to close. |
| 350 */ |
290 */ |
| 351 faim_export void aim_conn_close(OscarConnection *deadconn) |
291 void |
| |
292 aim_conn_close(OscarConnection *deadconn) |
| 352 { |
293 { |
| 353 aim_rxcallback_t userfunc; |
294 aim_rxcallback_t userfunc; |
| 354 |
295 |
| 355 if (deadconn->fd >= 0) |
296 if (deadconn->fd >= 0) |
| 356 close(deadconn->fd); |
297 close(deadconn->fd); |
| 360 if ((userfunc = aim_callhandler(deadconn->sessv, deadconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNDEAD))) |
301 if ((userfunc = aim_callhandler(deadconn->sessv, deadconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNDEAD))) |
| 361 userfunc(deadconn->sessv, NULL, deadconn); |
302 userfunc(deadconn->sessv, NULL, deadconn); |
| 362 |
303 |
| 363 if (deadconn->handlerlist) |
304 if (deadconn->handlerlist) |
| 364 aim_clearhandlers(deadconn); |
305 aim_clearhandlers(deadconn); |
| 365 |
306 } |
| 366 return; |
307 |
| 367 } |
308 /** |
| 368 |
309 * Locates a connection of the specified type in the |
| 369 /** |
|
| 370 * Locates a connection of the specified type in the |
|
| 371 * specified session. |
310 * specified session. |
| 372 * |
311 * |
| 373 * XXX - Except for rendezvous, all uses of this should be removed and |
312 * XXX - Except for rendezvous, all uses of this should be removed and |
| 374 * aim_conn_findbygroup() should be used instead. |
313 * aim_conn_findbygroup() should be used instead. |
| 375 * |
314 * |
| 376 * @param sess The session to search. |
315 * @param sess The session to search. |
| 377 * @param type The type of connection to look for. |
316 * @param type The type of connection to look for. |
| 378 * @return Returns the first connection found of the given target type, |
317 * @return Returns the first connection found of the given target type, |
| 379 * or NULL if none could be found. |
318 * or NULL if none could be found. |
| 380 */ |
319 */ |
| 381 faim_export OscarConnection *aim_getconn_type(OscarSession *sess, int type) |
320 OscarConnection * |
| |
321 aim_getconn_type(OscarSession *sess, int type) |
| 382 { |
322 { |
| 383 OscarConnection *cur; |
323 OscarConnection *cur; |
| 384 |
324 |
| 385 for (cur = sess->connlist; cur; cur = cur->next) { |
325 for (cur = sess->connlist; cur; cur = cur->next) { |
| 386 if ((cur->type == type) && |
326 if ((cur->type == type) && |
| 418 |
360 |
| 419 /** |
361 /** |
| 420 * Clone an OscarConnection. |
362 * Clone an OscarConnection. |
| 421 * |
363 * |
| 422 * A new connection is allocated, and the values are filled in |
364 * A new connection is allocated, and the values are filled in |
| 423 * appropriately. Note that this function sets the new connnection's |
365 * appropriately. |
| 424 * ->priv pointer to be equal to that of its parent: only the pointer |
|
| 425 * is copied, not the data it points to. |
|
| 426 * |
366 * |
| 427 * @param sess The session containing this connection. |
367 * @param sess The session containing this connection. |
| 428 * @param src The connection to clone. |
368 * @param src The connection to clone. |
| 429 * @return Returns a pointer to the new OscarConnection, or %NULL on error. |
369 * @return Returns a pointer to the new OscarConnection, or %NULL on error. |
| 430 */ |
370 */ |
| 431 faim_internal OscarConnection *aim_cloneconn(OscarSession *sess, OscarConnection *src) |
371 OscarConnection * |
| |
372 aim_cloneconn(OscarSession *sess, OscarConnection *src) |
| 432 { |
373 { |
| 433 OscarConnection *conn; |
374 OscarConnection *conn; |
| 434 |
375 |
| 435 if (!(conn = aim_conn_getnext(sess))) |
376 if (!(conn = aim_conn_getnext(sess))) |
| 436 return NULL; |
377 return NULL; |
| 437 |
378 |
| 438 conn->fd = src->fd; |
379 conn->fd = src->fd; |
| 439 conn->type = src->type; |
380 conn->type = src->type; |
| 440 conn->subtype = src->subtype; |
381 conn->subtype = src->subtype; |
| 441 conn->seqnum = src->seqnum; |
382 conn->seqnum = src->seqnum; |
| 442 conn->priv = src->priv; |
|
| 443 conn->internal = src->internal; |
383 conn->internal = src->internal; |
| 444 conn->lastactivity = src->lastactivity; |
384 conn->lastactivity = src->lastactivity; |
| 445 conn->forcedlatency = src->forcedlatency; |
385 conn->forcedlatency = src->forcedlatency; |
| 446 conn->sessv = src->sessv; |
386 conn->sessv = src->sessv; |
| 447 aim_clonehandlers(sess, conn, src); |
387 aim_clonehandlers(sess, conn, src); |
| 529 |
471 |
| 530 return 0; |
472 return 0; |
| 531 } |
473 } |
| 532 |
474 |
| 533 /** |
475 /** |
| 534 * Initializes a session structure by setting the initial values |
476 * Allocates a new OscarSession and initializes it with default values. |
| 535 * stuff in the OscarSession struct. |
477 */ |
| 536 * |
478 OscarSession * |
| 537 * @param sess Session to initialize. |
479 oscar_session_new(void) |
| 538 * @param nonblocking Set to true if you want connections to be non-blocking. |
480 { |
| 539 */ |
481 OscarSession *sess; |
| 540 faim_export void aim_session_init(OscarSession *sess, guint8 nonblocking) |
482 |
| 541 { |
483 sess = g_new(OscarSession, 1); |
| 542 |
484 |
| 543 if (!sess) |
|
| 544 return; |
|
| 545 |
|
| 546 memset(sess, 0, sizeof(OscarSession)); |
|
| 547 aim_connrst(sess); |
|
| 548 sess->queue_outgoing = NULL; |
485 sess->queue_outgoing = NULL; |
| 549 sess->queue_incoming = NULL; |
486 sess->queue_incoming = NULL; |
| 550 aim_initsnachash(sess); |
487 aim_initsnachash(sess); |
| 551 sess->msgcookies = NULL; |
488 sess->msgcookies = NULL; |
| 552 sess->nonblocking = nonblocking; |
|
| 553 sess->modlistv = NULL; |
489 sess->modlistv = NULL; |
| 554 sess->snacid_next = 0x00000001; |
490 sess->snacid_next = 0x00000001; |
| 555 |
491 |
| 556 sess->locate.userinfo = NULL; |
492 sess->locate.userinfo = NULL; |
| 557 sess->locate.torequest = NULL; |
493 sess->locate.torequest = NULL; |
| 601 aim__registermodule(sess, icq_modfirst); /* XXX - Make sure this isn't sent for AIM */ |
537 aim__registermodule(sess, icq_modfirst); /* XXX - Make sure this isn't sent for AIM */ |
| 602 /* missing 0x16 */ |
538 /* missing 0x16 */ |
| 603 aim__registermodule(sess, auth_modfirst); |
539 aim__registermodule(sess, auth_modfirst); |
| 604 aim__registermodule(sess, email_modfirst); |
540 aim__registermodule(sess, email_modfirst); |
| 605 |
541 |
| 606 return; |
542 return sess; |
| 607 } |
543 } |
| 608 |
544 |
| 609 /** |
545 /** |
| 610 * Logoff and deallocate a session. |
546 * Logoff and deallocate a session. |
| 611 * |
547 * |
| 612 * @param sess Session to kill |
548 * @param sess Session to kill |
| 613 */ |
549 */ |
| 614 faim_export void aim_session_kill(OscarSession *sess) |
550 void |
| |
551 oscar_session_destroy(OscarSession *sess) |
| 615 { |
552 { |
| 616 aim_cleansnacs(sess, -1); |
553 aim_cleansnacs(sess, -1); |
| 617 |
554 |
| 618 aim_logoff(sess); |
555 if (sess->connlist) { |
| |
556 OscarConnection *cur = sess->connlist, *tmp; |
| |
557 |
| |
558 /* Attempt to send the log-off packet */ |
| |
559 if (cur->type == AIM_CONN_TYPE_BOS) |
| |
560 aim_flap_close(sess, cur); |
| |
561 |
| |
562 while (cur) { |
| |
563 tmp = cur->next; |
| |
564 aim_conn_close(cur); |
| |
565 connkill_real(sess, cur); |
| |
566 cur = tmp; |
| |
567 } |
| |
568 } |
| |
569 sess->connlist = NULL; |
| 619 |
570 |
| 620 aim__shutdownmodules(sess); |
571 aim__shutdownmodules(sess); |
| 621 |
572 |
| 622 return; |
573 g_free(sess); |
| 623 } |
574 } |
| 624 |
575 |
| 625 /** |
576 /** |
| 626 * Determine if a connection is connecting. |
577 * Determine if a connection is connecting. |
| 627 * |
578 * |
| 628 * @param conn Connection to examine. |
579 * @param conn Connection to examine. |
| 629 * @return Returns nonzero if the connection is in the process of |
580 * @return Returns nonzero if the connection is in the process of |
| 630 * connecting (or if it just completed and |
581 * connecting (or if it just completed and |
| 631 * aim_conn_completeconnect() has yet to be called on it). |
582 * aim_conn_completeconnect() has yet to be called on it). |
| 632 */ |
583 */ |
| 633 faim_export int aim_conn_isconnecting(OscarConnection *conn) |
584 int |
| |
585 aim_conn_isconnecting(OscarConnection *conn) |
| 634 { |
586 { |
| 635 |
587 |
| 636 if (!conn) |
588 if (!conn) |
| 637 return 0; |
589 return 0; |
| 638 |
590 |
| 663 aim_tx_flushqueue(sess); |
616 aim_tx_flushqueue(sess); |
| 664 |
617 |
| 665 return 0; |
618 return 0; |
| 666 } |
619 } |
| 667 |
620 |
| 668 faim_export OscarSession *aim_conn_getsess(OscarConnection *conn) |
621 OscarSession * |
| |
622 aim_conn_getsess(OscarConnection *conn) |
| 669 { |
623 { |
| 670 |
624 |
| 671 if (!conn) |
625 if (!conn) |
| 672 return NULL; |
626 return NULL; |
| 673 |
627 |
| 674 return (OscarSession *)conn->sessv; |
628 return (OscarSession *)conn->sessv; |
| 675 } |
629 } |
| 676 |
630 |
| 677 /** |
631 /** |
| 678 * Close -ALL- open connections. |
|
| 679 * |
|
| 680 * @param sess The session. |
|
| 681 * @return Zero. |
|
| 682 */ |
|
| 683 faim_export int aim_logoff(OscarSession *sess) |
|
| 684 { |
|
| 685 aim_connrst(sess); /* in case we want to connect again */ |
|
| 686 |
|
| 687 return 0; |
|
| 688 } |
|
| 689 |
|
| 690 /** |
|
| 691 * No-op. This sends an empty channel 5 SNAC. WinAIM 4.x and higher |
632 * No-op. This sends an empty channel 5 SNAC. WinAIM 4.x and higher |
| 692 * sends these _every minute_ to keep the connection alive. |
633 * sends these _every minute_ to keep the connection alive. |
| 693 */ |
634 */ |
| 694 faim_export int aim_flap_nop(OscarSession *sess, OscarConnection *conn) |
635 int |
| |
636 aim_flap_nop(OscarSession *sess, OscarConnection *conn) |
| 695 { |
637 { |
| 696 FlapFrame *fr; |
638 FlapFrame *fr; |
| 697 |
639 |
| 698 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x05, 0))) |
640 if (!(fr = flap_frame_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x05, 0))) |
| 699 return -ENOMEM; |
641 return -ENOMEM; |
| 700 |
642 |
| 701 aim_tx_enqueue(sess, fr); |
643 aim_tx_enqueue(sess, fr); |
| 702 |
644 |
| 703 /* clean out SNACs over 60sec old */ |
645 /* clean out SNACs over 60sec old */ |