| 197 OscarData *od; |
215 OscarData *od; |
| 198 GaimAccount *account; |
216 GaimAccount *account; |
| 199 |
217 |
| 200 conn = data; |
218 conn = data; |
| 201 od = conn->od; |
219 od = conn->od; |
| |
220 account = gaim_connection_get_account(od->gc); |
| 202 |
221 |
| 203 gaim_debug_info("oscar", "Destroying oscar connection of " |
222 gaim_debug_info("oscar", "Destroying oscar connection of " |
| 204 "type 0x%04hx\n", conn->type); |
223 "type 0x%04hx\n", conn->type); |
| 205 |
224 |
| 206 flap_connection_close(od, conn); |
|
| 207 |
|
| 208 g_free(conn->cookie); |
|
| 209 |
|
| 210 if (conn->watcher_incoming != 0) |
|
| 211 gaim_input_remove(conn->watcher_incoming); |
|
| 212 if (conn->watcher_outgoing != 0) |
|
| 213 gaim_input_remove(conn->watcher_outgoing); |
|
| 214 g_free(conn->buffer_incoming.data.data); |
|
| 215 gaim_circ_buffer_destroy(conn->buffer_outgoing); |
|
| 216 |
|
| 217 /* |
|
| 218 * Free conn->internal, if necessary |
|
| 219 */ |
|
| 220 if (conn->type == SNAC_FAMILY_CHAT) |
|
| 221 flap_connection_destroy_chat(od, conn); |
|
| 222 |
|
| 223 g_slist_free(conn->groups); |
|
| 224 flap_connection_destroy_rates(conn->rates); |
|
| 225 |
|
| 226 od->oscar_connections = g_slist_remove(od->oscar_connections, conn); |
225 od->oscar_connections = g_slist_remove(od->oscar_connections, conn); |
| 227 |
|
| 228 account = gaim_connection_get_account(od->gc); |
|
| 229 |
226 |
| 230 /* |
227 /* |
| 231 * TODO: If we don't have a SNAC_FAMILY_LOCATE connection then |
228 * TODO: If we don't have a SNAC_FAMILY_LOCATE connection then |
| 232 * we should try to request one instead of disconnecting. |
229 * we should try to request one instead of disconnecting. |
| 233 */ |
230 */ |
| 234 if (!account->disconnecting && ((od->oscar_connections == NULL) |
231 if (!account->disconnecting && ((od->oscar_connections == NULL) |
| 235 || (!flap_connection_getbytype(od, SNAC_FAMILY_LOCATE)))) |
232 || (!flap_connection_getbytype(od, SNAC_FAMILY_LOCATE)))) |
| 236 { |
233 { |
| 237 /* No more FLAP connections! Sign off this GaimConnection! */ |
234 /* No more FLAP connections! Sign off this GaimConnection! */ |
| 238 const gchar *tmp; |
235 gchar *tmp; |
| 239 if (conn->disconnect_reason == OSCAR_DISCONNECT_REMOTE_CLOSED) |
236 if (conn->disconnect_reason == OSCAR_DISCONNECT_REMOTE_CLOSED) |
| 240 tmp = _("Server closed the connection."); |
237 tmp = g_strdup(_("Server closed the connection.")); |
| 241 else if (conn->disconnect_reason == OSCAR_DISCONNECT_LOST_CONNECTION) |
238 else if (conn->disconnect_reason == OSCAR_DISCONNECT_LOST_CONNECTION) |
| 242 tmp = _("Lost connection with server for an unknown reason."); |
239 tmp = g_strdup_printf(_("Lost connection with server:\n%s"), |
| |
240 conn->error_message); |
| 243 else if (conn->disconnect_reason == OSCAR_DISCONNECT_INVALID_DATA) |
241 else if (conn->disconnect_reason == OSCAR_DISCONNECT_INVALID_DATA) |
| 244 tmp = _("Received invalid data on connection with server."); |
242 tmp = g_strdup(_("Received invalid data on connection with server.")); |
| 245 else if (conn->disconnect_reason == OSCAR_DISCONNECT_COULD_NOT_CONNECT) |
243 else if (conn->disconnect_reason == OSCAR_DISCONNECT_COULD_NOT_CONNECT) |
| 246 tmp = _("Could not establish a connection with the server."); |
244 tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"), |
| |
245 conn->error_message); |
| 247 else |
246 else |
| 248 /* |
247 /* |
| 249 * We shouldn't print a message for some disconnect_reasons. |
248 * We shouldn't print a message for some disconnect_reasons. |
| 250 * Like OSCAR_DISCONNECT_LOCAL_CLOSED. |
249 * Like OSCAR_DISCONNECT_LOCAL_CLOSED. |
| 251 */ |
250 */ |
| 252 tmp = NULL; |
251 tmp = NULL; |
| 253 |
252 |
| 254 if (tmp != NULL) |
253 if (tmp != NULL) |
| |
254 { |
| 255 gaim_connection_error(od->gc, tmp); |
255 gaim_connection_error(od->gc, tmp); |
| 256 } |
256 g_free(tmp); |
| |
257 } |
| |
258 } |
| |
259 |
| |
260 flap_connection_close(od, conn); |
| |
261 |
| |
262 g_free(conn->error_message); |
| |
263 g_free(conn->cookie); |
| |
264 |
| |
265 /* |
| |
266 * Free conn->internal, if necessary |
| |
267 */ |
| |
268 if (conn->type == SNAC_FAMILY_CHAT) |
| |
269 flap_connection_destroy_chat(od, conn); |
| |
270 |
| |
271 g_slist_free(conn->groups); |
| |
272 flap_connection_destroy_rates(conn->rates); |
| 257 |
273 |
| 258 g_free(conn); |
274 g_free(conn); |
| 259 |
275 |
| 260 return FALSE; |
276 return FALSE; |
| 261 } |
277 } |
| 262 |
278 |
| |
279 /** |
| |
280 * See the comments for the parameters of |
| |
281 * flap_connection_schedule_destroy(). |
| |
282 */ |
| 263 void |
283 void |
| 264 flap_connection_destroy(FlapConnection *conn, OscarDisconnectReason reason) |
284 flap_connection_destroy(FlapConnection *conn, OscarDisconnectReason reason, const gchar *error_message) |
| 265 { |
285 { |
| 266 if (conn->destroy_timeout != 0) |
286 if (conn->destroy_timeout != 0) |
| 267 gaim_timeout_remove(conn->destroy_timeout); |
287 gaim_timeout_remove(conn->destroy_timeout); |
| 268 conn->disconnect_reason = reason; |
288 conn->disconnect_reason = reason; |
| |
289 g_free(conn->error_message); |
| |
290 conn->error_message = g_strdup(error_message); |
| 269 flap_connection_destroy_cb(conn); |
291 flap_connection_destroy_cb(conn); |
| 270 } |
292 } |
| 271 |
293 |
| 272 /** |
294 /** |
| 273 * Schedule Gaim to destroy the given FlapConnection as soon as we |
295 * Schedule Gaim to destroy the given FlapConnection as soon as we |
| 274 * return control back to the program's main loop. We must do this |
296 * return control back to the program's main loop. We must do this |
| 275 * if we want to destroy the connection but we are still using it |
297 * if we want to destroy the connection but we are still using it |
| 276 * for some reason. |
298 * for some reason. |
| |
299 * |
| |
300 * @param reason The reason for the disconnection. |
| |
301 * @param error_message A brief error message that gives more detail |
| |
302 * regarding the reason for the disconnecting. This should |
| |
303 * be NULL for everything except OSCAR_DISCONNECT_LOST_CONNECTION, |
| |
304 * in which case it should contain the value of strerror(errno), |
| |
305 * and OSCAR_DISCONNECT_COULD_NOT_CONNECT, in which case it |
| |
306 * should contain the error_message passed back from the call |
| |
307 * to gaim_proxy_connect(). |
| 277 */ |
308 */ |
| 278 void |
309 void |
| 279 flap_connection_schedule_destroy(FlapConnection *conn, OscarDisconnectReason reason) |
310 flap_connection_schedule_destroy(FlapConnection *conn, OscarDisconnectReason reason, const gchar *error_message) |
| 280 { |
311 { |
| 281 if (conn->destroy_timeout != 0) |
312 if (conn->destroy_timeout != 0) |
| 282 /* Already taken care of */ |
313 /* Already taken care of */ |
| 283 return; |
314 return; |
| 284 |
315 |
| 285 gaim_debug_info("oscar", "Scheduling destruction of FLAP " |
316 gaim_debug_info("oscar", "Scheduling destruction of FLAP " |
| 286 "connection of type 0x%04hx\n", conn->type); |
317 "connection of type 0x%04hx\n", conn->type); |
| 287 conn->disconnect_reason = reason; |
318 conn->disconnect_reason = reason; |
| |
319 conn->error_message = g_strdup(error_message); |
| 288 conn->destroy_timeout = gaim_timeout_add(0, flap_connection_destroy_cb, conn); |
320 conn->destroy_timeout = gaim_timeout_add(0, flap_connection_destroy_cb, conn); |
| 289 } |
321 } |
| 290 |
322 |
| 291 /** |
323 /** |
| 292 * In OSCAR, every connection has a set of SNAC groups associated |
324 * In OSCAR, every connection has a set of SNAC groups associated |