logresolve.c revision 0fdce60d89493753aeeadd6c26755143515f3de6
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl/* Copyright 1999-2004 The Apache Software Foundation
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * Licensed under the Apache License, Version 2.0 (the "License");
c362cf8bdeb690d43aca572eedf3343e8726b961nd * you may not use this file except in compliance with the License.
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * You may obtain a copy of the License at
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *
031b91a62d25106ae69d4693475c79618dd5e884fielding * http://www.apache.org/licenses/LICENSE-2.0
031b91a62d25106ae69d4693475c79618dd5e884fielding *
031b91a62d25106ae69d4693475c79618dd5e884fielding * Unless required by applicable law or agreed to in writing, software
031b91a62d25106ae69d4693475c79618dd5e884fielding * distributed under the License is distributed on an "AS IS" BASIS,
031b91a62d25106ae69d4693475c79618dd5e884fielding * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
031b91a62d25106ae69d4693475c79618dd5e884fielding * See the License for the specific language governing permissions and
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * limitations under the License.
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl */
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl/*
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * logresolve 1.1
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * Tom Rathborne - tomr uunet.ca - http://www.uunet.ca/~tomr/
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * UUNET Canada, April 16, 1995
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * Rewritten by David Robinson. (drtr ast.cam.ac.uk)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * Usage: logresolve [-s filename] [-c] < access_log > new_log
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * Arguments:
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * -s filename name of a file to record statistics
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * -c check the DNS for a matching A record for the host.
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * Notes:
955504c59e54738aafe056e88240dddcfd70fc78covener *
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * To generate meaningful statistics from an HTTPD log file, it's good
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * to have the domain name of each machine that accessed your site, but
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * doing this on the fly can slow HTTPD down.
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *
955504c59e54738aafe056e88240dddcfd70fc78covener * Compiling NCSA HTTPD with the -DMINIMAL_DNS flag turns IP#->hostname
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * resolution off. Before running your stats program, just run your log
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * file through this program (logresolve) and all of your IP numbers will
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * be resolved into hostnames (where possible).
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung * logresolve takes an HTTPD access log (in the COMMON log file format,
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * or any other format that has the IP number/domain name as the first
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * field for that matter), and outputs the same file with all of the
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung * domain names looked up. Where no domain name can be found, the IP
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * number is left in.
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung *
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung * To minimize impact on your nameserver, logresolve has its very own
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung * internal hash-table cache. This means that each IP number will only
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * be looked up the first time it is found in the log file.
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * The -c option causes logresolve to apply the same check as httpd
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * compiled with -DMAXIMUM_DNS; after finding the hostname from the IP
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * address, it looks up the IP addresses for the hostname and checks
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * that one of these matches the original address.
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl */
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#include "apr_lib.h"
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#if APR_HAVE_STDIO_H
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#include <stdio.h>
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#endif
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#if APR_HAVE_STDLIB_H
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#include <stdlib.h>
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#endif
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#if APR_HAVE_CTYPE_H
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#include <ctype.h>
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#endif
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#if APR_HAVE_NETDB_H
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#include <netdb.h>
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#endif
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#if APR_HAVE_NETINET_IN_H
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#include <netinet/in.h>
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#endif
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#if APR_HAVE_STRING_H
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#include <string.h>
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#endif
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#if APR_HAVE_SYS_SOCKET_H
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#include <sys/socket.h>
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#endif
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#if APR_HAVE_ARPA_INET_H
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#include <arpa/inet.h>
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#endif
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslstatic void cgethost(struct in_addr ipnum, char *string, int check);
c3ea2f06571c877091cd2f1016e47b1d5660df9drjungstatic int get_line(char *s, int n);
c3ea2f06571c877091cd2f1016e47b1d5660df9drjungstatic void stats(FILE *output);
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#ifdef BEOS
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#define NO_ADDRESS NO_DATA
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#endif
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl/* maximum line length */
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#ifndef MAXLINE
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#define MAXLINE 1024
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#endif
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl/* maximum length of a domain name */
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#ifndef MAXDNAME
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#define MAXDNAME 256
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#endif
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl/* number of buckets in cache hash apr_table_t */
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#define BUCKETS 256
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl/*
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * struct nsrec - record of nameservice for cache linked list
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * ipnum - IP number hostname - hostname noname - nonzero if IP number has no
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung * hostname, i.e. hostname=IP number
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl */
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
c3ea2f06571c877091cd2f1016e47b1d5660df9drjungstruct nsrec {
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung struct in_addr ipnum;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl char *hostname;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl int noname;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl struct nsrec *next;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl} *nscache[BUCKETS];
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl/*
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * statistics - obvious
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl */
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#ifndef h_errno
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#ifdef __CYGWIN__
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslextern __declspec(dllimport) int h_errno;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#else
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslextern int h_errno; /* some machines don't have this in their headers */
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#endif
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#endif
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl/* largest value for h_errno */
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#define MAX_ERR (NO_ADDRESS)
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#define UNKNOWN_ERR (MAX_ERR+1)
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung#define NO_REVERSE (MAX_ERR+2)
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslstatic int cachehits = 0;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslstatic int cachesize = 0;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslstatic int entries = 0;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslstatic int resolves = 0;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslstatic int withname = 0;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslstatic int errors[MAX_ERR + 3];
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl/*
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * cgethost - gets hostname by IP address, caching, and adding unresolvable
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * IP numbers with their IP number as hostname, setting noname flag
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl */
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslstatic void cgethost (struct in_addr ipnum, char *string, int check)
eacb724157bafd5062590305826ebc6fecb48cd2trawick{
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl struct nsrec **current, *new;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl struct hostent *hostdata;
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung char *name;
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) +
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung (ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)];
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr)
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung current = &(*current)->next;
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung if (*current == NULL) {
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl cachesize++;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl new = (struct nsrec *) malloc(sizeof(struct nsrec));
eacb724157bafd5062590305826ebc6fecb48cd2trawick if (new == NULL) {
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl perror("malloc");
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung fprintf(stderr, "Insufficient memory\n");
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung exit(1);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl }
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *current = new;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl new->next = NULL;
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung new->ipnum = ipnum;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr),
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl AF_INET);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (hostdata == NULL) {
eacb724157bafd5062590305826ebc6fecb48cd2trawick if (h_errno > MAX_ERR)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl errors[UNKNOWN_ERR]++;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl else
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl errors[h_errno]++;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl new->noname = h_errno;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl name = strdup(inet_ntoa(ipnum));
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl }
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl else {
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl new->noname = 0;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl name = strdup(hostdata->h_name);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (check) {
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (name == NULL) {
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl perror("strdup");
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(stderr, "Insufficient memory\n");
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl exit(1);
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung }
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung hostdata = gethostbyname(name);
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung if (hostdata != NULL) {
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung char **hptr;
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl break;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (*hptr == NULL)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl hostdata = NULL;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl }
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (hostdata == NULL) {
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(stderr, "Bad host: %s != %s\n", name,
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl inet_ntoa(ipnum));
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl new->noname = NO_REVERSE;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl free(name);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl name = strdup(inet_ntoa(ipnum));
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl errors[NO_REVERSE]++;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl }
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl }
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl }
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl new->hostname = name;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (new->hostname == NULL) {
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl perror("strdup");
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(stderr, "Insufficient memory\n");
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl exit(1);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl }
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl }
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl else
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl cachehits++;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl /* size of string == MAXDNAME +1 */
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl strncpy(string, (*current)->hostname, MAXDNAME);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl string[MAXDNAME] = '\0';
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl}
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl/*
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * prints various statistics to output
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl */
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslstatic void stats (FILE *output)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl{
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl int i;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl char *ipstring;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl struct nsrec *current;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl char *errstring[MAX_ERR + 3];
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl for (i = 0; i < MAX_ERR + 3; i++)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl errstring[i] = "Unknown error";
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl errstring[HOST_NOT_FOUND] = "Host not found";
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl errstring[TRY_AGAIN] = "Try again";
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl errstring[NO_RECOVERY] = "Non recoverable error";
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl errstring[NO_DATA] = "No data record";
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl errstring[NO_ADDRESS] = "No address";
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl errstring[NO_REVERSE] = "No reverse entry";
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, "logresolve Statistics:\n");
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, "Entries: %d\n", entries);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, " With name : %d\n", withname);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, " Resolves : %d\n", resolves);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (errors[HOST_NOT_FOUND])
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, " - Not found : %d\n", errors[HOST_NOT_FOUND]);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (errors[TRY_AGAIN])
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, " - Try again : %d\n", errors[TRY_AGAIN]);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (errors[NO_DATA])
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, " - No data : %d\n", errors[NO_DATA]);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (errors[NO_ADDRESS])
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, " - No address: %d\n", errors[NO_ADDRESS]);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (errors[NO_REVERSE])
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, " - No reverse: %d\n", errors[NO_REVERSE]);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, "Cache hits : %d\n", cachehits);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, "Cache size : %d\n", cachesize);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, "Cache buckets : IP number * hostname\n");
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl for (i = 0; i < BUCKETS; i++)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl for (current = nscache[i]; current != NULL; current = current->next) {
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl ipstring = inet_ntoa(current->ipnum);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (current->noname == 0)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, " %3d %15s - %s\n", i, ipstring,
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl current->hostname);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl else {
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (current->noname > MAX_ERR + 2)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, " %3d %15s : Unknown error\n", i,
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl ipstring);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl else
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl fprintf(output, " %3d %15s : %s\n", i, ipstring,
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl errstring[current->noname]);
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl }
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl }
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl}
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung/*
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung * gets a line from stdin
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung */
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
c3ea2f06571c877091cd2f1016e47b1d5660df9drjungstatic int get_line (char *s, int n)
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung{
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung char *cp;
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung if (!fgets(s, n, stdin))
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung return (0);
c3ea2f06571c877091cd2f1016e47b1d5660df9drjung cp = strchr(s, '\n');
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl if (cp)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl *cp = '\0';
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl return (1);
fda1a61aacb6950953b7393b845b0639d8e87359trawick}
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jslint main (int argc, char *argv[])
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl{
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl struct in_addr ipnum;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl int i, check;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl#if defined(WIN32) || defined(NETWARE)
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl /* If we apr'ify this code, apr_pool_create/apr_pool_destroy
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl * should perform the WSAStartup/WSACleanup for us.
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl */
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl WSADATA wsaData;
8a5db6a3d29e28627bf8a6d6f7066e840da6bdf2jsl WSAStartup(MAKEWORD(2, 0), &wsaData);
#endif
check = 0;
statfile = NULL;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-c") == 0)
check = 1;
else if (strcmp(argv[i], "-s") == 0) {
if (i == argc - 1) {
fprintf(stderr, "logresolve: missing filename to -s\n");
exit(1);
}
i++;
statfile = argv[i];
}
else {
fprintf(stderr, "Usage: logresolve [-s statfile] [-c] < input > output\n");
exit(0);
}
}
for (i = 0; i < BUCKETS; i++)
nscache[i] = NULL;
for (i = 0; i < MAX_ERR + 2; i++)
errors[i] = 0;
while (get_line(line, MAXLINE)) {
if (line[0] == '\0')
continue;
entries++;
if (!apr_isdigit(line[0])) { /* short cut */
puts(line);
withname++;
continue;
}
bar = strchr(line, ' ');
if (bar != NULL)
*bar = '\0';
ipnum.s_addr = inet_addr(line);
if (ipnum.s_addr == 0xffffffffu) {
if (bar != NULL)
*bar = ' ';
puts(line);
withname++;
continue;
}
resolves++;
cgethost(ipnum, hoststring, check);
if (bar != NULL)
printf("%s %s\n", hoststring, bar + 1);
else
puts(hoststring);
}
#if defined(WIN32) || defined(NETWARE)
WSACleanup();
#endif
if (statfile != NULL) {
FILE *fp;
fp = fopen(statfile, "w");
if (fp == NULL) {
fprintf(stderr, "logresolve: could not open statistics file '%s'\n"
,statfile);
exit(1);
}
stats(fp);
fclose(fp);
}
return (0);
}