These patches are written by Dark@Igor for Dutch Mountains, in December 1995.
They are freely redistributable.
diff -u src.ident/comm.c src.hname/comm.c
--- src.ident/comm.c Wed Jan 3 22:41:48 1996
+++ src.hname/comm.c Thu Jan 4 19:07:20 1996
@@ -70,8 +70,6 @@
char * const him_her [] = { "it", "him", "her" };
char * const his_her [] = { "its", "his", "her" };
-bool fLookupAddress = TRUE; /* Change here to disable nameserver default */
-
/*
* Signal handling.
* Apollo has a problem with __attribute(atomic) in signal.h,
@@ -161,6 +159,10 @@
fd_set *exceptfds, struct timeval *timeout ) );
int socket args( ( int domain, int type, int protocol ) );
int write args( ( int fd, char *buf, int nbyte ) );
+pid_t vfork args( ( void ) );
+int dup2 args( ( int oldfd, int newfd ) );
+int execlp args( ( const char *file, const char *arg, ... ) );
+unsigned long inet_addr args( ( const char *cp ) );
#endif
#if defined(macintosh)
@@ -283,7 +285,12 @@
long boot_time; /* Time when merc started up */
long current_time; /* Time of this pulse */
int players_max; /* Maximum numbers of players */
-
+int hname; /* Connects to hname resolver */
+struct {
+ long addr;
+ char *hname;
+} hname_table[MAX_HNAME]; /* Caches hostnames */
+int hname_index; /* Cycles through hname_table */
/*
* OS-dependent local functions.
@@ -297,6 +304,8 @@
#if defined(unix)
void game_loop_unix args( ( int control ) );
int init_socket args( ( int port ) );
+void init_hname args( ( char *mainpath ) );
+void get_hname args( ( void ) );
int getrlimit args( ( int resource, struct rlimit *rlp ) );
/*
int setrlimit args( ( int resource, struct rlimit *rlp ) );
@@ -421,6 +430,7 @@
#if defined(unix)
boot_db( );
+ init_hname( argv[0] );
control = init_socket( port );
sprintf( log_buf, "Dutch Mountains ready to rock on port %d.", port );
log_string( log_buf );
@@ -438,6 +448,63 @@
#if defined(unix)
+void init_hname( char *mainpath )
+{
+ int sockets[2];
+ int pid;
+ static char *hnamepath;
+ char *p;
+
+ p = strrchr( mainpath, '/' );
+ if ( p ) {
+ /* 7 is length of "hname" plus slash plus terminating 0 */
+ hnamepath = alloc_mem( p - mainpath + 7 );
+ strncpy( hnamepath, mainpath, p - mainpath + 1 );
+ strcat( hnamepath, "hname" );
+ }
+ else
+ {
+ hnamepath = str_dup( "hname" );
+ }
+
+#ifndef FNDELAY
+#define FNDELAY O_NDELAY
+#endif
+
+ if ( socketpair( AF_UNIX, SOCK_STREAM, 0, sockets) >= 0 )
+ {
+ pid = vfork();
+ if ( pid > 0 )
+ { /* parent */
+ hname = sockets[1];
+ close( sockets[0] );
+ free_string( hnamepath );
+ signal(SIGPIPE, SIG_IGN);
+ if ( fcntl( hname, F_SETFL, FNDELAY) < 0 )
+ {
+ perror("init_hname: fcntl");
+ close( hname );
+ hname = -1;
+ }
+ }
+ else if ( pid == 0 )
+ { /* child */
+ close(sockets[1]);
+ dup2( sockets[0], 0 );
+ dup2( sockets[0], 1 );
+ execlp( hnamepath, "hname", NULL );
+ /* Still here? Then exec failed. */
+ exit( 1 );
+ }
+ else
+ { /* failure */
+ close(sockets[0]);
+ close(sockets[1]);
+ hname = -1;
+ }
+ }
+}
+
int init_socket( int port )
{
static struct sockaddr_in sa_zero;
@@ -781,6 +848,8 @@
FD_ZERO( &out_set );
FD_ZERO( &exc_set );
FD_SET( control, &in_set );
+ if ( hname >= 0 )
+ FD_SET( hname, &in_set );
maxdesc = control;
for ( d = descriptor_list; d != NULL; d = d->next )
{
@@ -812,6 +881,14 @@
new_descriptor( control );
}
+ /*
+ * New hostname found?
+ */
+ if ( hname >= 0 && FD_ISSET( hname, &in_set ) )
+ {
+ get_hname();
+ }
+
/*
* Kick out the freaky folks.
*/
@@ -1041,6 +1118,147 @@
return 1;
}
+#if defined(unix)
+void query_hname( DESCRIPTOR_DATA *desc )
+{
+ int i;
+ char buf[20];
+
+ /* Look in cache */
+ for ( i = 0; i < MAX_HNAME; i++ )
+ {
+ if ( desc->hostaddr == hname_table[i].addr )
+ {
+ free_string( desc->host );
+ desc->host = str_dup( hname_table[i].hname );
+ return;
+ }
+ }
+
+ /*
+ * Would be nice to use inet_ntoa here but it takes a struct arg,
+ * which ain't very compatible between gcc and system libraries.
+ */
+ sprintf( buf, "%ld.%ld.%ld.%ld",
+ ( desc->hostaddr >> 24 ) & 0xFF, ( desc->hostaddr >> 16 ) & 0xFF,
+ ( desc->hostaddr >> 8 ) & 0xFF, ( desc->hostaddr ) & 0xFF
+ );
+
+ desc->host = str_dup( buf );
+ strcat( buf, "\n" );
+ if ( write( hname, buf, strlen( buf ) ) < 0 )
+ {
+ close( hname );
+ hname = -1;
+ }
+}
+#endif
+
+#if defined(unix)
+static void add_hname( long addr, char *hname )
+{
+ char *p;
+ DESCRIPTOR_DATA *d, *d_next;
+ BAN_DATA *pban;
+ bool newchar;
+
+ hname_table[hname_index].addr = addr;
+ free_string( hname_table[hname_index].hname );
+ hname_table[hname_index].hname = hname;
+ hname_index = ( hname_index + 1 ) % MAX_HNAME;
+
+ for ( d = descriptor_list; d; d = d_next )
+ {
+ d_next = d->next;
+ if ( d->hostaddr == addr ) {
+ p = strrchr( d->host, '@' );
+ if ( p )
+ {
+ char *hostname;
+
+ hostname = alloc_mem( p - d->host + strlen( hname ) + 2 );
+ strncpy( hostname, d->host, p - d->host + 1 );
+ strcat( hostname, hname );
+ free_string( d->host );
+ d->host = hostname;
+ }
+ else
+ {
+ free_string( d->host );
+ d->host = str_dup( hname );
+ }
+
+ /*
+ * We now have a hostname, so check banishment.
+ */
+
+ /*
+ * NOT fully reliable. A fast typist on a fast link may
+ * get through the character generation process before the
+ * hostname lookup completes.
+ */
+ newchar = ( d->connected == CON_CONFIRM_NEW_NAME ||
+ d->connected == CON_GET_NEW_PASSWORD ||
+ d->connected == CON_CONFIRM_NEW_PASSWORD ||
+ d->connected == CON_GET_NEW_RACE ||
+ d->connected == CON_GET_NEW_SEX ||
+ d->connected == CON_GET_NEW_CLASS ||
+ d->connected == CON_GET_ALIGNMENT ||
+ d->connected == CON_GET_STATS );
+
+ for ( pban = ban_list; pban != NULL; pban = pban->next )
+ {
+ if ( !str_suffix( pban->name, d->host ) &&
+ ( newchar || pban->flag ) )
+ {
+ if ( d->character == NULL || d->character->name == NULL )
+ sprintf( log_buf, "[%s] has been banned", d->host );
+ else
+ sprintf( log_buf, "%s [%s] has been banned",
+ d->character->name, d->host );
+ log_string( log_buf );
+ output_channel( NULL, log_buf, CHA_CONNECT );
+ if (pban->flag)
+ write_to_buffer( d, "Your site has been banned"
+ " from this Mud.\n\r", 0 );
+ else
+ write_to_buffer( d, "Your site has been banned"
+ " for new players.\n\r", 0 );
+ close_socket( d, FALSE );
+ return;
+ }
+ }
+ }
+ }
+}
+
+void get_hname( void )
+{
+ char buf[MAX_STRING_LENGTH + 1];
+ char *p, *q, *r;
+ long addr;
+ int size;
+
+ size = read( hname, buf, MAX_STRING_LENGTH );
+ if ( size < 0 )
+ {
+ close( hname );
+ hname = -1;
+ }
+
+ buf[size] = '\0';
+ q = buf;
+ while ( (p = strchr( q, '\n' )) )
+ {
+ *p = '\0';
+ addr = inet_addr( q );
+ r = strchr( q, ' ' );
+ if ( addr && r )
+ add_hname( ntohl( addr ), str_dup( r+1 ) );
+ q = p + 1;
+ }
+}
+#endif
void do_maxusers( CHAR_DATA *ch, char *argument )
@@ -1301,14 +1519,12 @@
void new_descriptor( int control )
{
static DESCRIPTOR_DATA d_zero;
- char buf[MAX_STRING_LENGTH];
DESCRIPTOR_DATA *dnew;
/* BB: Unused
DESCRIPTOR_DATA *test_list;
*/
BAN_DATA *pban;
struct sockaddr_in sock;
- struct hostent *from;
int desc;
int size;
int iHistory;
@@ -1361,32 +1577,12 @@
{
perror( "New_descriptor: getpeername" );
dnew->host = str_dup( "(unknown)" );
+ dnew->hostaddr = 0;
}
else
{
- /*
- * Would be nice to use inet_ntoa here but it takes a struct arg,
- * which ain't very compatible between gcc and system libraries.
- */
- int addr;
-
- addr = ntohl( sock.sin_addr.s_addr );
- sprintf( buf, "%d.%d.%d.%d",
- ( addr >> 24 ) & 0xFF, ( addr >> 16 ) & 0xFF,
- ( addr >> 8 ) & 0xFF, ( addr ) & 0xFF
- );
- /*
- * Next two lines can be disabled to reduce lag.
- */
- if ( fLookupAddress )
- {
- from = gethostbyaddr( (char *) &sock.sin_addr,
- sizeof(sock.sin_addr), AF_INET );
- }
- else
- from = NULL;
-
- dnew->host = str_dup( from ? from->h_name : buf );
+ dnew->hostaddr = ntohl( sock.sin_addr.s_addr );
+ query_hname( dnew );
}
dnew->ident = new_ident( dnew );
@@ -1398,6 +1594,11 @@
* using automated 'autodialers' and leaving connections hanging.
*
* Furey: added suffix check by request of Nickel of HiddenWorlds.
+ */
+
+ /*
+ * At this point, the hostname may or may not be known.
+ * There is another check in get_hname().
*/
for ( pban = ban_list; pban != NULL; pban = pban->next )
Only in src.hname: hname.c
diff -u src.ident/makefile src.hname/makefile
--- src.ident/makefile Wed Dec 6 15:17:16 1995
+++ src.hname/makefile Wed Jan 3 22:44:10 1996
@@ -10,6 +10,11 @@
interp.o newcommands.o magic.o save.o show.o special.o spells.o \
trap.o update.o
+all: merc hname
+
+hname: hname.c
+ $(CC) $(D_FLAGS) $< -o hname
+
merc: $(O_FILES)
$(CC) $(D_FLAGS) $(L_FLAGS) -o merc *.o
diff -u src.ident/merc.h src.hname/merc.h
--- src.ident/merc.h Thu Dec 28 02:30:36 1995
+++ src.hname/merc.h Wed Jan 3 22:50:51 1996
@@ -132,6 +132,7 @@
#define MAX_RACE 5
#define MAX_STAT 6
#define MAX_HISTORY 20
+#define MAX_HNAME 400
#define MAX_LEVEL 46
#define MAX_SKILL 212
#define MAX_SCAN_RANGE 3
@@ -269,6 +270,7 @@
char incomm [MAX_INPUT_LENGTH];
char * history [MAX_HISTORY];
sh_int nhistory;
+ long hostaddr;
char * outbuf;
int outsize;
int outtop;