Mercurial > pidgin
comparison src/protocols/oscar/conn.c @ 13254:e9802db22b06
[gaim-migrate @ 15620]
This is the way we clean the code, clean the code, clean the code
This is the way we clean the code, clean the code, clean the code
So early in the morning
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sun, 12 Feb 2006 22:14:38 +0000 |
parents | 87a7c3077c19 |
children | 7ead7b8aea63 |
comparison
equal
deleted
inserted
replaced
13253:87a7c3077c19 | 13254:e9802db22b06 |
---|---|
108 } | 108 } |
109 | 109 |
110 OscarConnection * | 110 OscarConnection * |
111 aim_conn_findbygroup(OscarSession *sess, guint16 group) | 111 aim_conn_findbygroup(OscarSession *sess, guint16 group) |
112 { | 112 { |
113 OscarConnection *cur; | 113 GList *cur;; |
114 | 114 |
115 for (cur = sess->connlist; cur; cur = cur->next) | 115 for (cur = sess->oscar_connections; cur; cur = cur->next) |
116 { | 116 { |
117 aim_conn_inside_t *ins = (aim_conn_inside_t *)cur->inside; | 117 OscarConnection *conn; |
118 aim_conn_inside_t *ins; | |
118 struct snacgroup *sg; | 119 struct snacgroup *sg; |
120 | |
121 conn = cur->data; | |
122 ins = (aim_conn_inside_t *)conn->inside; | |
119 | 123 |
120 for (sg = ins->groups; sg; sg = sg->next) | 124 for (sg = ins->groups; sg; sg = sg->next) |
121 { | 125 { |
122 if (sg->group == group) | 126 if (sg->group == group) |
123 return cur; | 127 return conn; |
124 } | 128 } |
125 } | 129 } |
126 | 130 |
127 return NULL; | 131 return NULL; |
128 } | 132 } |
165 | 169 |
166 rc = tmp; | 170 rc = tmp; |
167 } | 171 } |
168 } | 172 } |
169 | 173 |
170 static void | 174 void |
171 connkill_real(OscarSession *sess, OscarConnection *conn) | 175 oscar_connection_destroy(OscarSession *sess, OscarConnection *conn) |
172 { | 176 { |
173 | |
174 aim_rxqueue_cleanbyconn(sess, conn); | 177 aim_rxqueue_cleanbyconn(sess, conn); |
175 aim_tx_cleanqueue(sess, conn); | 178 aim_tx_cleanqueue(sess, conn); |
176 | 179 |
177 if (conn->fd != -1) | 180 if (conn->fd != -1) |
178 aim_conn_close(conn); | 181 aim_conn_close(sess, conn); |
179 | 182 |
180 /* | 183 /* |
181 * This will free ->internal if it necessary... | 184 * This will free ->internal if it necessary... |
182 */ | 185 */ |
183 if (conn->type == AIM_CONN_TYPE_CHAT) | 186 if (conn->type == AIM_CONN_TYPE_CHAT) |
192 | 195 |
193 free(inside); | 196 free(inside); |
194 } | 197 } |
195 | 198 |
196 gaim_circ_buffer_destroy(conn->buffer_outgoing); | 199 gaim_circ_buffer_destroy(conn->buffer_outgoing); |
197 free(conn); | 200 g_free(conn); |
198 } | 201 } |
199 | 202 |
200 /** | 203 /** |
201 * This sends an empty channel 4 SNAC. This is sent to signify | 204 * This sends an empty channel 4 SNAC. This is sent to signify |
202 * that we're logging off. This shouldn't really be necessary-- | 205 * that we're logging off. This shouldn't really be necessary-- |
239 conn->seqnum = 0; | 242 conn->seqnum = 0; |
240 conn->lastactivity = 0; | 243 conn->lastactivity = 0; |
241 conn->forcedlatency = 0; | 244 conn->forcedlatency = 0; |
242 conn->handlerlist = NULL; | 245 conn->handlerlist = NULL; |
243 | 246 |
244 conn->next = sess->connlist; | 247 sess->oscar_connections = g_list_prepend(sess->oscar_connections, conn); |
245 sess->connlist = conn; | |
246 | 248 |
247 return conn; | 249 return conn; |
248 } | 250 } |
249 | 251 |
250 /** | 252 /** |
253 * | 255 * |
254 * @param sess Session for the connection. | 256 * @param sess Session for the connection. |
255 * @param deadconn Connection to be freed. | 257 * @param deadconn Connection to be freed. |
256 */ | 258 */ |
257 void | 259 void |
258 aim_conn_kill(OscarSession *sess, OscarConnection **deadconn) | 260 aim_conn_kill(OscarSession *sess, OscarConnection *conn) |
259 { | 261 { |
260 OscarConnection *cur, **prev; | 262 if (!conn) |
261 | |
262 if (!deadconn || !*deadconn) | |
263 return; | 263 return; |
264 | 264 |
265 for (prev = &sess->connlist; (cur = *prev); ) { | 265 sess->oscar_connections = g_list_remove(sess->oscar_connections, conn); |
266 if (cur == *deadconn) { | 266 |
267 *prev = cur->next; | 267 oscar_connection_destroy(sess, conn); |
268 break; | |
269 } | |
270 prev = &cur->next; | |
271 } | |
272 | |
273 if (!cur) | |
274 return; /* oops */ | |
275 | |
276 connkill_real(sess, cur); | |
277 } | 268 } |
278 | 269 |
279 /** | 270 /** |
280 * Close (but not free) a connection. | 271 * Close (but not free) a connection. |
281 * | 272 * |
282 * This leaves everything untouched except for clearing the | 273 * This leaves everything untouched except for clearing the |
283 * handler list and setting the fd to -1 (used to recognize | 274 * handler list and setting the fd to -1 (used to recognize |
284 * dead connections). It will also remove cookies if necessary. | 275 * dead connections). It will also remove cookies if necessary. |
285 * | 276 * |
286 * Why only if fd >= 3? Seems rather implementation specific... | 277 * @param conn The connection to close. |
287 * fd's do not have to be distributed in a particular order, do they? | |
288 * | |
289 * @param deadconn The connection to close. | |
290 */ | 278 */ |
291 void | 279 void |
292 aim_conn_close(OscarConnection *deadconn) | 280 aim_conn_close(OscarSession *sess, OscarConnection *conn) |
293 { | 281 { |
294 aim_rxcallback_t userfunc; | 282 if (conn->type == AIM_CONN_TYPE_BOS) |
295 | 283 aim_flap_close(sess, conn); |
296 if (deadconn->fd >= 0) | 284 |
297 close(deadconn->fd); | 285 if (conn->fd >= 0) |
298 | 286 close(conn->fd); |
299 deadconn->fd = -1; | 287 |
300 | 288 conn->fd = -1; |
301 if ((userfunc = aim_callhandler(deadconn->sessv, deadconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNDEAD))) | 289 |
302 userfunc(deadconn->sessv, NULL, deadconn); | 290 if (conn->handlerlist) |
303 | 291 aim_clearhandlers(conn); |
304 if (deadconn->handlerlist) | |
305 aim_clearhandlers(deadconn); | |
306 } | 292 } |
307 | 293 |
308 /** | 294 /** |
309 * Locates a connection of the specified type in the | 295 * Locates a connection of the specified type in the |
310 * specified session. | 296 * specified session. |
318 * or NULL if none could be found. | 304 * or NULL if none could be found. |
319 */ | 305 */ |
320 OscarConnection * | 306 OscarConnection * |
321 aim_getconn_type(OscarSession *sess, int type) | 307 aim_getconn_type(OscarSession *sess, int type) |
322 { | 308 { |
323 OscarConnection *cur; | 309 GList *cur; |
324 | 310 |
325 for (cur = sess->connlist; cur; cur = cur->next) { | 311 for (cur = sess->oscar_connections; cur; cur = cur->next) |
326 if ((cur->type == type) && | 312 { |
327 !(cur->status & AIM_CONN_STATUS_INPROGRESS)) | 313 OscarConnection *conn; |
328 break; | 314 conn = cur->data; |
329 } | 315 if ((conn->type == type) && |
330 | 316 !(conn->status & AIM_CONN_STATUS_INPROGRESS)) |
331 return cur; | 317 return conn; |
318 } | |
319 | |
320 return NULL; | |
332 } | 321 } |
333 | 322 |
334 OscarConnection * | 323 OscarConnection * |
335 aim_getconn_type_all(OscarSession *sess, int type) | 324 aim_getconn_type_all(OscarSession *sess, int type) |
336 { | 325 { |
337 OscarConnection *cur; | 326 GList *cur; |
338 | 327 |
339 for (cur = sess->connlist; cur; cur = cur->next) { | 328 for (cur = sess->oscar_connections; cur; cur = cur->next) |
340 if (cur->type == type) | 329 { |
341 break; | 330 OscarConnection *conn; |
342 } | 331 if (conn->type == type) |
343 | 332 return conn; |
344 return cur; | 333 } |
345 } | 334 |
346 | 335 return NULL; |
347 /* If you pass -1 for the fd, you'll get what you ask for. Gibberish. */ | |
348 OscarConnection * | |
349 aim_getconn_fd(OscarSession *sess, int fd) | |
350 { | |
351 OscarConnection *cur; | |
352 | |
353 for (cur = sess->connlist; cur; cur = cur->next) { | |
354 if (cur->fd == fd) | |
355 break; | |
356 } | |
357 | |
358 return cur; | |
359 } | 336 } |
360 | 337 |
361 /** | 338 /** |
362 * Clone an OscarConnection. | 339 * Clone an OscarConnection. |
363 * | 340 * |
409 * | 386 * |
410 * @param sess Session to create connection in | 387 * @param sess Session to create connection in |
411 * @param type Type of connection to create | 388 * @param type Type of connection to create |
412 */ | 389 */ |
413 OscarConnection * | 390 OscarConnection * |
414 aim_newconn(OscarSession *sess, int type) | 391 oscar_connection_new(OscarSession *sess, int type) |
415 { | 392 { |
416 OscarConnection *conn; | 393 OscarConnection *conn; |
417 | 394 |
418 if (!(conn = aim_conn_getnext(sess))) | 395 if (!(conn = aim_conn_getnext(sess))) |
419 return NULL; | 396 return NULL; |
425 conn->status = 0; | 402 conn->status = 0; |
426 return conn; | 403 return conn; |
427 } | 404 } |
428 | 405 |
429 /** | 406 /** |
430 * Searches @sess for the passed connection. | |
431 * | |
432 * @param sess Session in which to look. | |
433 * @param conn Connection to look for. | |
434 * @return Returns 1 if the passed connection is present, zero otherwise. | |
435 */ | |
436 faim_export int aim_conn_in_sess(OscarSession *sess, OscarConnection *conn) | |
437 { | |
438 OscarConnection *cur; | |
439 | |
440 for (cur = sess->connlist; cur; cur = cur->next) { | |
441 if (cur == conn) | |
442 return 1; | |
443 } | |
444 | |
445 return 0; | |
446 } | |
447 | |
448 /** | |
449 * Set a forced latency value for connection. Basically causes | 407 * Set a forced latency value for connection. Basically causes |
450 * @newval seconds to be spent between transmits on a connection. | 408 * @newval seconds to be spent between transmits on a connection. |
451 * | 409 * |
452 * This is my lame attempt at overcoming not understanding the rate | 410 * This is my lame attempt at overcoming not understanding the rate |
453 * limiting. | 411 * limiting. |
468 | 426 |
469 conn->forcedlatency = newval; | 427 conn->forcedlatency = newval; |
470 conn->lastactivity = 0; /* reset this just to make sure */ | 428 conn->lastactivity = 0; /* reset this just to make sure */ |
471 | 429 |
472 return 0; | 430 return 0; |
473 } | |
474 | |
475 /** | |
476 * Allocates a new OscarSession and initializes it with default values. | |
477 */ | |
478 OscarSession * | |
479 oscar_session_new(void) | |
480 { | |
481 OscarSession *sess; | |
482 | |
483 sess = g_new(OscarSession, 1); | |
484 | |
485 sess->queue_outgoing = NULL; | |
486 sess->queue_incoming = NULL; | |
487 aim_initsnachash(sess); | |
488 sess->msgcookies = NULL; | |
489 sess->modlistv = NULL; | |
490 sess->snacid_next = 0x00000001; | |
491 | |
492 sess->locate.userinfo = NULL; | |
493 sess->locate.torequest = NULL; | |
494 sess->locate.requested = NULL; | |
495 sess->locate.waiting_for_response = FALSE; | |
496 sess->ssi.received_data = 0; | |
497 sess->ssi.numitems = 0; | |
498 sess->ssi.official = NULL; | |
499 sess->ssi.local = NULL; | |
500 sess->ssi.pending = NULL; | |
501 sess->ssi.timestamp = (time_t)0; | |
502 sess->ssi.waiting_for_ack = 0; | |
503 sess->icq_info = NULL; | |
504 sess->authinfo = NULL; | |
505 sess->emailinfo = NULL; | |
506 sess->peer_connections = NULL; | |
507 | |
508 /* | |
509 * This must always be set. Default to the queue-based | |
510 * version for back-compatibility. | |
511 */ | |
512 aim_tx_setenqueue(sess, AIM_TX_QUEUED, NULL); | |
513 | |
514 /* | |
515 * Register all the modules for this session... | |
516 */ | |
517 aim__registermodule(sess, misc_modfirst); /* load the catch-all first */ | |
518 aim__registermodule(sess, service_modfirst); | |
519 aim__registermodule(sess, locate_modfirst); | |
520 aim__registermodule(sess, buddylist_modfirst); | |
521 aim__registermodule(sess, msg_modfirst); | |
522 aim__registermodule(sess, adverts_modfirst); | |
523 aim__registermodule(sess, invite_modfirst); | |
524 aim__registermodule(sess, admin_modfirst); | |
525 aim__registermodule(sess, popups_modfirst); | |
526 aim__registermodule(sess, bos_modfirst); | |
527 aim__registermodule(sess, search_modfirst); | |
528 aim__registermodule(sess, stats_modfirst); | |
529 aim__registermodule(sess, translate_modfirst); | |
530 aim__registermodule(sess, chatnav_modfirst); | |
531 aim__registermodule(sess, chat_modfirst); | |
532 aim__registermodule(sess, odir_modfirst); | |
533 aim__registermodule(sess, bart_modfirst); | |
534 /* missing 0x11 - 0x12 */ | |
535 aim__registermodule(sess, ssi_modfirst); | |
536 /* missing 0x14 */ | |
537 aim__registermodule(sess, icq_modfirst); /* XXX - Make sure this isn't sent for AIM */ | |
538 /* missing 0x16 */ | |
539 aim__registermodule(sess, auth_modfirst); | |
540 aim__registermodule(sess, email_modfirst); | |
541 | |
542 return sess; | |
543 } | |
544 | |
545 /** | |
546 * Logoff and deallocate a session. | |
547 * | |
548 * @param sess Session to kill | |
549 */ | |
550 void | |
551 oscar_session_destroy(OscarSession *sess) | |
552 { | |
553 aim_cleansnacs(sess, -1); | |
554 | |
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; | |
570 | |
571 aim__shutdownmodules(sess); | |
572 | |
573 g_free(sess); | |
574 } | 431 } |
575 | 432 |
576 /** | 433 /** |
577 * Determine if a connection is connecting. | 434 * Determine if a connection is connecting. |
578 * | 435 * |
595 * XXX this is nearly as ugly as proxyconnect(). | 452 * XXX this is nearly as ugly as proxyconnect(). |
596 */ | 453 */ |
597 int | 454 int |
598 aim_conn_completeconnect(OscarSession *sess, OscarConnection *conn) | 455 aim_conn_completeconnect(OscarSession *sess, OscarConnection *conn) |
599 { | 456 { |
600 aim_rxcallback_t userfunc; | |
601 | |
602 if (!conn || (conn->fd == -1)) | 457 if (!conn || (conn->fd == -1)) |
603 return -1; | 458 return -1; |
604 | 459 |
605 if (!(conn->status & AIM_CONN_STATUS_INPROGRESS)) | 460 if (!(conn->status & AIM_CONN_STATUS_INPROGRESS)) |
606 return -1; | 461 return -1; |
607 | 462 |
608 fcntl(conn->fd, F_SETFL, 0); | 463 fcntl(conn->fd, F_SETFL, 0); |
609 | 464 |
610 conn->status &= ~AIM_CONN_STATUS_INPROGRESS; | 465 conn->status &= ~AIM_CONN_STATUS_INPROGRESS; |
611 | 466 |
612 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE))) | |
613 userfunc(sess, NULL, conn); | |
614 | |
615 /* Flush out the queues if there was something waiting for this conn */ | 467 /* Flush out the queues if there was something waiting for this conn */ |
616 aim_tx_flushqueue(sess); | 468 aim_tx_flushqueue(sess); |
617 | 469 |
618 return 0; | 470 return 0; |
619 } | 471 } |