adns-ruby 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }