logresolve.c revision f551d6effa8e95b39f31f727c5cc748f349317c4
/*
* logresolve 1.1
*
* Tom Rathborne - tomr@uunet.ca - http://www.uunet.ca/~tomr/
* UUNET Canada, April 16, 1995
*
* Rewritten by David Robinson. (drtr@ast.cam.ac.uk)
*
* Usage: logresolve [-s filename] [-c] < access_log > new_log
*
* Arguments:
* -s filename name of a file to record statistics
* -c check the DNS for a matching A record for the host.
*
* Notes:
*
* To generate meaningful statistics from an HTTPD log file, it's good
* to have the domain name of each machine that accessed your site, but
* doing this on the fly can slow HTTPD down.
*
* Compiling NCSA HTTPD with the -DMINIMAL_DNS flag turns IP#->hostname
* resolution off. Before running your stats program, just run your log
* file through this program (logresolve) and all of your IP numbers will
* be resolved into hostnames (where possible).
*
* logresolve takes an HTTPD access log (in the COMMON log file format,
* field for that matter), and outputs the same file with all of the
* domain names looked up. Where no domain name can be found, the IP
* number is left in.
*
* To minimize impact on your nameserver, logresolve has its very own
* internal hash-table cache. This means that each IP number will only
* be looked up the first time it is found in the log file.
*
* The -c option causes logresolve to apply the same check as httpd
* compiled with -DMAXIMUM_DNS; after finding the hostname from the IP
* address, it looks up the IP addresses for the hostname and checks
* that one of these matches the original address.
*/
#include "ap_config.h"
#include <ctype.h>
#include <stdio.h>
#endif
static int getline(char *s, int n);
#ifdef BEOS
#define NO_ADDRESS NO_DATA
#endif
/* maximum line length */
#define MAXLINE 1024
/* maximum length of a domain name */
#ifndef MAXDNAME
#define MAXDNAME 256
#endif
/* number of buckets in cache hash ap_table_t */
#define BUCKETS 256
#if defined(NEED_STRDUP)
{
char *dup;
return NULL;
return dup;
}
#endif
/*
* struct nsrec - record of nameservice for cache linked list
*
* ipnum - IP number hostname - hostname noname - nonzero if IP number has no
* hostname, i.e. hostname=IP number
*/
struct nsrec {
char *hostname;
int noname;
/*
* statistics - obvious
*/
#ifndef h_errno
extern int h_errno; /* some machines don't have this in their headers */
#endif
/* largest value for h_errno */
#define MAX_ERR (NO_ADDRESS)
static int cachehits = 0;
static int cachesize = 0;
static int entries = 0;
static int resolves = 0;
static int withname = 0;
/*
* cgethost - gets hostname by IP address, caching, and adding unresolvable
* IP numbers with their IP number as hostname, setting noname flag
*/
{
char *name;
cachesize++;
perror("malloc");
exit(1);
}
AF_INET);
errors[UNKNOWN_ERR]++;
else
}
else {
if (check) {
perror("strdup");
exit(1);
}
char **hptr;
break;
}
errors[NO_REVERSE]++;
}
}
}
perror("strdup");
exit(1);
}
}
else
cachehits++;
/* size of string == MAXDNAME +1 */
}
/*
* prints various statistics to output
*/
{
int i;
char *ipstring;
for (i = 0; i < MAX_ERR + 3; i++)
errstring[i] = "Unknown error";
if (errors[HOST_NOT_FOUND])
if (errors[NO_ADDRESS])
if (errors[NO_REVERSE])
for (i = 0; i < BUCKETS; i++)
else {
ipstring);
else
}
}
}
/*
* gets a line from stdin
*/
static int getline (char *s, int n)
{
char *cp;
return (0);
if (cp)
*cp = '\0';
return (1);
}
{
int i, check;
#ifdef WIN32
/* If we apr'ify this code, ap_create_pool/ap_destroy_pool
* should perform the WSAStartup/WSACleanup for us.
*/
#endif
check = 0;
for (i = 1; i < argc; i++) {
check = 1;
if (i == argc - 1) {
exit(1);
}
i++;
}
else {
exit(0);
}
}
for (i = 0; i < BUCKETS; i++)
for (i = 0; i < MAX_ERR + 2; i++)
errors[i] = 0;
if (line[0] == '\0')
continue;
entries++;
withname++;
continue;
}
*bar = '\0';
*bar = ' ';
withname++;
continue;
}
resolves++;
else
}
#ifdef WIN32
WSACleanup();
#endif
,statfile);
exit(1);
}
}
return (0);
}