ReactOS  0.4.13-dev-563-g0561610
adh-main.c
Go to the documentation of this file.
1 /*
2  * adh-main.c
3  * - useful general-purpose resolver client program
4  * main program and useful subroutines
5  */
6 /*
7  * This file is
8  * Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
9  *
10  * It is part of adns, which is
11  * Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
12  * Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28 
29 #ifdef ADNS_JGAA_WIN32
30 # include "adns_win32.h"
31 # include <io.h>
32 #endif
33 
34 #include "adnshost.h"
35 
36 int rcode;
37 const char *config_text;
38 
39 static int used, avail;
40 static char *buf;
41 
42 void quitnow(int rc) {
43  if (ads) adns_finish(ads);
44  free(buf);
45  free(ov_id);
46  exit(rc);
47 }
48 
49 void sysfail(const char *what, int errnoval) {
50  fprintf(stderr,"adnshost failed: %s: %s\n",what,strerror(errnoval));
51  quitnow(10);
52 }
53 
54 void usageerr(const char *fmt, ...) {
55  va_list al;
56  fputs("adnshost usage error: ",stderr);
57  va_start(al,fmt);
58  vfprintf(stderr,fmt,al);
59  va_end(al);
60  putc('\n',stderr);
61  quitnow(11);
62 }
63 
64 void outerr(void) {
65  sysfail("write to stdout",errno);
66 }
67 
68 void *xmalloc(size_t sz) {
69  void *p;
70 
71  p= malloc(sz); if (!p) sysfail("malloc",sz);
72  return p;
73 }
74 
75 char *xstrsave(const char *str) {
76  char *p;
77 
78  p= xmalloc(strlen(str)+1);
79  strcpy(p,str);
80  return p;
81 }
82 
83 void of_config(const struct optioninfo *oi, const char *arg, const char *arg2) {
85 }
86 
87 void of_type(const struct optioninfo *oi, const char *arg, const char *arg2) {
88  static const struct typename {
90  const char *desc;
91  } typenames[]= {
92  /* enhanced versions */
93  { adns_r_ns, "ns" },
94  { adns_r_soa, "soa" },
95  { adns_r_ptr, "ptr" },
96  { adns_r_mx, "mx" },
97  { adns_r_rp, "rp" },
98  { adns_r_addr, "addr" },
99 
100  /* types with only one version */
101  { adns_r_cname, "cname" },
102  { adns_r_hinfo, "hinfo" },
103  { adns_r_txt, "txt" },
104 
105  /* raw versions */
106  { adns_r_a, "a" },
107  { adns_r_ns_raw, "ns-" },
108  { adns_r_soa_raw, "soa-" },
109  { adns_r_ptr_raw, "ptr-" },
110  { adns_r_mx_raw, "mx-" },
111  { adns_r_rp_raw, "rp-" },
112 
113  { adns_r_none, 0 }
114  };
115 
116  const struct typename *tnp;
117 
118  for (tnp=typenames;
119  tnp->type && strcmp(arg,tnp->desc);
120  tnp++);
121  if (!tnp->type) usageerr("unknown RR type %s",arg);
122  ov_type= tnp->type;
123 }
124 
125 static void process_optarg(const char *arg,
126  const char *const **argv_p,
127  const char *value) {
128  const struct optioninfo *oip;
129  const char *arg2;
130  int invert;
131 
132  if (arg[0] == '-' || arg[0] == '+') {
133  if (arg[0] == '-' && arg[1] == '-') {
134  if (!strncmp(arg,"--no-",5)) {
135  invert= 1;
136  oip= opt_findl(arg+5);
137  } else {
138  invert= 0;
139  oip= opt_findl(arg+2);
140  }
141  if (oip->type == ot_funcarg) {
142  arg= argv_p ? *++(*argv_p) : value;
143  if (!arg) usageerr("option --%s requires a value argument",oip->lopt);
144  arg2= 0;
145  } else if (oip->type == ot_funcarg2) {
146  assert(argv_p);
147  arg= *++(*argv_p);
148  arg2= arg ? *++(*argv_p) : 0;
149  if (!arg || !arg2)
150  usageerr("option --%s requires two more arguments", oip->lopt);
151  } else {
152  if (value) usageerr("option --%s does not take a value",oip->lopt);
153  arg= 0;
154  arg2= 0;
155  }
156  opt_do(oip,invert,arg,arg2);
157  } else if (arg[0] == '-' && arg[1] == 0) {
158  arg= argv_p ? *++(*argv_p) : value;
159  if (!arg) usageerr("option `-' must be followed by a domain");
160  query_do(arg);
161  } else { /* arg[1] != '-', != '\0' */
162  invert= (arg[0] == '+');
163  ++arg;
164  while (*arg) {
165  oip= opt_finds(&arg);
166  if (oip->type == ot_funcarg) {
167  if (!*arg) {
168  arg= argv_p ? *++(*argv_p) : value;
169  if (!arg) usageerr("option -%s requires a value argument",oip->sopt);
170  } else {
171  if (value) usageerr("two values for option -%s given !",oip->sopt);
172  }
173  opt_do(oip,invert,arg,0);
174  arg= "";
175  } else {
176  if (value) usageerr("option -%s does not take a value",oip->sopt);
177  opt_do(oip,invert,0,0);
178  }
179  }
180  }
181  } else { /* arg[0] != '-' */
182  query_do(arg);
183  }
184 }
185 
186 static void read_stdin(void) {
187  int anydone, r;
188  char *newline, *space;
189 
190  anydone= 0;
191  while (!anydone || used) {
192  while (!(newline= memchr(buf,'\n',used))) {
193  if (used == avail) {
194  avail += 20; avail <<= 1;
195  buf= realloc(buf,avail);
196  if (!buf) sysfail("realloc stdin buffer",errno);
197  }
198  do {
199  r= read(0,buf+used,avail-used);
200  } while (r < 0 && errno == EINTR);
201  if (r == 0) {
202  if (used) {
203  /* fake up final newline */
204  buf[used++]= '\n';
205  r= 1;
206  } else {
207  ov_pipe= 0;
208  return;
209  }
210  }
211  if (r < 0) sysfail("read stdin",errno);
212  used += r;
213  }
214  *newline++= 0;
215  space= strchr(buf,' ');
216  if (space) *space++= 0;
218  used -= (newline-buf);
220  anydone= 1;
221  }
222 }
223 
224 int main(int argc, const char *const *argv) {
225  struct timeval *tv, tvbuf;
226  adns_query qu;
227  void *qun_v;
228  adns_answer *answer;
229  int r, maxfd;
230  fd_set readfds, writefds, exceptfds;
231  const char *arg;
232 
234 
235  while ((arg= *++argv)) process_optarg(arg,&argv,0);
236 
237  if (!ov_pipe && !ads) usageerr("no domains given, and -f/--pipe not used; try --help");
238 
239  for (;;) {
240  for (;;) {
241  qu= ov_asynch ? 0 : outstanding.head ? outstanding.head->qu : 0;
242  r= adns_check(ads,&qu,&answer,&qun_v);
243  if ((r == EAGAIN) || (r == EWOULDBLOCK)) break;
244  if (r == ESRCH) { if (!ov_pipe) goto x_quit; else break; }
245  assert(!r);
246  query_done(qun_v,answer);
247  }
248  maxfd= 0;
249  FD_ZERO(&readfds);
250  FD_ZERO(&writefds);
251  FD_ZERO(&exceptfds);
252  if (ov_pipe) {
253  maxfd= 1;
254  FD_SET(0,&readfds);
255  }
256  tv= 0;
257  adns_beforeselect(ads, &maxfd, &readfds,&writefds,&exceptfds, &tv,&tvbuf,0);
259  r= select(maxfd, &readfds,&writefds,&exceptfds, tv);
261  if (r == -1) {
262  if (errno == EINTR) continue;
263  sysfail("select",errno);
264  }
265  adns_afterselect(ads, maxfd, &readfds,&writefds,&exceptfds, 0);
266  if (ov_pipe && FD_ISSET(0,&readfds)) read_stdin();
267  }
268 x_quit:
269  if (fclose(stdout)) outerr();
270  quitnow(rcode);
271 }
#define realloc
Definition: debug_ros.c:6
Definition: winsock.h:66
static void process_optarg(const char *arg, const char *const **argv_p, const char *value)
Definition: adh-main.c:125
static int argc
Definition: ServiceArgs.c:12
void * xmalloc(size_t sz)
Definition: adh-main.c:68
void query_done(struct query_node *qun, adns_answer *answer)
Definition: adh-query.c:253
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
adns_state ads
Definition: adh-query.c:35
ADNS_API void adns_beforeselect(adns_state ads, int *maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval **tv_mod, struct timeval *tv_buf, const struct timeval *now)
Definition: event.c:562
#define memchr(s, c, n)
Definition: mkisofs.h:875
char typename[32]
Definition: main.c:84
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
int rcode
Definition: adh-main.c:36
ADNS_API void adns_finish(adns_state ads)
Definition: setup.c:650
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
adns_rrtype
Definition: adns.h:113
const char * config_text
Definition: adh-main.c:37
#define free
Definition: debug_ros.c:5
char * xstrsave(const char *str)
Definition: adh-main.c:75
#define EINTR
Definition: acclib.h:80
Definition: adns.h:120
char * ov_id
Definition: adh-opts.c:40
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
adns_rrtype ov_type
Definition: adh-opts.c:37
#define assert(x)
Definition: debug.h:53
int ov_pipe
Definition: adh-opts.c:35
void * arg
Definition: msvc.h:12
int errno
#define FD_ZERO(set)
Definition: winsock.h:96
#define argv
Definition: mplay32.c:18
#define FD_SET(fd, set)
Definition: winsock.h:89
int main(int argc, const char *const *argv)
Definition: adh-main.c:224
const char * strerror(int err)
Definition: compat_str.c:23
void query_do(const char *domain)
Definition: adh-query.c:138
static int avail
Definition: adh-main.c:39
FILE * stdout
ADNS_API void adns_afterselect(adns_state ads, int maxfd, const fd_set *readfds, const fd_set *writefds, const fd_set *exceptfds, const struct timeval *now)
Definition: event.c:595
#define ESRCH
Definition: errno.h:9
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLboolean invert
Definition: gl.h:1949
#define va_end(ap)
Definition: acmsvcex.h:90
void of_type(const struct optioninfo *oi, const char *arg, const char *arg2)
Definition: adh-main.c:87
#define FD_ISSET(fd, set)
Definition: winsock.h:100
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
const char * lopt
Definition: adnshost.h:68
#define EWOULDBLOCK
Definition: errno.h:42
struct outstanding_list outstanding
Definition: adh-query.c:36
const char * sopt
Definition: adnshost.h:68
const WCHAR * str
const struct builtin_class_descr * desc
Definition: regcontrol.c:48
char * va_list
Definition: acmsvcex.h:78
Definition: arc.h:35
#define ADNS_CLEAR_ERRNO
Definition: adns_win32.h:108
_Check_return_opt_ _CRTIMP int __cdecl putc(_In_ int _Ch, _Inout_ FILE *_File)
int ov_asynch
Definition: adh-opts.c:35
const struct optioninfo * opt_findl(const char *opt)
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
void usageerr(const char *fmt,...)
Definition: adh-main.c:54
void sysfail(const char *what, int errnoval)
Definition: adh-main.c:49
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
GLsizei const GLfloat * value
Definition: glext.h:6069
static int used
Definition: adh-main.c:39
void ensure_adns_init(void)
Definition: adh-query.c:40
enum optioninfo::oi_type type
void opt_do(const struct optioninfo *oip, int invert, const char *arg, const char *arg2)
static void newline(int)
Definition: ppl.yy.c:3768
#define va_start(ap, A)
Definition: acmsvcex.h:91
static char * buf
Definition: adh-main.c:40
#define ADNS_CAPTURE_ERRNO
Definition: adns_win32.h:107
char * strchr(const char *String, int ch)
Definition: utclib.c:501
ADNS_API int adns_check(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r)
Definition: event.c:731
static void read_stdin(void)
Definition: adh-main.c:186
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
const struct optioninfo * opt_finds(const char **optp)
#define malloc
Definition: debug_ros.c:4
void outerr(void)
Definition: adh-main.c:64
void exit(int exitcode)
Definition: _exit.c:33
GLfloat GLfloat p
Definition: glext.h:8902
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)
void quitnow(int rc)
Definition: adh-main.c:42
void of_config(const struct optioninfo *oi, const char *arg, const char *arg2)
Definition: adh-main.c:83
Definition: dsound.c:943
_Check_return_opt_ _CRTIMP int __cdecl fputs(_In_z_ const char *_Str, _Inout_ FILE *_File)
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)