Mercurial > pidgin.yaz
comparison src/dnssrv.c @ 11379:51c189755f1d
[gaim-migrate @ 13605]
Make the NTLM and dnssrv stuff compile on win32. This hasn't been tested very much (i.e. at all). When something starts using this stuff it'll get some testing love.
committer: Tailor Script <tailor@pidgin.im>
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Wed, 31 Aug 2005 00:00:31 +0000 |
parents | c84c35ee8202 |
children | e0f42900de12 |
comparison
equal
deleted
inserted
replaced
11378:3c88e4519fd1 | 11379:51c189755f1d |
---|---|
1 /** | 1 /** |
2 * @file srvresolve.c | 2 * @file dnssrv.c |
3 * | 3 * |
4 * gaim | 4 * gaim |
5 * | 5 * |
6 * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de> | 6 * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de> |
7 * | 7 * |
18 * You should have received a copy of the GNU General Public License | 18 * You should have received a copy of the GNU General Public License |
19 * along with this program; if not, write to the Free Software | 19 * along with this program; if not, write to the Free Software |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 */ | 21 */ |
22 #include <glib.h> | 22 #include <glib.h> |
23 #ifndef _WIN32 | |
23 #include <resolv.h> | 24 #include <resolv.h> |
24 #include <stdlib.h> | 25 #include <stdlib.h> |
25 #include <arpa/nameser_compat.h> | 26 #include <arpa/nameser_compat.h> |
26 #ifndef T_SRV | 27 #ifndef T_SRV |
27 #define T_SRV 33 | 28 #define T_SRV 33 |
29 #endif | |
30 #else | |
31 #include "win32dep.h" | |
32 #include <windns.h> | |
33 /* Missing from the mingw headers */ | |
34 #ifndef DNS_TYPE_SRV | |
35 # define DNS_TYPE_SRV 33 | |
36 #endif | |
28 #endif | 37 #endif |
29 | 38 |
30 #include "dnssrv.h" | 39 #include "dnssrv.h" |
31 #include <stdio.h> | 40 #include <stdio.h> |
32 #include <unistd.h> | 41 #include <unistd.h> |
33 #include <string.h> | 42 #include <string.h> |
34 #include "eventloop.h" | 43 #include "eventloop.h" |
35 #include "debug.h" | 44 #include "debug.h" |
36 | 45 |
46 #ifndef _WIN32 | |
37 typedef union { | 47 typedef union { |
38 HEADER hdr; | 48 HEADER hdr; |
39 u_char buf[1024]; | 49 u_char buf[1024]; |
40 } queryans; | 50 } queryans; |
51 #endif | |
41 | 52 |
42 struct resdata { | 53 struct resdata { |
43 SRVCallback cb; | 54 SRVCallback cb; |
55 #ifndef _WIN32 | |
44 guint handle; | 56 guint handle; |
57 #else | |
58 DNS_STATUS (*DnsQuery) (PCSTR lpstrName, WORD wType, DWORD fOptions, | |
59 PIP4_ARRAY aipServers, PDNS_RECORD* ppQueryResultsSet, PVOID* pReserved); | |
60 void (*DnsRecordListFree) (PDNS_RECORD pRecordList, DNS_FREE_TYPE FreeType); | |
61 char *query; | |
62 char *errmsg; | |
63 GSList *results; | |
64 #endif | |
45 }; | 65 }; |
46 | 66 |
47 static gint responsecompare(gconstpointer ar, gconstpointer br) { | 67 static gint responsecompare(gconstpointer ar, gconstpointer br) { |
48 struct srv_response *a = (struct srv_response*)ar; | 68 struct srv_response *a = (struct srv_response*)ar; |
49 struct srv_response *b = (struct srv_response*)br; | 69 struct srv_response *b = (struct srv_response*)br; |
57 } | 77 } |
58 if(a->pref < b->pref) | 78 if(a->pref < b->pref) |
59 return -1; | 79 return -1; |
60 return 1; | 80 return 1; |
61 } | 81 } |
62 | 82 #ifndef _WIN32 |
63 static void resolve(int in, int out) { | 83 static void resolve(int in, int out) { |
64 GList *ret = NULL; | 84 GList *ret = NULL; |
65 struct srv_response *srvres; | 85 struct srv_response *srvres; |
66 queryans answer; | 86 queryans answer; |
67 int size; | 87 int size; |
159 cb(res, size); | 179 cb(res, size); |
160 gaim_input_remove(rdata->handle); | 180 gaim_input_remove(rdata->handle); |
161 g_free(rdata); | 181 g_free(rdata); |
162 } | 182 } |
163 | 183 |
184 #else /* _WIN32 */ | |
185 | |
186 /** The Jabber Server code was inspiration for parts of this. */ | |
187 | |
188 static gboolean res_main_thread_cb(gpointer data) { | |
189 struct srv_response *srvres = NULL; | |
190 int size = 0; | |
191 struct resdata *rdata = data; | |
192 | |
193 if (rdata->errmsg != NULL) { | |
194 gaim_debug_error("srv", rdata->errmsg); | |
195 g_free(rdata->errmsg); | |
196 } else { | |
197 struct srv_response *srvres_tmp; | |
198 GSList *lst = rdata->results; | |
199 | |
200 size = g_slist_length(rdata->results); | |
201 | |
202 gaim_debug_info("srv","found %d SRV entries\n", size); | |
203 | |
204 srvres_tmp = srvres = g_malloc0(sizeof(struct srv_response) * size); | |
205 while (lst) { | |
206 memcpy(srvres_tmp++, lst->data, sizeof(struct srv_response)); | |
207 g_free(lst->data); | |
208 lst = g_slist_remove(lst, lst->data); | |
209 } | |
210 | |
211 rdata->results = lst; | |
212 } | |
213 | |
214 rdata->cb(srvres, size); | |
215 | |
216 g_free(rdata->query); | |
217 g_free(rdata); | |
218 | |
219 return FALSE; | |
220 } | |
221 | |
222 static gpointer res_thread(gpointer data) { | |
223 DNS_RECORD *dr = NULL, *dr_tmp; | |
224 GSList *lst = NULL; | |
225 struct srv_response *srvres; | |
226 DNS_SRV_DATA *srv_data; | |
227 int type = DNS_TYPE_SRV; | |
228 DNS_STATUS ds; | |
229 struct resdata *rdata = data; | |
230 | |
231 ds = rdata->DnsQuery(rdata->query, type, DNS_QUERY_STANDARD, NULL, &dr, NULL); | |
232 if (ds != ERROR_SUCCESS) { | |
233 rdata->errmsg = g_strdup_printf("Couldn't look up SRV record. Error = %d\n", (int) ds); | |
234 } else { | |
235 dr_tmp = dr; | |
236 while (dr_tmp != NULL) { | |
237 | |
238 /* Discard any incorrect entries. I'm not sure if this is necessary */ | |
239 if (dr_tmp->wType != type || strcmp(dr_tmp->pName, rdata->query) != 0) { | |
240 continue; | |
241 } | |
242 | |
243 srv_data = &dr_tmp->Data.SRV; | |
244 srvres = g_new0(struct srv_response, 1); | |
245 strncpy(srvres->hostname, srv_data->pNameTarget, 255); | |
246 srvres->hostname[255] = '\0'; | |
247 srvres->pref = srv_data->wPriority; | |
248 srvres->port = srv_data->wPort; | |
249 srvres->weight = srv_data->wWeight; | |
250 | |
251 lst = g_slist_insert_sorted(lst, srvres, responsecompare); | |
252 | |
253 dr_tmp = dr->pNext; | |
254 } | |
255 | |
256 rdata->DnsRecordListFree(dr, DnsFreeRecordList); | |
257 rdata->results = lst; | |
258 } | |
259 | |
260 /* back to main thread */ | |
261 g_idle_add(res_main_thread_cb, rdata); | |
262 | |
263 return 0; | |
264 } | |
265 | |
266 #endif | |
267 | |
164 void gaim_srv_resolve(char *protocol, char *transport, char *domain, SRVCallback cb) { | 268 void gaim_srv_resolve(char *protocol, char *transport, char *domain, SRVCallback cb) { |
165 char *query = g_strdup_printf("_%s._%s.%s",protocol, transport, domain); | 269 char *query = g_strdup_printf("_%s._%s.%s",protocol, transport, domain); |
270 struct resdata *rdata; | |
271 #ifndef _WIN32 | |
166 int in[2], out[2]; | 272 int in[2], out[2]; |
167 int pid; | 273 int pid; |
168 struct resdata *rdata; | 274 gaim_debug_info("srv","querying SRV record for %s\n", query); |
169 gaim_debug_info("dnssrv","querying SRV record for %s\n",query); | |
170 if(pipe(in) || pipe(out)) { | 275 if(pipe(in) || pipe(out)) { |
171 gaim_debug_error("srv", "Could not create pipe\n"); | 276 gaim_debug_error("srv", "Could not create pipe\n"); |
172 g_free(query); | 277 g_free(query); |
173 cb(NULL, 0); | 278 cb(NULL, 0); |
174 return; | 279 return; |
196 gaim_debug_error("srv", "Could not write to SRV resolver\n"); | 301 gaim_debug_error("srv", "Could not write to SRV resolver\n"); |
197 } | 302 } |
198 rdata = g_new0(struct resdata,1); | 303 rdata = g_new0(struct resdata,1); |
199 rdata->cb = cb; | 304 rdata->cb = cb; |
200 rdata->handle = gaim_input_add(out[0], GAIM_INPUT_READ, resolved, rdata); | 305 rdata->handle = gaim_input_add(out[0], GAIM_INPUT_READ, resolved, rdata); |
306 | |
201 g_free(query); | 307 g_free(query); |
202 } | 308 #else |
309 GError* err = NULL; | |
310 | |
311 static gboolean initialized = FALSE; | |
312 | |
313 static DNS_STATUS (*MyDnsQuery_UTF) ( | |
314 PCSTR lpstrName, WORD wType, DWORD fOptions, PIP4_ARRAY aipServers, | |
315 PDNS_RECORD* ppQueryResultsSet, PVOID* pReserved) = NULL; | |
316 static void (*MyDnsRecordListFree) (PDNS_RECORD pRecordList, DNS_FREE_TYPE FreeType) = NULL; | |
317 | |
318 gaim_debug_info("srv","querying SRV record for %s\n", query); | |
319 | |
320 if (!initialized) { | |
321 MyDnsQuery_UTF = (void*) wgaim_find_and_loadproc("dnsapi.dll", "DnsQuery_UTF"); | |
322 MyDnsRecordListFree = (void*) wgaim_find_and_loadproc( | |
323 "dnsapi.dll", "DnsRecordListFree"); | |
324 initialized = TRUE; | |
325 } | |
326 | |
327 | |
328 if (!MyDnsQuery_UTF || !MyDnsRecordListFree) { | |
329 gaim_debug_error("srv", "System missing DNS API (Requires W2K+)\n"); | |
330 g_free(query); | |
331 cb(NULL, 0); | |
332 return; | |
333 } | |
334 | |
335 rdata = g_new0(struct resdata, 1); | |
336 rdata->DnsQuery = MyDnsQuery_UTF; | |
337 rdata->DnsRecordListFree = MyDnsRecordListFree; | |
338 rdata->cb = cb; | |
339 rdata->query = query; | |
340 | |
341 if (!g_thread_create(res_thread, rdata, FALSE, &err)) { | |
342 rdata->errmsg = g_strdup_printf("SRV thread create failure: %s\n", err ? err->message : ""); | |
343 g_error_free(err); | |
344 res_main_thread_cb(rdata); | |
345 } | |
346 #endif | |
347 } | |
348 |