+ struct aim_conn_t *cur;
+
+ if (!deadconn || !*deadconn)
+ return;
+
+ faim_mutex_lock(&sess->connlistlock);
+ if (sess->connlist == NULL)
+ ;
+ else if (sess->connlist->next == NULL) {
+ if (sess->connlist == *deadconn)
+ sess->connlist = NULL;
+ } else {
+ cur = sess->connlist;
+ while (cur->next) {
+ if (cur->next == *deadconn) {
+ cur->next = cur->next->next;
+ break;
+ }
+ cur = cur->next;
+ }
+ }
+ faim_mutex_unlock(&sess->connlistlock);
+
+ /* XXX: do we need this for txqueue too? */
+ aim_rxqueue_cleanbyconn(sess, *deadconn);
+
+ aim_conn_close(*deadconn);
+ if ((*deadconn)->priv)
+ free((*deadconn)->priv);
+ free(*deadconn);
+ deadconn = NULL;
+
+ return;
+}
+
+faim_export void aim_conn_close(struct aim_conn_t *deadconn)
+{
+ int typesav = -1, subtypesav = -1;
+ void *privsav = NULL;
+
+ faim_mutex_destroy(&deadconn->active);
+ faim_mutex_destroy(&deadconn->seqnum_lock);
+ if (deadconn->fd >= 3)
+ close(deadconn->fd);
+ if (deadconn->handlerlist)
+ aim_clearhandlers(deadconn);
+
+ typesav = deadconn->type;
+ subtypesav = deadconn->subtype;
+
+ if (deadconn->priv && (deadconn->type != AIM_CONN_TYPE_RENDEZVOUS)) {
+ free(deadconn->priv);
+ deadconn->priv = NULL;
+ }
+ privsav = deadconn->priv;
+
+ aim_conn_init(deadconn);
+
+ deadconn->type = typesav;
+ deadconn->subtype = subtypesav;
+ deadconn->priv = privsav;
+
+ return;
+}
+
+faim_internal struct aim_conn_t *aim_getconn_type(struct aim_session_t *sess,
+ int type)
+{
+ struct aim_conn_t *cur;
+
+ faim_mutex_lock(&sess->connlistlock);
+ for (cur = sess->connlist; cur; cur = cur->next) {
+ if (cur->type == type)
+ break;
+ }
+ faim_mutex_unlock(&sess->connlistlock);
+ return cur;