logresolve.c revision bb65aeae7af1d33b64252bbc1b966942d757ac60
842ae4bd224140319ae7feec1872b93dfd491143fielding/*
842ae4bd224140319ae7feec1872b93dfd491143fielding * logresolve 1.1
842ae4bd224140319ae7feec1872b93dfd491143fielding *
842ae4bd224140319ae7feec1872b93dfd491143fielding * Tom Rathborne - tomr@uunet.ca - http://www.uunet.ca/~tomr/
842ae4bd224140319ae7feec1872b93dfd491143fielding * UUNET Canada, April 16, 1995
842ae4bd224140319ae7feec1872b93dfd491143fielding *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Rewritten by David Robinson. (drtr@ast.cam.ac.uk)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Usage: logresolve [-s filename] [-c] < access_log > new_log
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Arguments:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * -s filename name of a file to record statistics
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * -c check the DNS for a matching A record for the host.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Notes:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * To generate meaningful statistics from an HTTPD log file, it's good
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * to have the domain name of each machine that accessed your site, but
e8f95a682820a599fe41b22977010636be5c2717jim * doing this on the fly can slow HTTPD down.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
e8f95a682820a599fe41b22977010636be5c2717jim * Compiling NCSA HTTPD with the -DMINIMAL_DNS flag turns IP#->hostname
1747d30b98aa1bdbc43994c02cd46ab4cb9319e4fielding * resolution off. Before running your stats program, just run your log
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * file through this program (logresolve) and all of your IP numbers will
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * be resolved into hostnames (where possible).
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * logresolve takes an HTTPD access log (in the COMMON log file format,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * or any other format that has the IP number/domain name as the first
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * field for that matter), and outputs the same file with all of the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * domain names looked up. Where no domain name can be found, the IP
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * number is left in.
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * To minimize impact on your nameserver, logresolve has its very own
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * internal hash-table cache. This means that each IP number will only
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * be looked up the first time it is found in the log file.
5c0419d51818eb02045cf923a9fe456127a44c60wrowe *
5c0419d51818eb02045cf923a9fe456127a44c60wrowe * The -c option causes logresolve to apply the same check as httpd
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * compiled with -DMAXIMUM_DNS; after finding the hostname from the IP
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * address, it looks up the IP addresses for the hostname and checks
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * that one of these matches the original address.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include "apr_lib.h"
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton#if APR_HAVE_STDIO_H
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton#include <stdio.h>
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes#endif
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes#if APR_HAVE_CTYPE_H
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes#include <ctype.h>
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes#endif
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes#if APR_HAVE_NETDB_H
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes#include <netdb.h>
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes#endif
cd3bbd6d2df78d6c75e5d159a81ef8bdd5f70df9trawick#if APR_HAVE_NETINET_IN_H
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include <netinet/in.h>
0f60998368b493f90120180a93fc2e1e74490872covener#endif
0f60998368b493f90120180a93fc2e1e74490872covener#if APR_HAVE_SYS_SOCKET_H
0f60998368b493f90120180a93fc2e1e74490872covener#include <sys/socket.h>
0f60998368b493f90120180a93fc2e1e74490872covener#endif
0f60998368b493f90120180a93fc2e1e74490872covener#if APR_HAVE_ARPA_INET_H
0f60998368b493f90120180a93fc2e1e74490872covener#include <arpa/inet.h>
0f60998368b493f90120180a93fc2e1e74490872covener#endif
0f60998368b493f90120180a93fc2e1e74490872covener
87587593f1a53030e840acc0dec6cc881022ea40covenerstatic void cgethost(struct in_addr ipnum, char *string, int check);
87587593f1a53030e840acc0dec6cc881022ea40covenerstatic int getline(char *s, int n);
87587593f1a53030e840acc0dec6cc881022ea40covenerstatic void stats(FILE *output);
87587593f1a53030e840acc0dec6cc881022ea40covener
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#ifdef BEOS
43997561b2302d13dee973998e77743a3ddd2374trawick#define NO_ADDRESS NO_DATA
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
0568280364eb026393be492ebc732795c4934643jorton
0568280364eb026393be492ebc732795c4934643jorton
0568280364eb026393be492ebc732795c4934643jorton/* maximum line length */
0568280364eb026393be492ebc732795c4934643jorton#define MAXLINE 1024
0568280364eb026393be492ebc732795c4934643jorton
0568280364eb026393be492ebc732795c4934643jorton/* maximum length of a domain name */
0568280364eb026393be492ebc732795c4934643jorton#ifndef MAXDNAME
0568280364eb026393be492ebc732795c4934643jorton#define MAXDNAME 256
0568280364eb026393be492ebc732795c4934643jorton#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener/* number of buckets in cache hash apr_table_t */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener#define BUCKETS 256
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if !APR_HAVE_STRDUP
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholeschar *strdup (const char *str)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *dup;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!(dup = (char *) malloc(strlen(str) + 1)))
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
796e4a7141265d8ed7036e4628161c6eafb2a789jorton dup = strcpy(dup, str);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return dup;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * struct nsrec - record of nameservice for cache linked list
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * ipnum - IP number hostname - hostname noname - nonzero if IP number has no
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * hostname, i.e. hostname=IP number
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstruct nsrec {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes struct in_addr ipnum;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *hostname;
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe int noname;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes struct nsrec *next;
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin} *nscache[BUCKETS];
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin * statistics - obvious
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#ifndef h_errno
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesextern int h_errno; /* some machines don't have this in their headers */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* largest value for h_errno */
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin#define MAX_ERR (NO_ADDRESS)
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin#define UNKNOWN_ERR (MAX_ERR+1)
a1790fb35c4b352dab721370985c623a9f8f5062rpluem#define NO_REVERSE (MAX_ERR+2)
713a2b68bac4aeb1e9c48785006c0732451039depquerna
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic int cachehits = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic int cachesize = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic int entries = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic int resolves = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic int withname = 0;
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowestatic int errors[MAX_ERR + 3];
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * cgethost - gets hostname by IP address, caching, and adding unresolvable
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * IP numbers with their IP number as hostname, setting noname flag
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void cgethost (struct in_addr ipnum, char *string, int check)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes struct nsrec **current, *new;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener struct hostent *hostdata;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *name;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) +
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)];
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes current = &(*current)->next;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (*current == NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes cachesize++;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes new = (struct nsrec *) malloc(sizeof(struct nsrec));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (new == NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes perror("malloc");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes fprintf(stderr, "Insufficient memory\n");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes exit(1);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *current = new;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes new->next = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener new->ipnum = ipnum;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr),
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener AF_INET);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (hostdata == NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (h_errno > MAX_ERR)
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener errors[UNKNOWN_ERR]++;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener errors[h_errno]++;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes new->noname = h_errno;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes name = strdup(inet_ntoa(ipnum));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes new->noname = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes name = strdup(hostdata->h_name);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (check) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (name == NULL) {
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe perror("strdup");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes fprintf(stderr, "Insufficient memory\n");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes exit(1);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes hostdata = gethostbyname(name);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (hostdata != NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char **hptr;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes break;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (*hptr == NULL)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes hostdata = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (hostdata == NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes fprintf(stderr, "Bad host: %s != %s\n", name,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes inet_ntoa(ipnum));
1f299703465bd9975d94e9f229f76af807442de2covener new->noname = NO_REVERSE;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener free(name);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener name = strdup(inet_ntoa(ipnum));
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener errors[NO_REVERSE]++;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes new->hostname = name;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (new->hostname == NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes perror("strdup");
9ad7b260be233be7d7b5576979825cac72e15498rederpj fprintf(stderr, "Insufficient memory\n");
9ad7b260be233be7d7b5576979825cac72e15498rederpj exit(1);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes else
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes cachehits++;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* size of string == MAXDNAME +1 */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes strncpy(string, (*current)->hostname, MAXDNAME);
f2be127030aa4190033084f0a6add531c9bc41desf string[MAXDNAME] = '\0';
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
f2be127030aa4190033084f0a6add531c9bc41desf * prints various statistics to output
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
3e6d7277b90d3011db832139afc20efb5f17e203rederpj
3e6d7277b90d3011db832139afc20efb5f17e203rederpjstatic void stats (FILE *output)
3e6d7277b90d3011db832139afc20efb5f17e203rederpj{
3e6d7277b90d3011db832139afc20efb5f17e203rederpj int i;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *ipstring;
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes struct nsrec *current;
e8f95a682820a599fe41b22977010636be5c2717jim char *errstring[MAX_ERR + 3];
f2be127030aa4190033084f0a6add531c9bc41desf
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener for (i = 0; i < MAX_ERR + 3; i++)
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener errstring[i] = "Unknown error";
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener errstring[HOST_NOT_FOUND] = "Host not found";
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener errstring[TRY_AGAIN] = "Try again";
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener errstring[NO_RECOVERY] = "Non recoverable error";
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener errstring[NO_DATA] = "No data record";
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener errstring[NO_ADDRESS] = "No address";
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener errstring[NO_REVERSE] = "No reverse entry";
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, "logresolve Statistics:\n");
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, "Entries: %d\n", entries);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, " With name : %d\n", withname);
6683642c1e0032eeeed5f99e8c14880692ef84c5sf fprintf(output, " Resolves : %d\n", resolves);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (errors[HOST_NOT_FOUND])
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, " - Not found : %d\n", errors[HOST_NOT_FOUND]);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (errors[TRY_AGAIN])
6683642c1e0032eeeed5f99e8c14880692ef84c5sf fprintf(output, " - Try again : %d\n", errors[TRY_AGAIN]);
6683642c1e0032eeeed5f99e8c14880692ef84c5sf if (errors[NO_DATA])
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, " - No data : %d\n", errors[NO_DATA]);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (errors[NO_ADDRESS])
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, " - No address: %d\n", errors[NO_ADDRESS]);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (errors[NO_REVERSE])
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, " - No reverse: %d\n", errors[NO_REVERSE]);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, "Cache hits : %d\n", cachehits);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, "Cache size : %d\n", cachesize);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, "Cache buckets : IP number * hostname\n");
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener for (i = 0; i < BUCKETS; i++)
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener for (current = nscache[i]; current != NULL; current = current->next) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener ipstring = inet_ntoa(current->ipnum);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (current->noname == 0)
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, " %3d %15s - %s\n", i, ipstring,
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener current->hostname);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener else {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (current->noname > MAX_ERR + 2)
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, " %3d %15s : Unknown error\n", i,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ipstring);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener fprintf(output, " %3d %15s : %s\n", i, ipstring,
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener errstring[current->noname]);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener}
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener/*
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * gets a line from stdin
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovenerstatic int getline (char *s, int n)
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener{
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener char *cp;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (!fgets(s, n, stdin))
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener return (0);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener cp = strchr(s, '\n');
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (cp)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *cp = '\0';
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return (1);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes
0e05808dc59a321566303084c84b9826a4353cefrederpjint main (int argc, char *argv[])
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
b08925593f214f621161742925dcf074a8047e0acovener struct in_addr ipnum;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin int i, check;
465bb68501690d7a47bfd2a6129580047d76d8f1rederpj
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf#ifdef WIN32
465bb68501690d7a47bfd2a6129580047d76d8f1rederpj /* If we apr'ify this code, apr_create_pool/apr_destroy_pool
e8f95a682820a599fe41b22977010636be5c2717jim * should perform the WSAStartup/WSACleanup for us.
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes */
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes WSADATA wsaData;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin WSAStartup(0x101, &wsaData);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes#endif
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes check = 0;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes statfile = NULL;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes for (i = 1; i < argc; i++) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (strcmp(argv[i], "-c") == 0)
ebe5305f8b22507374358f32b74d12fb50c05a25covener check = 1;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes else if (strcmp(argv[i], "-s") == 0) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (i == argc - 1) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes fprintf(stderr, "logresolve: missing filename to -s\n");
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes exit(1);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
513b324e774c559b579896df131fd7c8471ed529rederpj i++;
513b324e774c559b579896df131fd7c8471ed529rederpj statfile = argv[i];
513b324e774c559b579896df131fd7c8471ed529rederpj }
513b324e774c559b579896df131fd7c8471ed529rederpj else {
513b324e774c559b579896df131fd7c8471ed529rederpj fprintf(stderr, "Usage: logresolve [-s statfile] [-c] < input > output\n");
513b324e774c559b579896df131fd7c8471ed529rederpj exit(0);
513b324e774c559b579896df131fd7c8471ed529rederpj }
513b324e774c559b579896df131fd7c8471ed529rederpj }
513b324e774c559b579896df131fd7c8471ed529rederpj
513b324e774c559b579896df131fd7c8471ed529rederpj for (i = 0; i < BUCKETS; i++)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes nscache[i] = NULL;
02fd88c85a9850109753b87612955ad372de1575sf for (i = 0; i < MAX_ERR + 2; i++)
02fd88c85a9850109753b87612955ad372de1575sf errors[i] = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (getline(line, MAXLINE)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (line[0] == '\0')
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes continue;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes entries++;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (!apr_isdigit(line[0])) { /* short cut */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes puts(line);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes withname++;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes continue;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes bar = strchr(line, ' ');
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (bar != NULL)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes *bar = '\0';
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ipnum.s_addr = inet_addr(line);
9ad7b260be233be7d7b5576979825cac72e15498rederpj if (ipnum.s_addr == 0xffffffffu) {
9ad7b260be233be7d7b5576979825cac72e15498rederpj if (bar != NULL)
9ad7b260be233be7d7b5576979825cac72e15498rederpj *bar = ' ';
9ad7b260be233be7d7b5576979825cac72e15498rederpj puts(line);
9ad7b260be233be7d7b5576979825cac72e15498rederpj withname++;
9ad7b260be233be7d7b5576979825cac72e15498rederpj continue;
9ad7b260be233be7d7b5576979825cac72e15498rederpj }
9ad7b260be233be7d7b5576979825cac72e15498rederpj
9ad7b260be233be7d7b5576979825cac72e15498rederpj resolves++;
9ad7b260be233be7d7b5576979825cac72e15498rederpj
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes cgethost(ipnum, hoststring, check);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (bar != NULL)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin printf("%s %s\n", hoststring, bar + 1);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes else
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes puts(hoststring);
ebe5305f8b22507374358f32b74d12fb50c05a25covener }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes#ifdef WIN32
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes WSACleanup();
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes#endif
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (statfile != NULL) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes FILE *fp;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin fp = fopen(statfile, "w");
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (fp == NULL) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes fprintf(stderr, "logresolve: could not open statistics file '%s'\n"
ebe5305f8b22507374358f32b74d12fb50c05a25covener ,statfile);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes exit(1);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes stats(fp);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes fclose(fp);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return (0);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes