145 lines
4.4 KiB
C
145 lines
4.4 KiB
C
/*********************************************************************\
|
|
* Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu) *
|
|
* *
|
|
* You may copy or modify this file in any manner you wish, provided *
|
|
* that this notice is always included, and that you hold the author *
|
|
* harmless for any loss or damage resulting from the installation or *
|
|
* use of this software. *
|
|
\*********************************************************************/
|
|
|
|
#include "tweak.h"
|
|
#include "server_def.h"
|
|
#include "s_extern.h"
|
|
#include <ctype.h>
|
|
#include <netdb.h>
|
|
#ifdef STDC_HEADERS
|
|
#include <stdlib.h>
|
|
#endif
|
|
#include "my-string.h"
|
|
|
|
/****************************************************************************
|
|
* This file contains routines to maintain client database.
|
|
****************************************************************************/
|
|
|
|
static HTAB *htab; /* client data base. */
|
|
static unsigned hcnt; /* number of clients. */
|
|
static unsigned htot = 0; /* available entries in the data base. */
|
|
static HTAB hzero;
|
|
|
|
#define HALLOC_SIZE 30
|
|
|
|
/****************************************************************************
|
|
* Look up the hostname for an inet number. Return NULL if not found.
|
|
****************************************************************************/
|
|
|
|
static char *find_hostname PROTO1(unsigned long, inet_num)
|
|
{
|
|
struct hostent *he;
|
|
char *hostname;
|
|
|
|
if ((he = gethostbyaddr((char*)&inet_num, sizeof(inet_num), AF_INET))) {
|
|
hostname = malloc(strlen(he->h_name)+1);
|
|
strcpy(hostname, he->h_name);
|
|
} else
|
|
hostname = 0;
|
|
|
|
return hostname;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Returns an entry from the database corresponding to to the inet number.
|
|
* A new entry is created is it is not found.
|
|
* The database is a linear array of sorted structures.
|
|
* Entries are searched using binary search on the array.
|
|
****************************************************************************/
|
|
|
|
HTAB *find_host PROTO1(unsigned long, inet_num)
|
|
{
|
|
unsigned l, h, m, i;
|
|
unsigned long inum;
|
|
HTAB *hs, *hd;
|
|
|
|
for(l = 0, h = hcnt-1; (m = (l + h) >> 1) != l; ) { /* binary search */
|
|
inum = htab[m].inet_num;
|
|
if(inum > inet_num) h = m;
|
|
else if(inum < inet_num) l = m;
|
|
else {
|
|
/* if we *need* reverse naming and we haven't already got one
|
|
then try looking it up again. */
|
|
if (no_unnamed && !htab[m].hostname)
|
|
htab[m].hostname = find_hostname(inum);
|
|
htab[m].acc_cnt++;
|
|
return(htab+m);
|
|
}
|
|
}
|
|
|
|
if(htab[m].inet_num < inet_num) m++; /* locate first entry that is > */
|
|
|
|
if((hcnt+1) > htot) { /* need more space */
|
|
htot += HALLOC_SIZE; /* add HALLOC_SIZE entries at a time */
|
|
|
|
if(!(htab = (HTAB *) realloc(htab,sizeof(HTAB)*htot))) {
|
|
perror("grow_htab realloc");
|
|
exit(5);
|
|
}
|
|
}
|
|
|
|
for(i = hcnt-m, hs = htab+hcnt, hd=htab+hcnt+1; i--; *--hd = *--hs);
|
|
|
|
htab[m]=hzero;
|
|
htab[m].inet_num = inet_num;
|
|
htab[m].hostname = find_hostname(inet_num);
|
|
hcnt++;
|
|
return(htab+m);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Client database initialization routine.
|
|
****************************************************************************/
|
|
|
|
int init_htab PROTO0((void)) /* always have 2 entries -- 0, MAXINT */
|
|
{
|
|
if(!(htab = (HTAB *) malloc(sizeof(HTAB)*HALLOC_SIZE))) {
|
|
perror("grow_htab malloc");
|
|
exit(5);
|
|
}
|
|
htab[0] = hzero;
|
|
htab[1] = hzero;
|
|
htab[1].inet_num = ~0U;
|
|
hcnt = 2;
|
|
htot = HALLOC_SIZE;
|
|
return(0);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Write out the client table in the .HTAB_DUMP file.
|
|
****************************************************************************/
|
|
|
|
int dump_htab PROTO1(FILE *,fp)
|
|
{
|
|
int i;
|
|
HTAB *hp;
|
|
|
|
if( fp == NULL)
|
|
{
|
|
if(dbug)
|
|
fp=stdout;
|
|
else
|
|
return(0);
|
|
}
|
|
|
|
fprintf(fp,"#FSP Server "PACKAGE_VERSION", dumping at %s\nHost table content:\n",ctime(&cur_time));
|
|
|
|
fprintf(fp,"#IP address\tcount last access date\n");
|
|
for(i = hcnt-2, hp = htab+1; i--; hp++) {
|
|
fprintf(fp,"%d.%d.%d.%d\t%5d %s", ((unsigned char *)(&hp->inet_num))[0],
|
|
((unsigned char *)(&hp->inet_num))[1],
|
|
((unsigned char *)(&hp->inet_num))[2],
|
|
((unsigned char *)(&hp->inet_num))[3],
|
|
hp->acc_cnt,
|
|
ctime((time_t *) &(hp->last_acc)));
|
|
}
|
|
fprintf(fp,"\n#END\n");
|
|
return(0);
|
|
}
|