ReactOS 0.4.16-dev-320-g3bd9ddc
adnslogres.c
Go to the documentation of this file.
1/*
2 * adnslogres.c
3 * - a replacement for the Apache logresolve program using adns
4 */
5/*
6 * This file is
7 * Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
8 * Copyright (C) 1999-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 * This version was originally supplied by Tony Finch, but has been
29 * modified by Ian Jackson as it was incorporated into adns and
30 * subsequently.
31 */
32
33#ifdef ADNS_JGAA_WIN32
34# include "adns_win32.h"
35# include "getopt.h"
36#else
37# include <sys/types.h>
38# include <sys/time.h>
39# include <unistd.h>
40# include <string.h>
41# include <stdlib.h>
42# include <stdio.h>
43# include <ctype.h>
44# include <errno.h>
45# include <stdarg.h>
46#endif
47
48#include "config.h"
49#include "adns.h"
50#include "client.h"
51
52#ifdef ADNS_REGRESS_TEST
53# include "hredirect.h"
54#endif
55
56/* maximum number of concurrent DNS queries */
57#define MAXMAXPENDING 64000
58#define DEFMAXPENDING 2000
59
60/* maximum length of a line */
61#define MAXLINE 1024
62
63/* option flags */
64#define OPT_DEBUG 1
65
66#ifdef HAVE_POLL
67# define OPT_POLL 2
68#endif
69
70static const char *const progname= "adnslogres";
71static const char *config_text;
72
73#define guard_null(str) ((str) ? (str) : "")
74
75#define sensible_ctype(type,ch) (type((unsigned char)(ch)))
76 /* isfoo() functions from ctype.h can't safely be fed char - blech ! */
77
78static void msg(const char *fmt, ...) {
79 va_list al;
80
81 fprintf(stderr, "%s: ", progname);
82 va_start(al,fmt);
83 vfprintf(stderr, fmt, al);
84 va_end(al);
85 fputc('\n',stderr);
86}
87
88static void aargh(const char *cause) {
89 const char *why = strerror(errno);
90 if (!why) why = "Unknown error";
91 msg("%s: %s (%d)", cause, why, errno);
92 exit(1);
93}
94
95/*
96 * Parse the IP address and convert to a reverse domain name.
97 */
98static char *ipaddr2domain(char *start, char **addr, char **rest) {
99 static char buf[30]; /* "123.123.123.123.in-addr.arpa.\0" */
100 char *ptrs[5];
101 int i;
102
103 ptrs[0]= start;
104retry:
105 while (!sensible_ctype(isdigit,*ptrs[0]))
106 if (!*ptrs[0]++) {
107 strcpy(buf, "invalid.");
108 *addr= *rest= NULL;
109 return buf;
110 }
111 for (i= 1; i < 5; i++) {
112 ptrs[i]= ptrs[i-1];
113 while (sensible_ctype(isdigit,*ptrs[i]++));
114 if ((i == 4 && !sensible_ctype(isspace,ptrs[i][-1])) ||
115 (i != 4 && ptrs[i][-1] != '.') ||
116 (ptrs[i]-ptrs[i-1] > 4)) {
117 ptrs[0]= ptrs[i]-1;
118 goto retry;
119 }
120 }
121 sprintf(buf, "%.*s.%.*s.%.*s.%.*s.in-addr.arpa.",
122 ptrs[4]-ptrs[3]-1, ptrs[3],
123 ptrs[3]-ptrs[2]-1, ptrs[2],
124 ptrs[2]-ptrs[1]-1, ptrs[1],
125 ptrs[1]-ptrs[0]-1, ptrs[0]);
126 *addr= ptrs[0];
127 *rest= ptrs[4]-1;
128 return buf;
129}
130
131static void printline(FILE *outf, char *start, char *addr, char *rest, char *domain) {
132 if (domain)
133 fprintf(outf, "%.*s%s%s", addr - start, start, domain, rest);
134 else
135 fputs(start, outf);
136 if (ferror(outf)) aargh("write output");
137}
138
139typedef struct logline {
140 struct logline *next;
141 char *start, *addr, *rest;
144
145static logline *readline(FILE *inf, adns_state adns, int opts) {
146 static char buf[MAXLINE];
147 char *str;
148 logline *line;
149
150 if (fgets(buf, MAXLINE, inf)) {
151 str= malloc(sizeof(*line) + strlen(buf) + 1);
152 if (!str) aargh("malloc");
153 line= (logline*)str;
154 line->next= NULL;
155 line->start= str+sizeof(logline);
156 strcpy(line->start, buf);
157 str= ipaddr2domain(line->start, &line->addr, &line->rest);
158 if (opts & OPT_DEBUG)
159 msg("submitting %.*s -> %s", line->rest-line->addr, guard_null(line->addr), str);
160 if (adns_submit(adns, str, adns_r_ptr,
162 NULL, &line->query))
163 aargh("adns_submit");
164 return line;
165 }
166 if (!feof(inf))
167 aargh("fgets");
168 return NULL;
169}
170
171static void proclog(FILE *inf, FILE *outf, int maxpending, int opts) {
172 int eof, err, len;
173 adns_state adns;
174 adns_answer *answer;
175 logline *head, *tail, *line;
177
178 initflags= (opts & OPT_DEBUG) ? adns_if_debug : 0;
179 if (config_text) {
181 } else {
182 errno= adns_init(&adns, initflags, 0);
183 }
184 if (errno) aargh("adns_init");
185 head= tail= readline(inf, adns, opts);
186 len= 1; eof= 0;
187 while (head) {
188 while (head) {
189 if (opts & OPT_DEBUG)
190 msg("%d in queue; checking %.*s", len,
191 head->rest-head->addr, guard_null(head->addr));
192 if (eof || len >= maxpending) {
193#ifdef HAVE_POLL
194 if (opts & OPT_POLL)
195 err= adns_wait_poll(adns, &head->query, &answer, NULL);
196 else
197#endif
198 err= adns_wait(adns, &head->query, &answer, NULL);
199 } else {
200 err= adns_check(adns, &head->query, &answer, NULL);
201 }
202 if ((err == EAGAIN) || (EWOULDBLOCK == err)) break;
203 if (err) {
204 fprintf(stderr, "%s: adns_wait/check: %s", progname, strerror(err));
205 exit(1);
206 }
207 printline(outf, head->start, head->addr, head->rest,
208 answer->status == adns_s_ok ? *answer->rrs.str : NULL);
209 line= head; head= head->next;
210 free(line);
211 free(answer);
212 len--;
213 }
214 if (!eof) {
215 line= readline(inf, adns, opts);
216 if (line) {
217 if (!head) head= line;
218 else tail->next= line;
219 tail= line; len++;
220 } else {
221 eof= 1;
222 }
223 }
224 }
225 adns_finish(adns);
226}
227
228static void printhelp(FILE *file) {
229 fputs("usage: adnslogres [<options>] [<logfile>]\n"
230 " adnslogres --version|--help\n"
231 "options: -c <concurrency> set max number of outstanding queries\n"
232#ifdef HAVE_POLL
233 " -p use poll(2) instead of select(2)\n"
234#endif
235 " -d turn on debugging\n"
236 " -C <config> use instead of contents of resolv.conf\n",
237 stdout);
238}
239
240static void usage(void) {
242 exit(1);
243}
244
245int main(int argc, char *argv[]) {
246 int c, opts, maxpending;
247 extern char *optarg;
248 FILE *inf;
249
250 if (argv[1] && !strncmp(argv[1],"--",2)) {
251 if (!strcmp(argv[1],"--help")) {
253 } else if (!strcmp(argv[1],"--version")) {
254 fputs(VERSION_MESSAGE("adnslogres"),stdout);
255 } else {
256 usage();
257 }
258 if (ferror(stdout) || fclose(stdout)) { perror("stdout"); exit(1); }
259 exit(0);
260 }
261
262 maxpending= DEFMAXPENDING;
263 opts= 0;
264 while ((c= getopt(argc, argv, "c:C:dp")) != -1)
265 switch (c) {
266 case 'c':
267 maxpending= atoi(optarg);
268 if (maxpending < 1 || maxpending > MAXMAXPENDING) {
269 fprintf(stderr, "%s: unfeasible concurrency %d\n", progname, maxpending);
270 exit(1);
271 }
272 break;
273 case 'C':
275 break;
276 case 'd':
277 opts|= OPT_DEBUG;
278 break;
279#ifdef HAVE_POLL
280 case 'p':
281 opts|= OPT_POLL;
282 break;
283#endif
284 default:
285 usage();
286 }
287
288 argc-= optind;
289 argv+= optind;
290
291 inf= NULL;
292 if (argc == 0)
293 inf= stdin;
294 else if (argc == 1)
295 inf= fopen(*argv, "r");
296 else
297 usage();
298
299 if (!inf)
300 aargh("couldn't open input");
301
302 proclog(inf, stdout, maxpending, opts);
303
304 if (fclose(inf))
305 aargh("fclose input");
306 if (fclose(stdout))
307 aargh("fclose output");
308
309 return 0;
310}
static int argc
Definition: ServiceArgs.c:12
#define isspace(c)
Definition: acclib.h:69
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define isdigit(c)
Definition: acclib.h:68
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define EAGAIN
Definition: acclib.h:83
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
@ adns_r_ptr
Definition: adns.h:131
ADNS_API void adns_finish(adns_state ads)
Definition: setup.c:650
ADNS_API int adns_check(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r)
Definition: event.c:731
ADNS_API int adns_init(adns_state *newstate_r, adns_initflags flags, FILE *diagfile)
Definition: setup.c:568
ADNS_API int adns_wait(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r)
Definition: event.c:696
adns_initflags
Definition: adns.h:87
@ adns_if_debug
Definition: adns.h:91
@ adns_s_ok
Definition: adns.h:216
ADNS_API int adns_wait_poll(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r)
ADNS_API int adns_submit(adns_state ads, const char *owner, adns_rrtype type, adns_queryflags flags, void *context, adns_query *query_r)
Definition: query.c:204
ADNS_API int adns_init_strcfg(adns_state *newstate_r, adns_initflags flags, FILE *diagfile, const char *configtext)
Definition: setup.c:629
@ adns_qf_quoteok_cname
Definition: adns.h:105
@ adns_qf_cname_loose
Definition: adns.h:108
static void printhelp(FILE *file)
Definition: adnslogres.c:228
#define MAXLINE
Definition: adnslogres.c:61
static const char * config_text
Definition: adnslogres.c:71
#define guard_null(str)
Definition: adnslogres.c:73
#define OPT_DEBUG
Definition: adnslogres.c:64
#define sensible_ctype(type, ch)
Definition: adnslogres.c:75
static const char *const progname
Definition: adnslogres.c:70
static void printline(FILE *outf, char *start, char *addr, char *rest, char *domain)
Definition: adnslogres.c:131
static char * ipaddr2domain(char *start, char **addr, char **rest)
Definition: adnslogres.c:98
#define MAXMAXPENDING
Definition: adnslogres.c:57
static void usage(void)
Definition: adnslogres.c:240
static void aargh(const char *cause)
Definition: adnslogres.c:88
static logline * readline(FILE *inf, adns_state adns, int opts)
Definition: adnslogres.c:145
#define DEFMAXPENDING
Definition: adnslogres.c:58
static void proclog(FILE *inf, FILE *outf, int maxpending, int opts)
Definition: adnslogres.c:171
static adns_initflags initflags
Definition: adnsresfilter.c:62
struct outqueuenode * tail
Definition: adnsresfilter.c:66
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define msg(x)
Definition: auth_time.c:54
int getopt(int nargc, char *const *nargv, const char *ostr)
Definition: getopt.c:55
const char * optarg
Definition: getopt.c:49
int optind
Definition: getopt.c:47
#define VERSION_MESSAGE(program)
Definition: client.h:39
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define EWOULDBLOCK
Definition: errno.h:42
int main()
Definition: test.c:6
GLuint start
Definition: gl.h:1545
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum const GLvoid * addr
Definition: glext.h:9621
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define stdout
Definition: stdio.h:99
_Check_return_ _CRTIMP int __cdecl ferror(_In_ FILE *_File)
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define stderr
Definition: stdio.h:100
_Check_return_ _CRTIMP int __cdecl feof(_In_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fputs(_In_z_ const char *_Str, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fputc(_In_ int _Ch, _Inout_ FILE *_File)
#define stdin
Definition: stdio.h:98
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define c
Definition: ke_i.h:80
#define sprintf(buf, format,...)
Definition: sprintf.c:55
const char * strerror(int err)
Definition: compat_str.c:23
#define argv
Definition: mplay32.c:18
#define err(...)
const WCHAR * str
#define errno
Definition: errno.h:18
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
#define exit(n)
Definition: config.h:202
fa outf
Definition: format.c:301
union adns_answer::@4226 rrs
adns_status status
Definition: adns.h:311
char ** str
Definition: adns.h:320
Definition: cookie.c:42
Definition: fci.c:127
Definition: dsound.c:943
Definition: parser.c:49
struct logline * next
Definition: adnslogres.c:140
adns_query query
Definition: adnslogres.c:142
char * addr
Definition: adnslogres.c:141
char * start
Definition: adnslogres.c:141
char * rest
Definition: adnslogres.c:141