home *** CD-ROM | disk | FTP | other *** search
- /*
- * doremote.c -- contact remote hosts for finger
- *
- * Copyright (c) 1986, 1990 Barry Z. Shein and 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.
- */
-
- /*
- * Barry Shein, Boston University
- * routine to attach to remote finger server
- * addition to finger.c
- *
- * Adapted to new finger; Phil Budne, Boston University
- *
- * Conforms (as much as I can tell) to RFC742
- * [which is a pretty liberal document]
- *
- * Note: Not all finger daemons support multiple requests.
- * According to my reading of the RFC this is allowed, the
- * correct format (which we use here) is name,name,name\r\n
- */
-
-
- # ifndef lint
- static char *rcsid = "$Id: doremote.c,v 3.0 90/07/06 13:10:32 budd Rel $";
- # endif /* lint not defined */
-
- # include <sys/types.h>
- # include <netinet/in.h>
- # include <sys/socket.h>
- # include <strings.h>
- # include <netdb.h>
- # include <ctype.h>
- # include <stdio.h>
-
- # include "remote.h"
- # include "args.h"
- # include "finger.h"
-
- # define SERVICE "finger"
- # define PROTOCOL "tcp"
-
- extern char *inet_ntoa(); /* from library */
-
- FORWARD LOCAL void prhost();
-
- # ifndef DEF_PORT
- # ifdef IPPORT_FINGER
- # define DEF_PORT IPPORT_FINGER
- # else /* IPPORT_FINGER not defined */
- # define DEF_PORT 79
- # endif /* IPPORT_FINGER not defined */
- # endif /* DEF_PORT not defined */
-
- LOCAL short port;
- GLOBAL void
- doremote( hosts )
- RHOST *hosts;
- {
- register char *cp;
- struct servent *sp;
- struct hostent *hp;
- RUSER *rup;
-
- if( hosts == NULL )
- return;
-
- if((sp = getservbyname(SERVICE,PROTOCOL)) == NULL)
- port = htons( DEF_PORT );
- else
- port = sp->s_port;
-
- /* loop for all host names */
- for( ; hosts != NULL ; hosts = hosts->rh_next ) {
-
- cp = hosts->rh_name; /* get host 'name' */
- rup = hosts->rh_user; /* get pointer to user chain */
-
- /* handle internet numeric format */
- if( isdigit( *cp ) ) {
- struct in_addr haddr;
- char temp[ 128 ];
-
- haddr.s_addr = inet_addr( cp ); /* get address */
-
- /* try to get name for address */
- if((hp = gethostbyaddr(&haddr, sizeof(haddr), AF_INET)) == NULL ) {
- if( net_host( temp, haddr ) ) /* failed, try network name */
- prhost( temp );
- else /* total lossage */
- prhost( inet_ntoa( haddr ) ); /* reformat!! */
- /* ie; 10.4 -> 10.0.0.4 */
- tryaddr( &haddr, rup ); /* try just given addr */
- continue; /* next host */
- }
- # ifdef JUST_ADDR_GIVEN
- prhost( hp->h_name ); /* official name */
- tryaddr( &haddr, rup );
- continue; /* next host */
- # endif /* JUST_ADDR_GIVEN defined */
- } /* given number */
- else if( (hp = gethostbyname(cp)) == NULL ) {
- /* try other networks here?! */
-
- # ifdef HAVE_H_ERRNO
- extern int h_errno, h_nerr;
- extern char *h_errlist[];
-
- if( h_errno > 0 && h_errno <= h_nerr )
- fprintf(stderr,"%%%s: %s\n", h_errlist[h_errno], cp );
- else
- # endif /* HAVE_H_ERRNO defined */
- fprintf(stderr,"%%Unknown host: %s\n", cp );
- continue; /* next host */
- } /* hostbyname failed */
-
- prhost( hp->h_name ); /* show official name */
- # ifdef h_addr
- if( hp->h_addr_list != NULL ) {
- struct in_addr **lp;
-
- for( lp = (struct in_addr **)hp->h_addr_list; *lp != NULL; lp++ ) {
- /* Trying... used to be here */
- if( tryaddr( *lp, rup ) )
- break;
- } /* for each address */
- } /* have address list */
- else
- fprintf(stderr,"%%No addresses?\n"); /* should get h_errno set! */
- # else /* h_addr not defined */
- tryaddr( hp->h_addr, rup );
- # endif /* h_addr not defined */
- } /* for each host */
- } /* doremote*/
-
- int
- tryaddr( addr, rup )
- struct in_addr *addr;
- register RUSER *rup;
- {
- char buf[BUFSIZ+1], *cp;
- struct sockaddr_in sin; /* so much for protcol independance */
- FILE *f;
- int s;
-
- if( (s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
- perror("socket");
- return( FALSE );
- } /* socket failed */
-
- bzero( (char *) &sin, sizeof( sin ) );
- bcopy( (char *) addr, (char *) &sin.sin_addr, sizeof( sin.sin_addr ) );
- sin.sin_family = AF_INET;
- sin.sin_port = port;
-
- # ifndef DONT_SAY_TRYING
- /* show all non-local addrs? */
- /* only show if multi-homed */
- /* only show address on error w/ multi-homed host? */
- printf("Trying %s...\n", inet_ntoa(*addr) );
- # endif /* DONT_SAY_TRYING not defined */
-
- if( connect( s, (char *) &sin, sizeof( sin ) ) < 0 ) {
- perror("connect");
- close(s);
- return( FALSE );
- }
-
- /*
- * Build into one buffer for the host
- * terminate with CR-LF
- */
-
- buf[0] = EOS;
- if( sw_whois )
- strcat(buf," /w ");
-
- while( rup != NULL ) {
- strcat(buf,rup->ru_name) ;
- if( (rup = rup->ru_next) != NULL )
- strcat(buf,",");
- } /* while rup */
-
- strcat(buf,"\r\n") ;
- /*
- * Send request
- */
- if( write(s, buf, strlen( buf ) ) < 0 ) {
- perror("write");
- close(s);
- return( FALSE );
- }
-
- /*
- * Read and display result
- */
- f = fdopen(s, "r");
- while( fgets(buf, BUFSIZ, f) != NULL ) {
- /* blast \r as well? */
- if( (cp = index( buf, '\n' )) != NULL ) /* strip newlines */
- *cp = EOS;
- outline( buf ); /* output as much as will fit */
- } /* while */
- fclose( f );
- return( TRUE );
- } /* doremote */
-
- LOCAL void
- prhost( name )
- char *name;
- {
- char buf[255];
-
- blankline();
- sprintf(buf, "[%s]", name); /* format string */
- outline( HZUP(buf) ); /* output it (upper cased) */
- fflush( stdout );
- } /* prhost */
-
- /*
- * Local variables:
- * comment-column: 40
- * End:
- */
-