comparison src/protocols/msn/servconn.c @ 10481:bcfea6c3d5c9

[gaim-migrate @ 11769] Patch 1093958 from Felipe Contreras. It fixes stuff. I also made some tweaks to make valgrind a bit happier. committer: Tailor Script <tailor@pidgin.im>
author Stu Tomlinson <stu@nosnilmot.com>
date Fri, 07 Jan 2005 02:48:33 +0000
parents 9bed28273ec7
children fed2a7c2471d
comparison
equal deleted inserted replaced
10480:8e0a91d11362 10481:bcfea6c3d5c9
25 #include "servconn.h" 25 #include "servconn.h"
26 #include "error.h" 26 #include "error.h"
27 27
28 static void read_cb(gpointer data, gint source, GaimInputCondition cond); 28 static void read_cb(gpointer data, gint source, GaimInputCondition cond);
29 29
30 /**************************************************************************
31 * Main
32 **************************************************************************/
33
30 MsnServConn * 34 MsnServConn *
31 msn_servconn_new(MsnSession *session, MsnServConnType type) 35 msn_servconn_new(MsnSession *session, MsnServConnType type)
32 { 36 {
33 MsnServConn *servconn; 37 MsnServConn *servconn;
34 38
40 44
41 servconn->session = session; 45 servconn->session = session;
42 servconn->cmdproc = msn_cmdproc_new(session); 46 servconn->cmdproc = msn_cmdproc_new(session);
43 servconn->cmdproc->servconn = servconn; 47 servconn->cmdproc->servconn = servconn;
44 48
45 if (session->http_method) 49 servconn->httpconn = msn_httpconn_new(servconn);
46 servconn->httpconn = msn_httpconn_new(servconn);
47 50
48 servconn->num = session->servconns_count++; 51 servconn->num = session->servconns_count++;
49 52
50 return servconn; 53 return servconn;
51 } 54 }
59 { 62 {
60 servconn->wasted = TRUE; 63 servconn->wasted = TRUE;
61 return; 64 return;
62 } 65 }
63 66
64 if (servconn->destroying)
65 return;
66
67 servconn->destroying = TRUE;
68
69 if (servconn->connected) 67 if (servconn->connected)
70 msn_servconn_disconnect(servconn); 68 msn_servconn_disconnect(servconn);
71 69
72 if (servconn->destroy_cb) 70 if (servconn->destroy_cb)
73 servconn->destroy_cb(servconn); 71 servconn->destroy_cb(servconn);
80 78
81 msn_cmdproc_destroy(servconn->cmdproc); 79 msn_cmdproc_destroy(servconn->cmdproc);
82 g_free(servconn); 80 g_free(servconn);
83 } 81 }
84 82
85 static void 83 void
86 show_error(MsnServConn *servconn) 84 msn_servconn_set_connect_cb(MsnServConn *servconn,
87 { 85 void (*connect_cb)(MsnServConn *))
88 GaimConnection *gc; 86 {
87 g_return_if_fail(servconn != NULL);
88 servconn->connect_cb = connect_cb;
89 }
90
91 void
92 msn_servconn_set_disconnect_cb(MsnServConn *servconn,
93 void (*disconnect_cb)(MsnServConn *))
94 {
95 g_return_if_fail(servconn != NULL);
96
97 servconn->disconnect_cb = disconnect_cb;
98 }
99
100 void
101 msn_servconn_set_destroy_cb(MsnServConn *servconn,
102 void (*destroy_cb)(MsnServConn *))
103 {
104 g_return_if_fail(servconn != NULL);
105
106 servconn->destroy_cb = destroy_cb;
107 }
108
109 /**************************************************************************
110 * Utility
111 **************************************************************************/
112
113 void
114 msn_servconn_got_error(MsnServConn *servconn, MsnServConnError error)
115 {
89 char *tmp; 116 char *tmp;
90 char *cmd; 117 const char *reason;
91 118
92 const char *names[] = { "Notification", "Switchboard" }; 119 const char *names[] = { "Notification", "Switchboard" };
93 const char *name; 120 const char *name;
94 121
95 gc = gaim_account_get_connection(servconn->session->account);
96 name = names[servconn->type]; 122 name = names[servconn->type];
97 123
98 switch (servconn->cmdproc->error) 124 switch (error)
99 { 125 {
100 case MSN_ERROR_CONNECT: 126 case MSN_SERVCONN_ERROR_CONNECT:
101 tmp = g_strdup_printf(_("Unable to connect to %s server"), 127 reason = _("Unable to connect"); break;
102 name); 128 case MSN_SERVCONN_ERROR_WRITE:
103 break; 129 reason = _("Writing error"); break;
104 case MSN_ERROR_WRITE: 130 case MSN_SERVCONN_ERROR_READ:
105 tmp = g_strdup_printf(_("Error writing to %s server"), name); 131 reason = _("Reading error"); break;
106 break;
107 case MSN_ERROR_READ:
108 cmd = servconn->cmdproc->last_trans;
109 tmp = g_strdup_printf(_("Error reading from %s server"), name);
110 gaim_debug_info("msn", "Last command was: %s\n", cmd);
111 break;
112 default: 132 default:
113 tmp = g_strdup_printf(_("Unknown error from %s server"), name); 133 reason = _("Unknown error"); break;
114 break; 134 }
115 } 135
116 136 tmp = g_strdup_printf(_("Connection error from %s server (%s):\n%s"),
117 if (servconn->type != MSN_SERVER_SB) 137 name, servconn->host, reason);
118 { 138
119 gaim_connection_error(gc, tmp); 139 if (servconn->type == MSN_SERVCONN_NS)
120 } 140 {
121 else 141 msn_session_set_error(servconn->session, MSN_ERROR_SERVCONN, tmp);
142 }
143 else if (servconn->type == MSN_SERVCONN_SB)
122 { 144 {
123 MsnSwitchBoard *swboard; 145 MsnSwitchBoard *swboard;
124 swboard = servconn->cmdproc->data; 146 swboard = servconn->cmdproc->data;
125 swboard->error = MSN_SB_ERROR_CONNECTION; 147 if (swboard != NULL)
126 } 148 swboard->error = MSN_SB_ERROR_CONNECTION;
149 }
150
151 msn_servconn_disconnect(servconn);
127 152
128 g_free(tmp); 153 g_free(tmp);
129 } 154 }
155
156 /**************************************************************************
157 * Connect
158 **************************************************************************/
130 159
131 static void 160 static void
132 connect_cb(gpointer data, gint source, GaimInputCondition cond) 161 connect_cb(gpointer data, gint source, GaimInputCondition cond)
133 { 162 {
134 MsnServConn *servconn = data; 163 MsnServConn *servconn = data;
144 servconn->fd = source; 173 servconn->fd = source;
145 174
146 if (source > 0) 175 if (source > 0)
147 { 176 {
148 servconn->connected = TRUE; 177 servconn->connected = TRUE;
149 servconn->cmdproc->ready = TRUE;
150 178
151 /* Someone wants to know we connected. */ 179 /* Someone wants to know we connected. */
152 servconn->connect_cb(servconn); 180 servconn->connect_cb(servconn);
153 servconn->inpa = gaim_input_add(servconn->fd, GAIM_INPUT_READ, 181 servconn->inpa = gaim_input_add(servconn->fd, GAIM_INPUT_READ,
154 read_cb, data); 182 read_cb, data);
155 } 183 }
156 else 184 else
157 { 185 {
158 servconn->cmdproc->error = MSN_ERROR_CONNECT; 186 msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_CONNECT);
159 show_error(servconn);
160 } 187 }
161 } 188 }
162 189
163 gboolean 190 gboolean
164 msn_servconn_connect(MsnServConn *servconn, const char *host, int port) 191 msn_servconn_connect(MsnServConn *servconn, const char *host, int port)
186 213
187 if (!servconn->httpconn->connected) 214 if (!servconn->httpconn->connected)
188 msn_httpconn_connect(servconn->httpconn, host, port); 215 msn_httpconn_connect(servconn->httpconn, host, port);
189 216
190 servconn->connected = TRUE; 217 servconn->connected = TRUE;
191 servconn->cmdproc->ready = TRUE;
192 servconn->httpconn->virgin = TRUE; 218 servconn->httpconn->virgin = TRUE;
193 219
194 /* Someone wants to know we connected. */ 220 /* Someone wants to know we connected. */
195 servconn->connect_cb(servconn); 221 servconn->connect_cb(servconn);
196 222
214 { 240 {
215 g_return_if_fail(servconn != NULL); 241 g_return_if_fail(servconn != NULL);
216 242
217 if (!servconn->connected) 243 if (!servconn->connected)
218 { 244 {
245 /* We could not connect. */
219 if (servconn->disconnect_cb != NULL) 246 if (servconn->disconnect_cb != NULL)
220 servconn->disconnect_cb(servconn); 247 servconn->disconnect_cb(servconn);
221 248
222 return; 249 return;
223 } 250 }
224 251
225 if (servconn->session->http_method) 252 if (servconn->session->http_method)
226 { 253 {
227 /* Fake disconnection */ 254 /* Fake disconnection. */
228 if (servconn->disconnect_cb != NULL) 255 if (servconn->disconnect_cb != NULL)
229 servconn->disconnect_cb(servconn); 256 servconn->disconnect_cb(servconn);
230 257
231 return; 258 return;
232 } 259 }
242 servconn->rx_buf = NULL; 269 servconn->rx_buf = NULL;
243 servconn->rx_len = 0; 270 servconn->rx_len = 0;
244 servconn->payload_len = 0; 271 servconn->payload_len = 0;
245 272
246 servconn->connected = FALSE; 273 servconn->connected = FALSE;
247 servconn->cmdproc->ready = FALSE;
248 274
249 if (servconn->disconnect_cb != NULL) 275 if (servconn->disconnect_cb != NULL)
250 servconn->disconnect_cb(servconn); 276 servconn->disconnect_cb(servconn);
251 } 277 }
252 278
253 void
254 msn_servconn_set_connect_cb(MsnServConn *servconn,
255 void (*connect_cb)(MsnServConn *))
256 {
257 g_return_if_fail(servconn != NULL);
258 servconn->connect_cb = connect_cb;
259 }
260
261 void
262 msn_servconn_set_disconnect_cb(MsnServConn *servconn,
263 void (*disconnect_cb)(MsnServConn *))
264 {
265 g_return_if_fail(servconn != NULL);
266
267 servconn->disconnect_cb = disconnect_cb;
268 }
269
270 void
271 msn_servconn_set_destroy_cb(MsnServConn *servconn,
272 void (*destroy_cb)(MsnServConn *))
273 {
274 g_return_if_fail(servconn != NULL);
275
276 servconn->destroy_cb = destroy_cb;
277 }
278
279 static void
280 failed_io(MsnServConn *servconn)
281 {
282 g_return_if_fail(servconn != NULL);
283
284 show_error(servconn);
285
286 msn_servconn_disconnect(servconn);
287 }
288
289 size_t 279 size_t
290 msn_servconn_write(MsnServConn *servconn, const char *buf, size_t len) 280 msn_servconn_write(MsnServConn *servconn, const char *buf, size_t len)
291 { 281 {
292 size_t ret = FALSE; 282 size_t ret = FALSE;
293 283
295 285
296 if (!servconn->session->http_method) 286 if (!servconn->session->http_method)
297 { 287 {
298 switch (servconn->type) 288 switch (servconn->type)
299 { 289 {
300 case MSN_SERVER_NS: 290 case MSN_SERVCONN_NS:
301 case MSN_SERVER_SB: 291 case MSN_SERVCONN_SB:
302 ret = write(servconn->fd, buf, len); 292 ret = write(servconn->fd, buf, len);
303 break; 293 break;
304 case MSN_SERVER_DC: 294 #if 0
295 case MSN_SERVCONN_DC:
305 ret = write(servconn->fd, &buf, sizeof(len)); 296 ret = write(servconn->fd, &buf, sizeof(len));
306 ret = write(servconn->fd, buf, len); 297 ret = write(servconn->fd, buf, len);
307 break; 298 break;
299 #endif
308 default: 300 default:
309 ret = write(servconn->fd, buf, len); 301 ret = write(servconn->fd, buf, len);
310 break; 302 break;
311 } 303 }
312 } 304 }
315 ret = msn_httpconn_write(servconn->httpconn, buf, len); 307 ret = msn_httpconn_write(servconn->httpconn, buf, len);
316 } 308 }
317 309
318 if (ret == -1) 310 if (ret == -1)
319 { 311 {
320 servconn->cmdproc->error = MSN_ERROR_WRITE; 312 msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE);
321 failed_io(servconn);
322 } 313 }
323 314
324 return ret; 315 return ret;
325 } 316 }
326 317
338 329
339 len = read(servconn->fd, buf, sizeof(buf) - 1); 330 len = read(servconn->fd, buf, sizeof(buf) - 1);
340 331
341 if (len <= 0) 332 if (len <= 0)
342 { 333 {
343 servconn->cmdproc->error = MSN_ERROR_READ; 334 msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ);
344
345 failed_io(servconn);
346 335
347 return; 336 return;
348 } 337 }
349 338
350 buf[len] = '\0'; 339 buf[len] = '\0';