home *** CD-ROM | disk | FTP | other *** search
- /*
- * undomain.c -- massage host names
- *
- * Copyright (C) 1986, 1990 Philip L. Budne
- *
- * This file is part of "Phil's Finger Program".
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- */
-
- # ifndef lint
- static char *rcsid = "$Id: undomain.c,v 3.0 90/07/06 13:12:06 budd Rel $";
- # endif /* lint not defined */
-
- # include <stdio.h> /* for NULL */
- # include <strings.h> /* for (r)index */
- # include <ctype.h> /* for isdigit() */
- # include <sys/types.h> /* for socket.h */
- # include <sys/socket.h> /* for AF_INET */
- # include <netdb.h> /* for {host,net}ent structs */
- # include <arpa/inet.h> /* for inet_.... */
- # include <netinet/in.h> /* for in_addr */
- # include "finger.h"
- # include "upper.h"
-
- # if 1
- # define SCMP(a,b) casecmp(a,b)
- # define CCMP(a,b) TOUP(a) == TOUP(b)
- # define TOUP(c) uppercase[c&0177]
- # else /* not 1 */
- # define SCMP(a,b) (strcmp(a,b) == 0)
- # define CCMP(a,b) a == b
- # endif /* not 1 */
-
- extern char localhost[]; /* from args.c */
- extern char OFFICIALhostname[]; /* from args.c */
-
- extern char *conf_prefix(); /* from conf.c */
-
- LOCAL char *prefixes[] = { /* read from init file? */
- /* Sorted by length?? */
- # ifdef PREFIXES
- PREFIXES ,
- # endif /* PREFIXES defined */
- NULL
- };
-
- LOCAL BOOL tryprefix( hp, pp )
- register char *pp, *hp;
- {
- char *h;
- # ifdef DEBUG
- printf("tryprefix(%s,%s)\n", hp, pp );
- # endif /* DEBUG defined */
- h = hp; /* save host buffer pointer */
- while( CCMP(*hp,*pp) && *pp != EOS ) {
- hp++;
- pp++;
- } /* while prefix matches */
- if( *hp == EOS ) /* saw end of host first? */
- return( FALSE ); /* ENTIRE hostname is a prefix?? */
- /* try next (shorter?) prefix */
-
- if( *pp == EOS ) /* saw end of prefix */
- strcpy( h, hp ); /* slide back (backwards overlap?) */
-
- return( TRUE );
- } /* tryprefix */
-
- LOCAL void unprefix( h )
- char *h;
- {
- char **ppp, *pp;
- int i;
-
- for( ppp = prefixes; *ppp != NULL; ppp++ )
- if( tryprefix( h, *ppp ) )
- return;
-
- for( i = 0; (pp = conf_prefix(i)) != NULL; i++ )
- if( tryprefix( h, pp ) )
- return;
- } /* unprefix */
-
- GLOBAL void undomain( h, rem_prefix )
- char *h;
- int rem_prefix;
- {
- int tries;
- register char *p1, *p2;
- char *op1;
-
- HZUP( h );
- p1 = rindex(h, '.'); /* find last dot in name */
- if( p1 != NULL ) { /* hack for well known domains */
- if( SCMP( p1, ".ARPA" ) ) {
- *p1 = EOS; /* zap it */
- return;
- } /* special case for .ARPA */
- } /* got last dot */
- else { /* no dots at all */
- # ifdef UNPREFIX_NODOMAIN
- if( rem_prefix )
- unprefix( h );
- # endif /* UNPREFIX_NODOMAIN defined */
- return;
- } /* no dots at all */
-
- tries = 0;
- p1 = index(h, '.'); /* find first dot in new name */
- if( p1 == NULL )
- return;
- p1++;
- op1 = p1;
-
- # if 0
- p2 = index( OFFICIALhostname, '.' ); /* find first dot in local name */
- if( p2 == NULL )
- return;
- p2++;
- # else /* not 0 */
- p2 = OFFICIALhostname; /* host may be a subdomain of ours */
- # endif /* not 0 */
-
- for( ; ; ) { /* loop1 */
- for( ; ; ) { /* loop2 */
- tries++;
- if( SCMP( p1, p2 ) ) { /* both suffixes match? */
- p1[-1] = EOS; /* yes remove common suffix */
- if( rem_prefix && tries == 1 ) {
- unprefix( h );
- return;
- } /* removing prefixes and full domain matches */
- } /* suffixes match */
-
- p1 = index( p1, '.' ); /* find next dot in target string */
- if( p1 == NULL ) /* no more? */
- break; /* loop2 */
- p1++;
- } /* loop2 */
-
- p2 = index( p2, '.' ); /* step to next higher local domain */
- if( p2 == NULL )
- break; /* loop1 */
- p2++;
- p1 = op1; /* go back to first target domain */
- } /* loop1 */
- } /* undomain */
-
- BOOL casecmp( a, b )
- register char *a, *b;
- {
- while( TOUP(*a) == TOUP(*b++) )
- if( *a == EOS )
- return( TRUE );
- else
- a++;
- return( FALSE );
- } /* casecmp */
-
- GLOBAL int checkhost( host, len )
- char *host;
- int len;
- {
- int o1, o2, o3, o4;
-
- /* exactly four octets? */
- if( isdigit( host[0] ) &&
- sscanf( host, "%d.%d.%d.%d", &o1, &o2, &o3, &o4 ) == 4 ) {
- char temp[ 256 ]; /* large */
- struct in_addr in;
- struct hostent *hp;
-
- /* make into an address */
- in.s_addr = (o1 << 24) | (o2 << 16) | (o3 << 8) | o4;
-
- /* assume login was dumb. try to reverse address */
- if( (hp = gethostbyaddr( &in, sizeof( in ), AF_INET )) != NULL ) {
- strzcpy( host, hp->h_name, len );
- return( TRUE );
- }
- else if( net_host( temp, in ) ) {
- strzcpy( host, temp, len );
- return( TRUE );
- } /* getnetbyaddr */
- } /* 4 dotted octets */
- return( FALSE );
- } /* checkhost */
-
- GLOBAL int
- net_host( buf, in )
- char *buf;
- struct in_addr in;
- {
- char octet[ 5 ];
- struct netent *np;
- long lna;
-
- if( (np = getnetbyaddr( inet_netof( in ), AF_INET )) != NULL ) {
- strcpy( buf, np->n_name );
-
- lna = inet_lnaof( in ); /* get "local net address" */
- if( lna & 0xff0000 ) { /* 2nd octet set */
- sprintf( octet, ".%d", (lna >> 16) & 0xff );
- strcat( buf, octet );
- }
- if( lna & 0xffff00 ) { /* 2nd or 3rd */
- sprintf( octet, ".%d", (lna >> 8) & 0xff );
- strcat( buf, octet );
- }
- sprintf( octet, ".%d", lna & 0xff ); /* Class A B and C */
- strcat( buf, octet );
- return( TRUE );
- }
- return( FALSE );
- }
- /*
- * Local variables:
- * comment-column: 40
- * End:
- */
-