comparison libgaim/dnssrv.c @ 14312:ef05f400817f

[gaim-migrate @ 17002] Fix the win32 method. I also changed the callback to be triggered asynchronously in the error case and had to add some supporting stuff. committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Wed, 23 Aug 2006 14:49:40 +0000
parents 9ad313800b19
children
comparison
equal deleted inserted replaced
14311:fda9dc44807d 14312:ef05f400817f
58 #endif 58 #endif
59 59
60 struct _GaimSrvQueryData { 60 struct _GaimSrvQueryData {
61 GaimSrvCallback cb; 61 GaimSrvCallback cb;
62 gpointer extradata; 62 gpointer extradata;
63 #ifndef _WIN32
64 guint handle; 63 guint handle;
65 #else 64 #ifdef _WIN32
66 GThread *resolver; 65 GThread *resolver;
67 char *query; 66 char *query;
68 char *error_message; 67 char *error_message;
69 GSList *results; 68 GSList *results;
70 #endif 69 #endif
206 { 205 {
207 GaimSrvResponse *srvres = NULL; 206 GaimSrvResponse *srvres = NULL;
208 int size = 0; 207 int size = 0;
209 GaimSrvQueryData *query_data = data; 208 GaimSrvQueryData *query_data = data;
210 209
211 if (query_data->error_message != NULL) { 210 if(query_data->error_message != NULL)
212 gaim_debug_error("dnssrv", query_data->error_message); 211 gaim_debug_error("dnssrv", query_data->error_message);
213 } else { 212 else {
214 GaimSrvResponse *srvres_tmp; 213 GaimSrvResponse *srvres_tmp = NULL;
215 GSList *lst = query_data->results; 214 GSList *lst = query_data->results;
216 215
217 size = g_slist_length(query_data->results); 216 size = g_slist_length(query_data->results);
218 217
219 srvres_tmp = srvres = g_new0(GaimSrvResponse, size); 218 if(query_data->cb)
219 srvres_tmp = srvres = g_new0(GaimSrvResponse, size);
220 while (lst) { 220 while (lst) {
221 memcpy(srvres_tmp++, lst->data, sizeof(GaimSrvResponse)); 221 if(query_data->cb)
222 memcpy(srvres_tmp++, lst->data, sizeof(GaimSrvResponse));
222 g_free(lst->data); 223 g_free(lst->data);
223 lst = g_slist_remove(lst, lst->data); 224 lst = g_slist_remove(lst, lst->data);
224 } 225 }
225 226
226 query_data->results = lst; 227 query_data->results = NULL;
227 } 228 }
228 229
229 gaim_debug_info("dnssrv", "found %d SRV entries\n", size); 230 gaim_debug_info("dnssrv", "found %d SRV entries\n", size);
230 231
231 query_data->cb(srvres, size, query_data->extradata); 232 if(query_data->cb)
233 query_data->cb(srvres, size, query_data->extradata);
234
235 query_data->resolver = NULL;
236 query_data->handle = 0;
232 237
233 gaim_srv_cancel(query_data); 238 gaim_srv_cancel(query_data);
234 239
235 return FALSE; 240 return FALSE;
236 } 241 }
274 MyDnsRecordListFree(dr, DnsFreeRecordList); 279 MyDnsRecordListFree(dr, DnsFreeRecordList);
275 query_data->results = lst; 280 query_data->results = lst;
276 } 281 }
277 282
278 /* back to main thread */ 283 /* back to main thread */
284 /* Note: this should *not* be attached to query_data->handle - it will cause leakage */
279 g_idle_add(res_main_thread_cb, query_data); 285 g_idle_add(res_main_thread_cb, query_data);
280 286
281 g_thread_exit(NULL); 287 g_thread_exit(NULL);
282 return NULL; 288 return NULL;
283 } 289 }
295 #else 301 #else
296 GError* err = NULL; 302 GError* err = NULL;
297 static gboolean initialized = FALSE; 303 static gboolean initialized = FALSE;
298 #endif 304 #endif
299 305
300 #ifndef _WIN32
301 query = g_strdup_printf("_%s._%s.%s", protocol, transport, domain); 306 query = g_strdup_printf("_%s._%s.%s", protocol, transport, domain);
302 gaim_debug_info("dnssrv","querying SRV record for %s\n", query); 307 gaim_debug_info("dnssrv","querying SRV record for %s\n", query);
303 308
309 #ifndef _WIN32
304 if(pipe(in) || pipe(out)) { 310 if(pipe(in) || pipe(out)) {
305 gaim_debug_error("dnssrv", "Could not create pipe\n"); 311 gaim_debug_error("dnssrv", "Could not create pipe\n");
306 g_free(query); 312 g_free(query);
307 cb(NULL, 0, extradata); 313 cb(NULL, 0, extradata);
308 return NULL; 314 return NULL;
344 MyDnsRecordListFree = (void*) wgaim_find_and_loadproc( 350 MyDnsRecordListFree = (void*) wgaim_find_and_loadproc(
345 "dnsapi.dll", "DnsRecordListFree"); 351 "dnsapi.dll", "DnsRecordListFree");
346 initialized = TRUE; 352 initialized = TRUE;
347 } 353 }
348 354
349 if (!MyDnsQuery_UTF8 || !MyDnsRecordListFree) {
350 gaim_debug_error("dnssrv", "System missing DNS API (Requires W2K+)\n");
351 g_free(query);
352 cb(NULL, 0, extradata);
353 return NULL;
354 }
355
356 query_data = g_new0(GaimSrvQueryData, 1); 355 query_data = g_new0(GaimSrvQueryData, 1);
357 query_data->cb = cb; 356 query_data->cb = cb;
358 query_data->query = query; 357 query_data->query = query;
359 query_data->extradata = extradata; 358 query_data->extradata = extradata;
359
360 if (!MyDnsQuery_UTF8 || !MyDnsRecordListFree) {
361 query_data->error_message = g_strdup_printf("System missing DNS API (Requires W2K+)\n");
362
363 /* Asynchronously call the callback since stuff may not expect
364 * the callback to be called before this returns */
365 query_data->handle = g_idle_add(res_main_thread_cb, query_data);
366
367 return query_data;
368 }
360 369
361 query_data->resolver = g_thread_create(res_thread, query_data, FALSE, &err); 370 query_data->resolver = g_thread_create(res_thread, query_data, FALSE, &err);
362 if (query_data->resolver == NULL) 371 if (query_data->resolver == NULL)
363 { 372 {
364 query_data->error_message = g_strdup_printf("SRV thread create failure: %s\n", err ? err->message : ""); 373 query_data->error_message = g_strdup_printf("SRV thread create failure: %s\n", err ? err->message : "");
365 g_error_free(err); 374 g_error_free(err);
366 res_main_thread_cb(query_data); 375
367 return NULL; 376 /* Asynchronously call the callback since stuff may not expect
377 * the callback to be called before this returns */
378 query_data->handle = g_idle_add(res_main_thread_cb, query_data);
379
380 return query_data;
368 } 381 }
369 382
370 return query_data; 383 return query_data;
371 #endif 384 #endif
372 } 385 }
373 386
374 void 387 void
375 gaim_srv_cancel(GaimSrvQueryData *query_data) 388 gaim_srv_cancel(GaimSrvQueryData *query_data)
376 { 389 {
377 #ifndef _WIN32
378 if (query_data->handle > 0) 390 if (query_data->handle > 0)
379 gaim_input_remove(query_data->handle); 391 gaim_input_remove(query_data->handle);
380 #else 392 #ifdef _WIN32
381 if (query_data->resolver != NULL) 393 if (query_data->resolver != NULL)
382 { 394 {
383 /* 395 /*
384 * It's not really possible to kill a thread. So instead we 396 * It's not really possible to kill a thread. So instead we
385 * just set the callback to NULL and let the DNS lookup 397 * just set the callback to NULL and let the DNS lookup
386 * finish. 398 * finish.
387 */ 399 */
388 query_data->callback = NULL; 400 query_data->cb = NULL;
389 return; 401 return;
390 } 402 }
391 g_free(query_data->query); 403 g_free(query_data->query);
392 g_free(query_data->error_message); 404 g_free(query_data->error_message);
393 #endif 405 #endif