adns-ruby 0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/ruby
2
+ # This file is part of adns-ruby library
3
+
4
+ require 'rubygems'
5
+ require 'adns'
6
+ require 'pp'
7
+
8
+ domain=""
9
+ if ARGV.length != 1
10
+ $stderr.puts "usage: #{__FILE__} <domain>"
11
+ exit -1
12
+ else
13
+ domain = ARGV[0]
14
+ end
15
+
16
+ puts '* initializing adns..'
17
+ adns = ADNS::State.new
18
+ puts "* resolving TXT record of domain #{domain}.."
19
+ q = adns.submit(domain, ADNS::RR::TXT)
20
+ pp q.wait()
21
+ puts "query status: #{ADNS::status_to_s(q.check[:status])}"
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ abort '* GNU adns library missing.' unless have_library 'adns'
3
+ abort '* GNU adn_ header missing.' unless have_header 'adns.h'
4
+ create_makefile 'adns/adns'
@@ -0,0 +1,998 @@
1
+ /*
2
+ * Ruby interface to GNU adns asynchronous DNS client library.
3
+ * Copyright (C) 2013 Purushottam Tuladhar <purshottam.tuladhar@gmail.com>
4
+ *
5
+ * This program is free software; you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation; either version 2 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ */
15
+
16
+ #include <adns.h>
17
+ #include <ruby.h>
18
+
19
+ #include <errno.h>
20
+ #include <fcntl.h>
21
+ #include <string.h>
22
+ #include <sys/time.h>
23
+ #include <arpa/inet.h>
24
+ #include <sys/select.h>
25
+ #include <netinet/in.h>
26
+
27
+ #define VERSION "0.3"
28
+ #define CSTR2STR(cstr) ((cstr) ? rb_str_new2(cstr) : rb_str_new2(""))
29
+ #define CSTR2SYM(cstr) (rb_str_intern(CSTR2STR(cstr)))
30
+ #define CHECK_TYPE(v,t) (Check_Type(v, t))
31
+ #define DEFAULT_DIAG_FILEMODE "w"
32
+
33
+ typedef struct {
34
+ adns_state ads;
35
+ FILE *diagfile;
36
+ } rb_adns_state_t;
37
+
38
+ typedef struct {
39
+ adns_query adq;
40
+ rb_adns_state_t *rb_ads_r;
41
+ VALUE answer;
42
+ } rb_adns_query_t;
43
+
44
+ static VALUE mADNS; /* ADNS */
45
+ static VALUE mADNS__cState; /* ADNS::State */
46
+ static VALUE mADNS__cQuery; /* ADNS::Query */
47
+ static VALUE mADNS__mRR; /* ADNS::RR */
48
+ static VALUE mADNS__mStatus; /* ADNS::Status */
49
+ static VALUE mADNS__mIF; /* ADNS::IF */
50
+ static VALUE mADNS__mQF; /* ADNS::QF */
51
+ static VALUE mADNS__eError; /* ADNS::Error */
52
+ static VALUE mADNS__eLocalError; /* ADNS::LocalError */
53
+ static VALUE mADNS__eRemoteError; /* ADNS::RemoteError */
54
+ static VALUE mADNS__eQueryError; /* ADNS::QueryError */
55
+ static VALUE maDNS__ePermanentError;/* ADNS::PermanentError */
56
+ static VALUE mADNS__eNotReadyError; /* ADNS::NotReadyError */
57
+
58
+ static void adns_select_timeout(rb_adns_state_t *rb_ads_r, double t)
59
+ {
60
+ /*
61
+ * select call on adns query IO rather than file descriptors.
62
+ */
63
+ struct timeval **tv_mod = NULL, tv_buf, timeout, now;
64
+ int nfds, maxfds = 0;
65
+ fd_set rfds, wfds, efds;
66
+ int ecode;
67
+
68
+ timeout.tv_sec = t;
69
+ timeout.tv_usec = 0;
70
+ ecode = gettimeofday(&now, NULL);
71
+ if (ecode == -1)
72
+ rb_raise(mADNS__eError, strerror(ecode));
73
+ FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
74
+ adns_beforeselect(rb_ads_r->ads, &maxfds, &rfds, &wfds, &efds,
75
+ tv_mod, &tv_buf, &now);
76
+ ecode = select(maxfds, &rfds, &wfds, &efds, &timeout);
77
+ if (ecode == -1)
78
+ rb_raise(mADNS__eError, strerror(ecode));
79
+ ecode = gettimeofday(&now, NULL);
80
+ if (ecode == -1)
81
+ rb_raise(mADNS__eError, strerror(ecode));
82
+ adns_afterselect(rb_ads_r->ads, maxfds, &rfds, &wfds, &efds, &now);
83
+ }
84
+
85
+ /*
86
+ * call-seq: status_to_s(status) => String
87
+ *
88
+ * Convert adns status code to string representation.
89
+ */
90
+ static VALUE mADNS__status_to_s(VALUE self, VALUE a1)
91
+ {
92
+ adns_status status;
93
+ const char *s;
94
+
95
+ CHECK_TYPE(a1, T_FIXNUM);
96
+ status = FIX2INT(a1);
97
+ s = adns_strerror(status);
98
+ return CSTR2STR(s);
99
+ }
100
+
101
+ /*
102
+ * call-seq: status_to_ss(status) => String
103
+ *
104
+ * Convert adns status code to short abbreviation string representation.
105
+ */
106
+ static VALUE mADNS__status_to_ss(VALUE self, VALUE a1)
107
+ {
108
+ adns_status status;
109
+ const char *s;
110
+
111
+ CHECK_TYPE(a1, T_FIXNUM);
112
+ status = FIX2INT(a1);
113
+ s = adns_errabbrev(status);
114
+ return CSTR2STR(s);
115
+ }
116
+
117
+ void __rdata_modify(VALUE data)
118
+ {
119
+ struct RData *data_r = (struct RData *)data;
120
+ long data_len = sizeof(data_r->data);
121
+ VALUE *ptr = ALLOC_N(VALUE, data_len);
122
+ MEMCPY(ptr, data_r->data, VALUE, data_len);
123
+ }
124
+ #define RDATA_MODIFY(d) (__rdata_modify(d))
125
+
126
+ static VALUE parse_adns_rr_addr(adns_rr_addr *addr_r)
127
+ {
128
+ const char *addr_str = inet_ntoa(addr_r->addr.inet.sin_addr);
129
+ if (!addr_str)
130
+ return CSTR2STR("");
131
+ else
132
+ return CSTR2STR(addr_str);
133
+ }
134
+
135
+ static VALUE parse_adns_rr_hostaddr(adns_rr_hostaddr *hostaddr_r)
136
+ {
137
+ VALUE rb_hostaddr = rb_hash_new();
138
+ VALUE host_k = CSTR2SYM("host");
139
+ VALUE host_v = CSTR2STR(hostaddr_r->host);
140
+ VALUE status_k = CSTR2SYM("status");
141
+ VALUE status_v = INT2FIX(hostaddr_r->astatus);
142
+ VALUE addrs_k = CSTR2SYM("addr");
143
+ VALUE addrs_v = rb_ary_new();
144
+ int idx;
145
+
146
+ if (hostaddr_r->naddrs > 0)
147
+ for (idx=0; idx < hostaddr_r->naddrs; idx++)
148
+ rb_ary_store(addrs_v, idx, parse_adns_rr_addr(hostaddr_r->addrs+idx));
149
+
150
+ rb_hash_aset(rb_hostaddr, host_k, host_v);
151
+ rb_hash_aset(rb_hostaddr, status_k, status_v);
152
+ rb_hash_aset(rb_hostaddr, addrs_k, addrs_v);
153
+
154
+ return rb_hostaddr;
155
+ }
156
+
157
+
158
+ static VALUE parse_adns_rr_soa(adns_rr_soa *soa_r)
159
+ {
160
+ VALUE rb_soa = rb_hash_new();
161
+ VALUE mname_k = CSTR2SYM("mname");
162
+ VALUE mname_v = CSTR2STR(soa_r->mname);
163
+ VALUE rname_k = CSTR2SYM("rname");
164
+ VALUE rname_v = CSTR2STR(soa_r->rname);
165
+ VALUE serial_k = CSTR2SYM("serial");
166
+ VALUE serial_v = INT2FIX(soa_r->serial);
167
+ VALUE refresh_k = CSTR2SYM("refresh");
168
+ VALUE refresh_v = INT2FIX(soa_r->refresh);
169
+ VALUE retry_k = CSTR2SYM("retry");
170
+ VALUE retry_v = INT2FIX(soa_r->retry);
171
+ VALUE minimum_k = CSTR2SYM("minimum");
172
+ VALUE mimimum_v = INT2FIX(soa_r->minimum);
173
+
174
+ rb_hash_aset(rb_soa, mname_k, mname_v);
175
+ rb_hash_aset(rb_soa, rname_k, rname_v);
176
+ rb_hash_aset(rb_soa, serial_k, serial_v);
177
+ rb_hash_aset(rb_soa, refresh_k, refresh_v);
178
+ rb_hash_aset(rb_soa, retry_k, retry_v);
179
+ rb_hash_aset(rb_soa, minimum_k, mimimum_v);
180
+
181
+ return rb_soa;
182
+ }
183
+
184
+
185
+ static VALUE parse_adns_rr_srv(adns_rr_srvraw *srvraw_r, adns_rr_srvha *srvha_r)
186
+ {
187
+ VALUE rb_srv = rb_hash_new();
188
+ VALUE priority_k = CSTR2SYM("priority"), priority_v;
189
+ VALUE weight_k = CSTR2SYM("weight"), weight_v;
190
+ VALUE port_k = CSTR2SYM("port"), port_v;
191
+ VALUE host_k = CSTR2SYM("host"), host_v;
192
+ VALUE addrs_k = CSTR2SYM("addrs"), addrs_v;
193
+
194
+ if (srvraw_r)
195
+ {
196
+ priority_v = INT2FIX(srvraw_r->priority);
197
+ weight_v = INT2FIX(srvraw_r->weight);
198
+ port_v = INT2FIX(srvraw_r->port);
199
+ host_v = CSTR2STR(srvraw_r->host);
200
+ rb_hash_aset(rb_srv, host_k, host_v);
201
+ }
202
+ else if (srvha_r)
203
+ {
204
+ priority_v = INT2FIX(srvha_r->priority);
205
+ weight_v = INT2FIX(srvha_r->weight);
206
+ port_v = INT2FIX(srvha_r->port);
207
+ addrs_v = parse_adns_rr_hostaddr(&srvha_r->ha);
208
+ rb_hash_aset(rb_srv, addrs_k, addrs_v);
209
+ }
210
+
211
+ rb_hash_aset(rb_srv, priority_k, priority_v);
212
+ rb_hash_aset(rb_srv, weight_k, weight_v);
213
+ rb_hash_aset(rb_srv, port_k, port_v);
214
+
215
+ return rb_srv;
216
+ }
217
+
218
+
219
+ static VALUE parse_adns_answer(adns_answer *answer_r)
220
+ {
221
+ VALUE rb_answer = rb_ary_new2(answer_r->nrrs);;
222
+ adns_rrtype t = answer_r->type & adns_rrt_typemask;
223
+ adns_rrtype t_dref = answer_r->type & adns__qtf_deref;
224
+ int idx, ecode;
225
+
226
+ if (answer_r->nrrs == 0)
227
+ /* something went wrong! */
228
+ return rb_answer;
229
+
230
+ for (idx=0; idx < answer_r->nrrs; idx++)
231
+ {
232
+ VALUE v; /* record specific value */
233
+
234
+ /* A, ADDR RECORD */
235
+ if (t == adns_r_a)
236
+ if (t_dref)
237
+ v = parse_adns_rr_addr(answer_r->rrs.addr+idx);
238
+ else
239
+ {
240
+ const char *addr_buf;
241
+ struct in_addr *inaddr_r = answer_r->rrs.inaddr+idx;
242
+ addr_buf = inet_ntoa(*inaddr_r);
243
+ if (ecode)
244
+ v = CSTR2STR("");
245
+ else
246
+ v = CSTR2STR(addr_buf);
247
+ }
248
+ /* NS, NS_RAW RECORD */
249
+ else if (t == adns_r_ns_raw)
250
+ if (t_dref)
251
+ v = parse_adns_rr_hostaddr(answer_r->rrs.hostaddr+idx);
252
+ else
253
+ v = CSTR2STR(answer_r->rrs.str[idx]);
254
+ /* CNAME, PTR, PTR_RAW RECORD */
255
+ else if (t == adns_r_cname ||
256
+ t == adns_r_ptr ||
257
+ t == adns_r_ptr_raw)
258
+ v = CSTR2STR(answer_r->rrs.str[idx]);
259
+ /* SOA, SOA_RAW RECORD */
260
+ else if (t == adns_r_soa_raw)
261
+ v = parse_adns_rr_soa(answer_r->rrs.soa+idx);
262
+ /* HINFO RECORD */
263
+ else if (t == adns_r_hinfo)
264
+ {
265
+ adns_rr_intstrpair *intstrpair_r = answer_r->rrs.intstrpair+idx;
266
+ const char *str1 = intstrpair_r->array[0].str;
267
+ const char *str2 = intstrpair_r->array[1].str;
268
+ v = rb_ary_new();
269
+ VALUE v1 = rb_ary_new();
270
+ VALUE v2 = rb_ary_new();
271
+
272
+ rb_ary_store(v1, 0, INT2FIX(intstrpair_r->array[0].i));
273
+ rb_ary_store(v1, 1, str1 ? CSTR2STR(str1) : CSTR2STR(""));
274
+ rb_ary_store(v2, 0, INT2FIX(intstrpair_r->array[1].i));
275
+ rb_ary_store(v2, 1, str2 ? CSTR2STR(str2) : CSTR2STR(""));
276
+ rb_ary_store(v, 0, v1);
277
+ rb_ary_store(v, 1, v2);
278
+ }
279
+ /* MX, MX_RAW RECORD */
280
+ else if (t == adns_r_mx_raw)
281
+ {
282
+ v = rb_hash_new();
283
+ VALUE preference_k = CSTR2SYM("preference"), preference_v;
284
+
285
+ if (t_dref) {
286
+ adns_rr_inthostaddr *inthostaddr_r = answer_r->rrs.inthostaddr+idx;
287
+ preference_v = INT2FIX(inthostaddr_r->i);
288
+ v = parse_adns_rr_hostaddr(&inthostaddr_r->ha);
289
+ } else {
290
+ adns_rr_intstr *intstr_r = answer_r->rrs.intstr+idx;
291
+ preference_v = INT2FIX(intstr_r->i);
292
+ VALUE host_k = CSTR2SYM("host");
293
+ VALUE host_v = CSTR2STR(intstr_r->str);
294
+ rb_hash_aset(v, host_k, host_v);
295
+ }
296
+ rb_hash_aset(v, preference_k, preference_v);
297
+ }
298
+ /* TXT RECORD */
299
+ else if (t == adns_r_txt)
300
+ {
301
+ adns_rr_intstr *intstr_r = answer_r->rrs.manyistr[idx];
302
+ v = CSTR2STR(intstr_r->str);
303
+ }
304
+ /* RP RP_RAW RECORD */
305
+ else if (t == adns_r_rp)
306
+ {
307
+ adns_rr_strpair *strpair_r = answer_r->rrs.strpair+idx;
308
+ v = rb_ary_new2(2);
309
+ rb_ary_store(v, 0, CSTR2STR(strpair_r->array[0]));
310
+ rb_ary_store(v, 1, CSTR2STR(strpair_r->array[1]));
311
+ }
312
+ /* SRV, SRV_RAW RECORD */
313
+ else if (t == adns_r_srv)
314
+ {
315
+ if (t_dref) {
316
+ adns_rr_srvraw *srvraw_r = answer_r->rrs.srvraw+idx;
317
+ v = parse_adns_rr_srv(srvraw_r, NULL);
318
+ } else {
319
+ adns_rr_srvha *srvha_r = answer_r->rrs.srvha+idx;
320
+ v = parse_adns_rr_srv(NULL, srvha_r);
321
+ }
322
+ }
323
+ /* UNKNOWN RECORD */
324
+ else
325
+ v = rb_hash_new();
326
+ /* push value to answer array */
327
+ rb_ary_store(rb_answer, idx, v);
328
+ }
329
+ return rb_answer;
330
+ }
331
+
332
+ static VALUE cQuery_init(VALUE self)
333
+ {
334
+ return self;
335
+ }
336
+
337
+ static void cQuery_mark(void *ptr)
338
+ {
339
+ rb_adns_query_t *rb_adq_r = (rb_adns_query_t *)ptr;
340
+ rb_gc_mark(rb_adq_r->answer);
341
+ }
342
+
343
+ static void cQuery_free(void *ptr)
344
+ {
345
+ rb_adns_query_t *rb_adq_r = (rb_adns_query_t *)ptr;
346
+ rb_adq_r->rb_ads_r = NULL;
347
+ rb_adq_r->adq = NULL;
348
+ rb_adq_r->answer = Qnil;
349
+ (void) free(rb_adq_r);
350
+ }
351
+
352
+ /*
353
+ * call-seq: check => Hash or raises ADNS::NotReadyError
354
+ *
355
+ * Check pending asynchronous request and retrieve answer or raises ADNS::NotReadyError, if request is still pending.
356
+ */
357
+ static VALUE cQuery_check(VALUE self)
358
+ {
359
+ rb_adns_query_t *rb_adq_r;
360
+ adns_answer *answer_r;
361
+ int ecode;
362
+
363
+ Data_Get_Struct(self, rb_adns_query_t, rb_adq_r);
364
+ if (rb_adq_r->answer != Qnil)
365
+ return rb_adq_r->answer;
366
+ if (!rb_adq_r->adq)
367
+ rb_raise(mADNS__eQueryError, "invalid query");
368
+ ecode = adns_check(rb_adq_r->rb_ads_r->ads, &rb_adq_r->adq, &answer_r, NULL);
369
+ if (ecode)
370
+ {
371
+ if (ecode == EWOULDBLOCK)
372
+ rb_raise(mADNS__eNotReadyError, strerror(ecode));
373
+ else
374
+ {
375
+ rb_adq_r->adq = NULL;
376
+ rb_raise(mADNS__eError, strerror(ecode));
377
+ }
378
+ }
379
+ rb_adq_r->answer = rb_hash_new();
380
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("type"), INT2FIX(answer_r->type));
381
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("owner"), CSTR2STR(answer_r->owner));
382
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("status"), INT2FIX(answer_r->status));
383
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("expires"), INT2FIX(answer_r->expires));
384
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("answer"), parse_adns_answer(answer_r));
385
+ rb_adq_r->adq = NULL; /* mark query as completed, thus making it invalid */
386
+ return rb_adq_r->answer;
387
+ }
388
+
389
+ /*
390
+ * call-seq: wait() => Hash
391
+ *
392
+ * Wait until answer is received.
393
+ */
394
+ static VALUE cQuery_wait(int argc, VALUE argv[], VALUE self)
395
+ {
396
+ rb_adns_query_t *rb_adq_r;
397
+ adns_answer *answer_r;
398
+ int ecode;
399
+
400
+ Data_Get_Struct(self, rb_adns_query_t, rb_adq_r);
401
+ if (rb_adq_r->answer != Qnil)
402
+ return rb_adq_r->answer;
403
+ if (!rb_adq_r->adq)
404
+ rb_raise(mADNS__eQueryError, "query invalidated");
405
+ ecode = adns_wait(rb_adq_r->rb_ads_r->ads, &rb_adq_r->adq, &answer_r, NULL);
406
+ if (ecode)
407
+ {
408
+ rb_adq_r->adq = NULL;
409
+ rb_adq_r->answer = Qnil;
410
+ rb_raise(mADNS__eError, strerror(ecode));
411
+ }
412
+ rb_adq_r->answer = rb_hash_new();
413
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("type"), INT2FIX(answer_r->type));
414
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("owner"), CSTR2STR(answer_r->owner));
415
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("status"), INT2FIX(answer_r->status));
416
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("expires"), INT2FIX(answer_r->expires));
417
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("answer"), parse_adns_answer(answer_r));
418
+ rb_adq_r->adq = NULL;
419
+ return rb_adq_r->answer;
420
+ }
421
+
422
+ /*
423
+ * call-seq: cancel() => nil
424
+ *
425
+ * Cancel current pending asynchronous request.
426
+ */
427
+ static VALUE cQuery_cancel(VALUE self)
428
+ {
429
+ rb_adns_query_t *rb_adq_r;
430
+ int ecode;
431
+
432
+ Data_Get_Struct(self, rb_adns_query_t, rb_adq_r);
433
+ if (!rb_adq_r->adq)
434
+ rb_raise(mADNS__eQueryError, "query invalidated");
435
+ (void) adns_cancel(rb_adq_r->adq);
436
+ cQuery_free((void *)rb_adq_r);
437
+ return Qnil;
438
+ }
439
+
440
+
441
+ /*
442
+ * call-seq: submit(domain, type[, qflags]) => ADNS::Query instance
443
+ *
444
+ * Submit asynchronous request to resolve domain <domain> of record type <type> using optional query flags <qflags>.
445
+ */
446
+ static VALUE cState_submit(int argc, VALUE argv[], VALUE self)
447
+ {
448
+ rb_adns_query_t *rb_adq_r = ALLOC(rb_adns_query_t);
449
+ const char *owner;
450
+ adns_rrtype type;
451
+ adns_queryflags qflags = adns_qf_owner;
452
+ VALUE query; /* return instance */
453
+ int ecode;
454
+
455
+ Data_Get_Struct(self, rb_adns_state_t, rb_adq_r->rb_ads_r);
456
+ if (argc < 2)
457
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
458
+ else if (argc > 3)
459
+ rb_raise(rb_eArgError, "excess number of arguments (%d for 3)", argc);
460
+ CHECK_TYPE(argv[0], T_STRING); /* DOMAIN */
461
+ CHECK_TYPE(argv[1], T_FIXNUM); /* RR */
462
+ if (argc == 3)
463
+ CHECK_TYPE(argv[2], T_FIXNUM); /* QFlags */
464
+ owner = STR2CSTR(argv[0]);
465
+ type = FIX2INT(argv[1]);
466
+ if (argc == 3)
467
+ qflags |= FIX2INT(argv[2]);
468
+ rb_adq_r->answer = Qnil;
469
+ query = Data_Wrap_Struct(mADNS__cQuery, cQuery_mark, cQuery_free, rb_adq_r);
470
+ ecode = adns_submit(rb_adq_r->rb_ads_r->ads, owner, type, qflags, (void *)query, &rb_adq_r->adq);
471
+ if (ecode)
472
+ rb_raise(mADNS__eError, strerror(ecode));
473
+ rb_obj_call_init(query, 0, 0);
474
+ return query;
475
+ }
476
+
477
+ /*
478
+ * call-seq: submit_reverse(ipaddr, type[, qflags]) => ADNS::Query object
479
+ *
480
+ * Submit asynchronous request to reverse lookup address <ipaddr> using optional query flags <qflags>.
481
+ * Note: <type> can only be ADNS::RR::PTR or ADNS::RR::PTR_RAW
482
+ */
483
+ static VALUE cState_submit_reverse(int argc, VALUE argv[], VALUE self)
484
+ {
485
+ VALUE query; /* return instance */
486
+ rb_adns_query_t *rb_adq_r = ALLOC(rb_adns_query_t);
487
+ const char *owner;
488
+ struct sockaddr_in addr;
489
+ adns_rrtype type;
490
+ adns_queryflags qflags = adns_qf_owner;
491
+ int idx, ecode;
492
+
493
+ if (argc < 2)
494
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
495
+ if (argc > 3)
496
+ rb_raise(rb_eArgError, "excess number of arguments (%d for 2)", argc);
497
+ CHECK_TYPE(argv[0], T_STRING);
498
+ CHECK_TYPE(argv[1], T_FIXNUM);
499
+ if (argc == 3)
500
+ CHECK_TYPE(argv[2], T_FIXNUM);
501
+ owner = STR2CSTR(argv[0]);
502
+ type = FIX2INT(argv[1]);
503
+ if (argc == 3)
504
+ qflags |= FIX2INT(argv[2]);
505
+ switch(type)
506
+ {
507
+ case adns_r_ptr:
508
+ case adns_r_ptr_raw:
509
+ break;
510
+ default:
511
+ rb_raise(rb_eArgError, "invalid record type (PTR or PTR_RAW record expected)");
512
+ }
513
+ addr.sin_family = AF_INET;
514
+ ecode = inet_aton(owner, &addr.sin_addr);
515
+ if (ecode == -1)
516
+ rb_raise(mADNS__eQueryError, "invalid ip address");
517
+ Data_Get_Struct(self, rb_adns_state_t, rb_adq_r->rb_ads_r);
518
+ rb_adq_r->answer = Qnil;
519
+ query = Data_Wrap_Struct(mADNS__cQuery, cQuery_mark, cQuery_free, rb_adq_r);
520
+ rb_obj_call_init(query, 0, 0);
521
+ ecode = adns_submit_reverse(rb_adq_r->rb_ads_r->ads, (struct sockaddr *) &addr,
522
+ type, qflags, (void *)query, &rb_adq_r->adq);
523
+ if (ecode)
524
+ rb_raise(mADNS__eError, strerror(ecode));
525
+ return query;
526
+ }
527
+
528
+ /*
529
+ * call-seq: submit_reverse_any(ip_addr, type[, qflags]) => ADNS::Query instance
530
+ *
531
+ * Submit asynchronous request to reverse lookup address <ipaddr> using optional query flags <qflags>.
532
+ * Note: <type> can any resource record.
533
+ */
534
+ static VALUE cState_submit_reverse_any(int argc, VALUE argv[], VALUE self)
535
+ {
536
+ VALUE query; /* return instance */
537
+ rb_adns_query_t *rb_adq_r = ALLOC(rb_adns_query_t);
538
+ const char *owner;
539
+ struct sockaddr_in addr;
540
+ const char *zone; /* in-addr.arpa or any other reverse zones */
541
+ adns_rrtype type = adns_r_none;
542
+ adns_queryflags qflags = adns_qf_owner;
543
+ int idx, ecode;
544
+
545
+ Data_Get_Struct(self, rb_adns_state_t, rb_adq_r->rb_ads_r);
546
+ if (argc < 3)
547
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 3)", argc);
548
+ if (argc > 4)
549
+ rb_raise(rb_eArgError, "excess number of arguments (%d for 4)", argc);
550
+ CHECK_TYPE(argv[0], T_STRING); /* IP */
551
+ CHECK_TYPE(argv[1], T_STRING); /* Zone */
552
+ CHECK_TYPE(argv[2], T_FIXNUM); /* RR */
553
+ if (argc == 4)
554
+ CHECK_TYPE(argv[3], T_FIXNUM); /* )); */
555
+ owner = STR2CSTR(argv[0]);
556
+ zone = STR2CSTR(argv[1]);
557
+ type = FIX2INT(argv[2]);
558
+ if (argc == 4)
559
+ qflags |= FIX2INT(argv[3]);
560
+ addr.sin_family = AF_INET;
561
+ ecode = inet_aton(owner, &addr.sin_addr);
562
+ if (ecode == 0)
563
+ rb_raise(mADNS__eQueryError, "invalid ip address");
564
+ rb_adq_r->answer = Qnil;
565
+ query = Data_Wrap_Struct(mADNS__cQuery, cQuery_mark, cQuery_free, rb_adq_r);
566
+ rb_obj_call_init(query, 0, 0);
567
+ ecode = adns_submit_reverse_any(rb_adq_r->rb_ads_r->ads, (struct sockaddr*)&addr,
568
+ zone, type, qflags, (void *)query, &rb_adq_r->adq);
569
+ if (ecode)
570
+ rb_raise(mADNS__eError, strerror(ecode));
571
+ return query;
572
+ }
573
+
574
+ /*
575
+ * call-seq: completed() => Array
576
+ *
577
+ * Returns an array of all the completed (ADNS::Query) queries submitted using ADNS::State.submit_*() methods.
578
+ */
579
+ static VALUE cState_completed_queries(int argc, VALUE argv[], VALUE self)
580
+ {
581
+ VALUE a1, query_list = rb_ary_new();
582
+ VALUE query_ctx; /* ADNS::Query context passed from one of the submit_* */
583
+ rb_adns_state_t *rb_ads_r;
584
+ rb_adns_query_t *rb_adq_r;
585
+ adns_query adq;
586
+ adns_answer *answer_r;
587
+ double timeout;
588
+ int ecode;
589
+
590
+ if (argc == 1)
591
+ {
592
+ a1 = argv[0];
593
+ CHECK_TYPE(a1, T_FLOAT);
594
+ }
595
+ else
596
+ a1 = rb_float_new(0.0);
597
+ timeout = (double) RFLOAT_VALUE(a1);
598
+ Data_Get_Struct(self, rb_adns_state_t, rb_ads_r);
599
+ (void) adns_select_timeout(rb_ads_r, timeout);
600
+ for (adns_forallqueries_begin(rb_ads_r->ads);
601
+ (adq = adns_forallqueries_next(rb_ads_r->ads, 0)) != 0;)
602
+ {
603
+ ecode = adns_check(rb_ads_r->ads, &adq, &answer_r, (void **)&query_ctx);
604
+ if (ecode)
605
+ if (ecode == EWOULDBLOCK)
606
+ continue;
607
+ Data_Get_Struct(query_ctx, rb_adns_query_t, rb_adq_r);
608
+ rb_adq_r->answer = rb_hash_new();
609
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("type"), INT2FIX(answer_r->type));
610
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("owner"), CSTR2STR(answer_r->owner));
611
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("status"), INT2FIX(answer_r->status));
612
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("expires"), INT2FIX(answer_r->expires));
613
+ rb_hash_aset(rb_adq_r->answer, CSTR2SYM("answer"), parse_adns_answer(answer_r));
614
+ rb_adq_r->adq = NULL;
615
+ free(answer_r);
616
+ rb_ary_push(query_list, query_ctx);
617
+ }
618
+ return query_list;
619
+ }
620
+
621
+ /*
622
+ * call-seq: synchronous(domain, type[, qflags]) => Hash
623
+ *
624
+ * Submit synchronous request to resolve domain <domain> of record type <type> using optional query flags <qflags>.
625
+ */
626
+ static VALUE cState_synchronous(int argc, VALUE argv[], VALUE self)
627
+ {
628
+ VALUE answer = rb_hash_new(); /* return instance */
629
+ rb_adns_state_t *rb_ads_r;
630
+ adns_answer *answer_r;
631
+ adns_queryflags qflags = adns_qf_owner;
632
+ adns_rrtype type = adns_r_none;
633
+ const char *owner;
634
+ int ecode;
635
+
636
+ Data_Get_Struct(self, rb_adns_state_t, rb_ads_r);
637
+ if (argc < 2)
638
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
639
+ if (argc > 3)
640
+ rb_raise(rb_eArgError, "excess number of arguments (%d for 3)", argc);
641
+ CHECK_TYPE(argv[0], T_STRING); /* DOMAIN */
642
+ CHECK_TYPE(argv[1], T_FIXNUM); /* RR */
643
+ if (argc == 3)
644
+ CHECK_TYPE(argv[2], T_FIXNUM); /* QFlags */
645
+ owner = STR2CSTR(argv[0]);
646
+ type = FIX2INT(argv[1]);
647
+ if (argc == 3)
648
+ qflags |= FIX2INT(argv[2]);
649
+ ecode = adns_synchronous(rb_ads_r->ads, owner, type, qflags, &answer_r);
650
+ if (ecode)
651
+ rb_raise(mADNS__eError, adns_strerror(ecode));
652
+ /* populate return hash */
653
+ rb_hash_aset(answer, CSTR2SYM("type"), INT2FIX(answer_r->type));
654
+ rb_hash_aset(answer, CSTR2SYM("owner"), CSTR2STR(answer_r->owner));
655
+ rb_hash_aset(answer, CSTR2SYM("status"), INT2FIX(answer_r->status));
656
+ rb_hash_aset(answer, CSTR2SYM("expires"), INT2FIX(answer_r->expires));
657
+ rb_hash_aset(answer, CSTR2SYM("answer"), Qnil);
658
+ if (answer_r->nrrs == 0)
659
+ return answer;
660
+ else
661
+ rb_hash_aset(answer, CSTR2SYM("answer"), parse_adns_answer(answer_r));
662
+ return answer;
663
+ }
664
+
665
+ /*
666
+ * call-seq: global_system_failure() => nil
667
+ *
668
+ * Call this function, If serious problem(s) occurs with adns library.
669
+ * All currently outstanding queries will be made to fail with ADNS::Status::SystemFail
670
+ * status code and adns library will close any stream sockets it has open since inception.
671
+ */
672
+ static VALUE cState_global_system_failure(VALUE self)
673
+ {
674
+ rb_adns_state_t *rb_ads_r;
675
+ Data_Get_Struct(self, rb_adns_state_t, rb_ads_r);
676
+ (void) adns_globalsystemfailure(rb_ads_r->ads);
677
+ return Qnil;
678
+ }
679
+
680
+ static VALUE cState_initialize(int argc, VALUE argv[], VALUE self)
681
+ {
682
+ return self;
683
+ }
684
+
685
+ static void cState_free(void *ptr)
686
+ {
687
+ rb_adns_state_t *rb_ads_r = (rb_adns_state_t *) ptr;
688
+ (void) adns_finish(rb_ads_r->ads);
689
+ if (rb_ads_r->diagfile)
690
+ (void) fclose(rb_ads_r->diagfile);
691
+ free(rb_ads_r);
692
+ }
693
+
694
+ static void cState_mark(void *ptr)
695
+ {
696
+ return;
697
+ }
698
+
699
+ /*
700
+ * call-seq: new([iflags, filename, filemode]) => ADNS::State object
701
+ *
702
+ * Create new ADNS::State object and initialize adns library using optional initialization
703
+ * flags <iflags>, debug log to filename <filename> (*only available if ADNS::IF::DEBUG flag is given*),
704
+ * debug log filemode <filemode>.
705
+ */
706
+ static VALUE cState_new(int argc, VALUE argv[], VALUE self)
707
+ {
708
+ VALUE state; /* return instance */
709
+ rb_adns_state_t *rb_ads_r = ALLOC(rb_adns_state_t);
710
+ rb_ads_r->ads = NULL;
711
+ rb_ads_r->diagfile = NULL;
712
+ adns_initflags iflags = adns_if_none;
713
+ const char *fname, *fmode;
714
+
715
+ if (argc > 3)
716
+ rb_raise(rb_eArgError, "excess number of arguments (%d for 3)", argc);
717
+ if (argc >= 1)
718
+ {
719
+ CHECK_TYPE(argv[0], T_FIXNUM);
720
+ iflags |= FIX2INT(argv[0]);
721
+ if (argc >= 2)
722
+ {
723
+ CHECK_TYPE(argv[1], T_STRING);
724
+ fname = STR2CSTR(argv[1]);
725
+ if (argc == 3)
726
+ {
727
+ CHECK_TYPE(argv[2], T_STRING);
728
+ fmode = STR2CSTR(argv[2]);
729
+ } else
730
+ fmode = DEFAULT_DIAG_FILEMODE;
731
+ rb_ads_r->diagfile = fopen(fname, fmode);
732
+ if (!rb_ads_r->diagfile)
733
+ rb_raise(rb_eIOError, "%s - %s", strerror(errno), fname);
734
+ }
735
+ }
736
+ adns_init(&rb_ads_r->ads, iflags, rb_ads_r->diagfile);
737
+ state = Data_Wrap_Struct(mADNS__cState, cState_mark, cState_free, rb_ads_r);
738
+ rb_obj_call_init(state, 0, 0);
739
+ return state;
740
+ }
741
+
742
+ /*
743
+ * call-seq: new2(configtext, [iflags, filename, filemode]) => ADNS::State object
744
+ *
745
+ * Create new ADNS::State object and initialize adns library using resolve.conf style
746
+ * configuration text and optional initialization
747
+ * flags <iflags>, debug log to filename <filename> (*only available if ADNS::IF::DEBUG flag is given*),
748
+ * debug log filemode <filemode>.
749
+ */
750
+ static VALUE cState_new2(int argc, VALUE argv[], VALUE self)
751
+ {
752
+ VALUE state; /* return instance */
753
+ rb_adns_state_t *rb_ads_r = ALLOC(rb_adns_state_t);
754
+ rb_ads_r->ads = NULL;
755
+ rb_ads_r->diagfile = NULL;
756
+ adns_initflags iflags = adns_if_none;
757
+ const char *fname, *fmode, *cfgtxt;
758
+
759
+ if (argc > 4)
760
+ rb_raise(rb_eArgError, "excess number of arguments (%d for 3)", argc);
761
+ if (argc >= 1)
762
+ {
763
+ CHECK_TYPE(argv[0], T_STRING);
764
+ cfgtxt = STR2CSTR(argv[0]);
765
+ if (argc >= 2)
766
+ {
767
+ CHECK_TYPE(argv[1], T_FIXNUM);
768
+ iflags |= FIX2INT(argv[1]);
769
+ }
770
+ if (argc >= 3)
771
+ {
772
+ CHECK_TYPE(argv[2], T_STRING);
773
+ fname = STR2CSTR(argv[2]);
774
+ if (argc == 4)
775
+ {
776
+ CHECK_TYPE(argv[3], T_STRING);
777
+ fmode = STR2CSTR(argv[3]);
778
+ } else
779
+ fmode = DEFAULT_DIAG_FILEMODE;
780
+ rb_ads_r->diagfile = fopen(fname, fmode);
781
+ if (!rb_ads_r->diagfile)
782
+ rb_raise(rb_eIOError, "%s - %s", strerror(errno), fname);
783
+ }
784
+ }
785
+ adns_init_strcfg(&rb_ads_r->ads, iflags, rb_ads_r->diagfile, cfgtxt);
786
+ state = Data_Wrap_Struct(mADNS__cState, cState_mark, cState_free, rb_ads_r);
787
+ rb_obj_call_init(state, 0, 0);
788
+ return state;
789
+ }
790
+
791
+ /*
792
+ * call-seq: finish() => nil
793
+ *
794
+ * Finish all the outstanding queries associated with the ADNS::State instance.
795
+ */
796
+ static VALUE cState_finish(VALUE self)
797
+ {
798
+ rb_adns_state_t *rb_ads_r;
799
+ Data_Get_Struct(self, rb_adns_state_t, rb_ads_r);
800
+ (void) adns_finish(rb_ads_r->ads);
801
+ return Qnil;
802
+ }
803
+
804
+ /*
805
+ * = ADNS Module
806
+ *
807
+ * === Classes
808
+ * * ADNS::State
809
+ * * ADNS::Query
810
+ * * ADNS::Error
811
+ * * ADNS::LocalError
812
+ * * ADNS::RemoteError
813
+ * * ADNS::QueryError
814
+ * * ADNS::NotReadyError
815
+ *
816
+ * === Class methods
817
+ * * ADNS::status_to_s
818
+ * * ADNS::status_to_ss
819
+ *
820
+ * === Modules
821
+ * * ADNS::RR - resource record types constant collection module.
822
+ * * ADNS::QF - adns query flags constant collection module.
823
+ * * ADNS::IF - adns initialization flags constant collections module.
824
+ * * ADNS::Status - adns status code constant collection module.
825
+ *
826
+ * === Usage Example
827
+ * ==== Asynchronous
828
+ * require 'rubygems';
829
+ * require 'adns';
830
+ * require 'pp';
831
+ * adns = ADNS::State.new();
832
+ * query = adns.submit("rubygems.org", ADNS::RR:NS);
833
+ * pp query.wait();
834
+ *
835
+ * ==== Synchronous
836
+ * require 'rubygems'
837
+ * require 'adns';
838
+ * require 'pp';
839
+ * adns = ADNS::State.new();
840
+ * pp adns.synchronous('rubygems', ADNS::RR::MX);
841
+ *
842
+ */
843
+ void Init_adns(void)
844
+ {
845
+ /*
846
+ * Document-module: ADNS
847
+ * ADNS module provides bindings to GNU adns resolver library.
848
+ */
849
+ mADNS = rb_define_module("ADNS");
850
+ rb_define_module_function(mADNS, "status_to_s", mADNS__status_to_s, 1);
851
+ rb_define_module_function(mADNS, "status_to_ss", mADNS__status_to_ss, 1);
852
+ rb_define_const(mADNS, "VERSION", CSTR2STR(VERSION));
853
+
854
+ /*
855
+ * Document-class: ADNS::State
856
+ * ADNS::State class defines asychronous/synchronous methods to submit/check the query.
857
+ */
858
+ mADNS__cState = rb_define_class_under(mADNS, "State", rb_cObject);
859
+ rb_define_module_function(mADNS__cState, "new", cState_new, -1);
860
+ rb_define_module_function(mADNS__cState, "new2", cState_new2, -1);
861
+ rb_define_method(mADNS__cState, "initialize", cState_initialize, -1);
862
+ rb_define_method(mADNS__cState, "synchronous", cState_synchronous, -1);
863
+ rb_define_method(mADNS__cState, "submit", cState_submit, -1);
864
+ rb_define_method(mADNS__cState, "submit_reverse", cState_submit_reverse, -1);
865
+ rb_define_method(mADNS__cState, "submit_reverse_any", cState_submit_reverse_any, -1);
866
+ rb_define_method(mADNS__cState, "completed_queries", cState_completed_queries, -1);
867
+ rb_define_method(mADNS__cState, "global_system_failure", cState_global_system_failure, -1);
868
+
869
+ /*
870
+ * Document-class: ADNS::Query
871
+ * ADNS::Query class defines asychronous/synchronous methods to check the query
872
+ * submitted using one of the ADNS::State.submit* methods.
873
+ */
874
+ mADNS__cQuery = rb_define_class_under(mADNS, "Query", rb_cObject);
875
+ rb_define_method(mADNS__cQuery, "initialize", cQuery_init, 0);
876
+ rb_define_method(mADNS__cQuery, "check", cQuery_check, 0);
877
+ rb_define_method(mADNS__cQuery, "wait", cQuery_wait, -1);
878
+ rb_define_method(mADNS__cQuery, "cancel", cQuery_cancel, 0);
879
+
880
+ /*
881
+ * Document-module: ADNS::RR
882
+ * Module defines collection of adns resource records.
883
+ */
884
+ mADNS__mRR = rb_define_module_under(mADNS, "RR");
885
+ rb_define_const(mADNS__mRR, "UNKNOWN", INT2FIX(adns_r_unknown));
886
+ rb_define_const(mADNS__mRR, "NONE", INT2FIX(adns_r_none));
887
+ rb_define_const(mADNS__mRR, "A", INT2FIX(adns_r_a));
888
+ rb_define_const(mADNS__mRR, "NS_RAW", INT2FIX(adns_r_ns_raw));
889
+ rb_define_const(mADNS__mRR, "NS", INT2FIX(adns_r_ns));
890
+ rb_define_const(mADNS__mRR, "CNAME", INT2FIX(adns_r_cname));
891
+ rb_define_const(mADNS__mRR, "SOA_RAW", INT2FIX(adns_r_soa_raw));
892
+ rb_define_const(mADNS__mRR, "SOA", INT2FIX(adns_r_soa));
893
+ rb_define_const(mADNS__mRR, "PTR_RAW", INT2FIX(adns_r_ptr_raw));
894
+ rb_define_const(mADNS__mRR, "PTR", INT2FIX(adns_r_ptr));
895
+ rb_define_const(mADNS__mRR, "HINFO", INT2FIX(adns_r_hinfo));
896
+ rb_define_const(mADNS__mRR, "MX_RAW", INT2FIX(adns_r_mx_raw));
897
+ rb_define_const(mADNS__mRR, "MX", INT2FIX(adns_r_mx));
898
+ rb_define_const(mADNS__mRR, "TXT", INT2FIX(adns_r_txt));
899
+ rb_define_const(mADNS__mRR, "RP_RAW", INT2FIX(adns_r_rp_raw));
900
+ rb_define_const(mADNS__mRR, "RP", INT2FIX(adns_r_rp));
901
+ rb_define_const(mADNS__mRR, "SRV", INT2FIX(adns_r_srv));
902
+ rb_define_const(mADNS__mRR, "SRV_RAW", INT2FIX(adns_r_srv_raw));
903
+
904
+ /*
905
+ * Document-module: ADNS::Status
906
+ * Module defines collection of adns status code.
907
+ */
908
+ mADNS__mStatus = rb_define_module_under(mADNS, "Status");
909
+ rb_define_const(mADNS__mStatus, "OK", INT2FIX(adns_s_ok));
910
+
911
+ // ADNS::LocalError
912
+ rb_define_const(mADNS__mStatus, "NoMemory", INT2FIX(adns_s_nomemory));
913
+ rb_define_const(mADNS__mStatus, "UnknownRRType", INT2FIX(adns_s_unknownrrtype));
914
+ rb_define_const(mADNS__mStatus, "SystemFail", INT2FIX(adns_s_systemfail));
915
+
916
+ // ADNS::RemoteError
917
+ rb_define_const(mADNS__mStatus, "Timeout", INT2FIX(adns_s_timeout));
918
+ rb_define_const(mADNS__mStatus, "AllServFail", INT2FIX(adns_s_allservfail));
919
+ rb_define_const(mADNS__mStatus, "NoRecurse", INT2FIX(adns_s_norecurse));
920
+ rb_define_const(mADNS__mStatus, "InvalidResponse", INT2FIX(adns_s_invalidresponse));
921
+ rb_define_const(mADNS__mStatus, "UnknownFormat", INT2FIX(adns_s_unknownformat));
922
+ rb_define_const(mADNS__mStatus, "RcodeServFail", INT2FIX(adns_s_rcodeservfail));
923
+ rb_define_const(mADNS__mStatus, "RcodeFormatError", INT2FIX(adns_s_rcodeformaterror));
924
+ rb_define_const(mADNS__mStatus, "RcodeNotImplemented", INT2FIX(adns_s_rcodenotimplemented));
925
+ rb_define_const(mADNS__mStatus, "RcodeRefused", INT2FIX(adns_s_rcoderefused));
926
+ rb_define_const(mADNS__mStatus, "RcodeUnknown", INT2FIX(adns_s_rcodeunknown));
927
+ rb_define_const(mADNS__mStatus, "Inconsistent", INT2FIX(adns_s_inconsistent));
928
+ rb_define_const(mADNS__mStatus, "ProhibitedCNAME", INT2FIX(adns_s_prohibitedcname));
929
+ rb_define_const(mADNS__mStatus, "AnswerDomainInvalid", INT2FIX(adns_s_answerdomaininvalid));
930
+ rb_define_const(mADNS__mStatus, "InvalidData", INT2FIX(adns_s_invaliddata));
931
+
932
+ // ADNS::QueryError
933
+ rb_define_const(mADNS__mStatus, "QueryDomainWrong", INT2FIX(adns_s_querydomainwrong));
934
+ rb_define_const(mADNS__mStatus, "QueryDomainInvalid", INT2FIX(adns_s_querydomaininvalid));
935
+ rb_define_const(mADNS__mStatus, "QueryDomainTooLong", INT2FIX(adns_s_querydomaintoolong));
936
+
937
+ // ADNS::PermanentError
938
+ rb_define_const(mADNS__mStatus, "NXDomain", INT2FIX(adns_s_nxdomain));
939
+ rb_define_const(mADNS__mStatus, "NoData", INT2FIX(adns_s_nodata));
940
+
941
+ /*
942
+ * Document-module: ADNS::IF
943
+ * Module defines collection of adns init flags.
944
+ */
945
+ mADNS__mIF = rb_define_module_under(mADNS, "IF");
946
+ rb_define_const(mADNS__mIF, "NONE", INT2FIX(adns_if_none));
947
+ rb_define_const(mADNS__mIF, "NOENV", INT2FIX(adns_if_noenv));
948
+ rb_define_const(mADNS__mIF, "NOERRPRINT", INT2FIX(adns_if_noerrprint));
949
+ rb_define_const(mADNS__mIF, "NOSERVWarn", INT2FIX(adns_if_noserverwarn));
950
+ rb_define_const(mADNS__mIF, "DEBUG", INT2FIX(adns_if_debug));
951
+ rb_define_const(mADNS__mIF, "LOGPID", INT2FIX(adns_if_logpid));
952
+ rb_define_const(mADNS__mIF, "NOAUTOSYS", INT2FIX(adns_if_noautosys));
953
+ rb_define_const(mADNS__mIF, "EINTR", INT2FIX(adns_if_eintr));
954
+ rb_define_const(mADNS__mIF, "NOSIGPIPE", INT2FIX(adns_if_nosigpipe));
955
+ rb_define_const(mADNS__mIF, "CHECKC_ENTEX", INT2FIX(adns_if_checkc_entex));
956
+ rb_define_const(mADNS__mIF, "CHECKC_FREQ", INT2FIX(adns_if_checkc_freq));
957
+
958
+ /*
959
+ * Document-module: ADNS::QF
960
+ * Module defines collection of adns query flags.
961
+ */
962
+ mADNS__mQF = rb_define_module_under(mADNS, "QF");
963
+ rb_define_const(mADNS__mQF, "NONE", INT2FIX(adns_qf_none));
964
+ rb_define_const(mADNS__mQF, "SEARCH", INT2FIX(adns_qf_search));
965
+ rb_define_const(mADNS__mQF, "USEVC", INT2FIX(adns_qf_usevc));
966
+ rb_define_const(mADNS__mQF, "OWNER", INT2FIX(adns_qf_owner));
967
+ rb_define_const(mADNS__mQF, "QUOTEOK_QUERY", INT2FIX(adns_qf_quoteok_query));
968
+ rb_define_const(mADNS__mQF, "QUOTEOK_CNAME", INT2FIX(adns_qf_quoteok_cname));
969
+ rb_define_const(mADNS__mQF, "QUOTEOK_ANSHOST", INT2FIX(adns_qf_quoteok_anshost));
970
+ rb_define_const(mADNS__mQF, "QUOTEFAIL_CNAME", INT2FIX(adns_qf_quotefail_cname));
971
+ rb_define_const(mADNS__mQF, "CNAME_LOOSE", INT2FIX(adns_qf_cname_loose));
972
+ rb_define_const(mADNS__mQF, "CNAME_FORBID", INT2FIX(adns_qf_cname_forbid));
973
+
974
+ /*
975
+ * Document-class: ADNS::Error
976
+ */
977
+ mADNS__eError = rb_define_class_under(mADNS, "Error", rb_eException);
978
+ /*
979
+ * Document-class: ADNS::LocalError
980
+ */
981
+ mADNS__eLocalError = rb_define_class_under(mADNS, "LocalError", mADNS__eError);
982
+ /*
983
+ * Document-class: ADNS::RemoteError
984
+ */
985
+ mADNS__eRemoteError = rb_define_class_under(mADNS, "RemoteError", mADNS__eError);
986
+ /*
987
+ * Document-class: ADNS::QueryError
988
+ */
989
+ mADNS__eQueryError = rb_define_class_under(mADNS, "QueryError", mADNS__eError);
990
+ /*
991
+ * Document-class: ADNS::PermanentError
992
+ */
993
+ maDNS__ePermanentError = rb_define_class_under(mADNS, "PermanentError", mADNS__eError);
994
+ /*
995
+ * Document-class: ADNS::NotReadyError
996
+ */
997
+ mADNS__eNotReadyError = rb_define_class_under(mADNS, "NotReadyError", mADNS__eError);
998
+ }