Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenadh-main.c
Go to the documentation of this file.
00001 /* 00002 * adh-main.c 00003 * - useful general-purpose resolver client program 00004 * main program and useful subroutines 00005 */ 00006 /* 00007 * This file is 00008 * Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk> 00009 * 00010 * It is part of adns, which is 00011 * Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk> 00012 * Copyright (C) 1999-2000 Tony Finch <dot@dotat.at> 00013 * 00014 * This program is free software; you can redistribute it and/or modify 00015 * it under the terms of the GNU General Public License as published by 00016 * the Free Software Foundation; either version 2, or (at your option) 00017 * any later version. 00018 * 00019 * This program is distributed in the hope that it will be useful, 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 * GNU General Public License for more details. 00023 * 00024 * You should have received a copy of the GNU General Public License 00025 * along with this program; if not, write to the Free Software Foundation, 00026 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00027 */ 00028 00029 #ifdef ADNS_JGAA_WIN32 00030 # include "adns_win32.h" 00031 # include <io.h> 00032 #endif 00033 00034 #include "adnshost.h" 00035 00036 int rcode; 00037 const char *config_text; 00038 00039 static int used, avail; 00040 static char *buf; 00041 00042 void quitnow(int rc) { 00043 if (ads) adns_finish(ads); 00044 free(buf); 00045 free(ov_id); 00046 exit(rc); 00047 } 00048 00049 void sysfail(const char *what, int errnoval) { 00050 fprintf(stderr,"adnshost failed: %s: %s\n",what,strerror(errnoval)); 00051 quitnow(10); 00052 } 00053 00054 void usageerr(const char *fmt, ...) { 00055 va_list al; 00056 fputs("adnshost usage error: ",stderr); 00057 va_start(al,fmt); 00058 vfprintf(stderr,fmt,al); 00059 va_end(al); 00060 putc('\n',stderr); 00061 quitnow(11); 00062 } 00063 00064 void outerr(void) { 00065 sysfail("write to stdout",errno); 00066 } 00067 00068 void *xmalloc(size_t sz) { 00069 void *p; 00070 00071 p= malloc(sz); if (!p) sysfail("malloc",sz); 00072 return p; 00073 } 00074 00075 char *xstrsave(const char *str) { 00076 char *p; 00077 00078 p= xmalloc(strlen(str)+1); 00079 strcpy(p,str); 00080 return p; 00081 } 00082 00083 void of_config(const struct optioninfo *oi, const char *arg, const char *arg2) { 00084 config_text= arg; 00085 } 00086 00087 void of_type(const struct optioninfo *oi, const char *arg, const char *arg2) { 00088 static const struct typename { 00089 adns_rrtype type; 00090 const char *desc; 00091 } typenames[]= { 00092 /* enhanced versions */ 00093 { adns_r_ns, "ns" }, 00094 { adns_r_soa, "soa" }, 00095 { adns_r_ptr, "ptr" }, 00096 { adns_r_mx, "mx" }, 00097 { adns_r_rp, "rp" }, 00098 { adns_r_addr, "addr" }, 00099 00100 /* types with only one version */ 00101 { adns_r_cname, "cname" }, 00102 { adns_r_hinfo, "hinfo" }, 00103 { adns_r_txt, "txt" }, 00104 00105 /* raw versions */ 00106 { adns_r_a, "a" }, 00107 { adns_r_ns_raw, "ns-" }, 00108 { adns_r_soa_raw, "soa-" }, 00109 { adns_r_ptr_raw, "ptr-" }, 00110 { adns_r_mx_raw, "mx-" }, 00111 { adns_r_rp_raw, "rp-" }, 00112 00113 { adns_r_none, 0 } 00114 }; 00115 00116 const struct typename *tnp; 00117 00118 for (tnp=typenames; 00119 tnp->type && strcmp(arg,tnp->desc); 00120 tnp++); 00121 if (!tnp->type) usageerr("unknown RR type %s",arg); 00122 ov_type= tnp->type; 00123 } 00124 00125 static void process_optarg(const char *arg, 00126 const char *const **argv_p, 00127 const char *value) { 00128 const struct optioninfo *oip; 00129 const char *arg2; 00130 int invert; 00131 00132 if (arg[0] == '-' || arg[0] == '+') { 00133 if (arg[0] == '-' && arg[1] == '-') { 00134 if (!strncmp(arg,"--no-",5)) { 00135 invert= 1; 00136 oip= opt_findl(arg+5); 00137 } else { 00138 invert= 0; 00139 oip= opt_findl(arg+2); 00140 } 00141 if (oip->type == ot_funcarg) { 00142 arg= argv_p ? *++(*argv_p) : value; 00143 if (!arg) usageerr("option --%s requires a value argument",oip->lopt); 00144 arg2= 0; 00145 } else if (oip->type == ot_funcarg2) { 00146 assert(argv_p); 00147 arg= *++(*argv_p); 00148 arg2= arg ? *++(*argv_p) : 0; 00149 if (!arg || !arg2) 00150 usageerr("option --%s requires two more arguments", oip->lopt); 00151 } else { 00152 if (value) usageerr("option --%s does not take a value",oip->lopt); 00153 arg= 0; 00154 arg2= 0; 00155 } 00156 opt_do(oip,invert,arg,arg2); 00157 } else if (arg[0] == '-' && arg[1] == 0) { 00158 arg= argv_p ? *++(*argv_p) : value; 00159 if (!arg) usageerr("option `-' must be followed by a domain"); 00160 query_do(arg); 00161 } else { /* arg[1] != '-', != '\0' */ 00162 invert= (arg[0] == '+'); 00163 ++arg; 00164 while (*arg) { 00165 oip= opt_finds(&arg); 00166 if (oip->type == ot_funcarg) { 00167 if (!*arg) { 00168 arg= argv_p ? *++(*argv_p) : value; 00169 if (!arg) usageerr("option -%s requires a value argument",oip->sopt); 00170 } else { 00171 if (value) usageerr("two values for option -%s given !",oip->sopt); 00172 } 00173 opt_do(oip,invert,arg,0); 00174 arg= ""; 00175 } else { 00176 if (value) usageerr("option -%s does not take a value",oip->sopt); 00177 opt_do(oip,invert,0,0); 00178 } 00179 } 00180 } 00181 } else { /* arg[0] != '-' */ 00182 query_do(arg); 00183 } 00184 } 00185 00186 static void read_stdin(void) { 00187 int anydone, r; 00188 char *newline, *space; 00189 00190 anydone= 0; 00191 while (!anydone || used) { 00192 while (!(newline= memchr(buf,'\n',used))) { 00193 if (used == avail) { 00194 avail += 20; avail <<= 1; 00195 buf= realloc(buf,avail); 00196 if (!buf) sysfail("realloc stdin buffer",errno); 00197 } 00198 do { 00199 r= read(0,buf+used,avail-used); 00200 } while (r < 0 && errno == EINTR); 00201 if (r == 0) { 00202 if (used) { 00203 /* fake up final newline */ 00204 buf[used++]= '\n'; 00205 r= 1; 00206 } else { 00207 ov_pipe= 0; 00208 return; 00209 } 00210 } 00211 if (r < 0) sysfail("read stdin",errno); 00212 used += r; 00213 } 00214 *newline++= 0; 00215 space= strchr(buf,' '); 00216 if (space) *space++= 0; 00217 process_optarg(buf,0,space); 00218 used -= (newline-buf); 00219 memmove(buf,newline,used); 00220 anydone= 1; 00221 } 00222 } 00223 00224 int main(int argc, const char *const *argv) { 00225 struct timeval *tv, tvbuf; 00226 adns_query qu; 00227 void *qun_v; 00228 adns_answer *answer; 00229 int r, maxfd; 00230 fd_set readfds, writefds, exceptfds; 00231 const char *arg; 00232 00233 ensure_adns_init(); 00234 00235 while ((arg= *++argv)) process_optarg(arg,&argv,0); 00236 00237 if (!ov_pipe && !ads) usageerr("no domains given, and -f/--pipe not used; try --help"); 00238 00239 for (;;) { 00240 for (;;) { 00241 qu= ov_asynch ? 0 : outstanding.head ? outstanding.head->qu : 0; 00242 r= adns_check(ads,&qu,&answer,&qun_v); 00243 if ((r == EAGAIN) || (r == EWOULDBLOCK)) break; 00244 if (r == ESRCH) { if (!ov_pipe) goto x_quit; else break; } 00245 assert(!r); 00246 query_done(qun_v,answer); 00247 } 00248 maxfd= 0; 00249 FD_ZERO(&readfds); 00250 FD_ZERO(&writefds); 00251 FD_ZERO(&exceptfds); 00252 if (ov_pipe) { 00253 maxfd= 1; 00254 FD_SET(0,&readfds); 00255 } 00256 tv= 0; 00257 adns_beforeselect(ads, &maxfd, &readfds,&writefds,&exceptfds, &tv,&tvbuf,0); 00258 ADNS_CLEAR_ERRNO; 00259 r= select(maxfd, &readfds,&writefds,&exceptfds, tv); 00260 ADNS_CAPTURE_ERRNO; 00261 if (r == -1) { 00262 if (errno == EINTR) continue; 00263 sysfail("select",errno); 00264 } 00265 adns_afterselect(ads, maxfd, &readfds,&writefds,&exceptfds, 0); 00266 if (ov_pipe && FD_ISSET(0,&readfds)) read_stdin(); 00267 } 00268 x_quit: 00269 if (fclose(stdout)) outerr(); 00270 quitnow(rcode); 00271 } Generated on Sun May 27 2012 04:33:25 for ReactOS by
1.7.6.1
|