home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / finger / part03 / doremote.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-03  |  5.6 KB  |  231 lines

  1. /*
  2.  * doremote.c -- contact remote hosts for finger
  3.  *
  4.  * Copyright (c) 1986, 1990  Barry Z. Shein and Philip L. Budne
  5.  *
  6.  * This file is part of "Phil's Finger Program".
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 1, or (at your option)
  11.  * any later version.
  12.  */
  13.  
  14. /*
  15.  *    Barry Shein, Boston University
  16.  *        routine to attach to remote finger server
  17.  *        addition to finger.c
  18.  *
  19.  *    Adapted to new finger; Phil Budne, Boston University
  20.  *
  21.  *    Conforms (as much as I can tell) to RFC742
  22.  *    [which is a pretty liberal document]
  23.  *
  24.  *    Note: Not all finger daemons support multiple requests.
  25.  *    According to my reading of the RFC this is allowed, the
  26.  *    correct format (which we use here) is name,name,name\r\n
  27.  */
  28.  
  29.  
  30. # ifndef lint
  31. static char *rcsid = "$Id: doremote.c,v 3.0 90/07/06 13:10:32 budd Rel $";
  32. # endif /* lint not defined */
  33.  
  34. # include <sys/types.h>
  35. # include <netinet/in.h>
  36. # include <sys/socket.h>
  37. # include <strings.h>
  38. # include <netdb.h>
  39. # include <ctype.h>
  40. # include <stdio.h>
  41.  
  42. # include "remote.h"
  43. # include "args.h"
  44. # include "finger.h"
  45.  
  46. # define SERVICE "finger"
  47. # define PROTOCOL "tcp"
  48.  
  49. extern char *inet_ntoa();        /* from library */
  50.  
  51. FORWARD LOCAL void prhost();
  52.  
  53. # ifndef DEF_PORT
  54. # ifdef IPPORT_FINGER
  55. # define DEF_PORT IPPORT_FINGER 
  56. # else  /* IPPORT_FINGER not defined */
  57. # define DEF_PORT 79
  58. # endif /* IPPORT_FINGER not defined */
  59. # endif /* DEF_PORT not defined */
  60.  
  61. LOCAL short port;
  62. GLOBAL void
  63. doremote( hosts )
  64. RHOST *hosts;
  65. {
  66.     register char *cp;
  67.     struct servent *sp;
  68.     struct hostent *hp;
  69.     RUSER *rup;
  70.  
  71.     if( hosts == NULL )
  72.     return;
  73.  
  74.     if((sp = getservbyname(SERVICE,PROTOCOL)) == NULL)
  75.     port = htons( DEF_PORT );
  76.     else
  77.     port = sp->s_port;
  78.  
  79.     /* loop for all host names */
  80.     for( ; hosts != NULL ; hosts = hosts->rh_next ) {
  81.  
  82.     cp = hosts->rh_name;            /* get host 'name' */
  83.     rup = hosts->rh_user;            /* get pointer to user chain */
  84.  
  85.     /* handle internet numeric format */
  86.     if( isdigit( *cp ) ) {
  87.         struct in_addr haddr;
  88.         char temp[ 128 ];
  89.  
  90.         haddr.s_addr = inet_addr( cp ); /* get address */
  91.  
  92.         /* try to get name for address */
  93.         if((hp = gethostbyaddr(&haddr, sizeof(haddr), AF_INET)) == NULL ) {
  94.         if( net_host( temp, haddr ) )    /* failed, try network name */
  95.             prhost( temp );
  96.         else                /* total lossage */
  97.             prhost( inet_ntoa( haddr ) ); /* reformat!! */
  98.                         /* ie; 10.4 -> 10.0.0.4 */
  99.         tryaddr( &haddr, rup );        /* try just given addr */
  100.         continue;            /* next host */
  101.         }
  102. # ifdef JUST_ADDR_GIVEN
  103.         prhost( hp->h_name );        /* official name */
  104.         tryaddr( &haddr, rup );
  105.         continue;                /* next host */
  106. # endif /* JUST_ADDR_GIVEN defined */
  107.     } /* given number */
  108.     else if( (hp = gethostbyname(cp)) == NULL ) {
  109.         /* try other networks here?! */
  110.  
  111. # ifdef HAVE_H_ERRNO
  112.         extern int h_errno, h_nerr;
  113.         extern char *h_errlist[];
  114.  
  115.         if( h_errno > 0 && h_errno <= h_nerr )
  116.         fprintf(stderr,"%%%s: %s\n", h_errlist[h_errno], cp );
  117.         else
  118. # endif /* HAVE_H_ERRNO defined */
  119.         fprintf(stderr,"%%Unknown host: %s\n", cp );
  120.         continue;                /* next host */
  121.     } /* hostbyname failed */
  122.  
  123.     prhost( hp->h_name );        /* show official name */
  124. # ifdef h_addr
  125.     if( hp->h_addr_list != NULL ) {
  126.         struct in_addr **lp;
  127.  
  128.         for( lp = (struct in_addr **)hp->h_addr_list; *lp != NULL; lp++ ) {
  129.         /* Trying... used to be here */
  130.         if( tryaddr( *lp, rup ) )
  131.             break;
  132.         } /* for each address */
  133.     } /* have address list */
  134.     else
  135.         fprintf(stderr,"%%No addresses?\n"); /* should get h_errno set! */
  136. # else  /* h_addr not defined */
  137.     tryaddr( hp->h_addr, rup );
  138. # endif /* h_addr not defined */
  139.     } /* for each host */
  140. } /* doremote*/
  141.  
  142. int
  143. tryaddr( addr, rup )
  144.     struct in_addr *addr;
  145.     register RUSER *rup;
  146. {
  147.     char buf[BUFSIZ+1], *cp;
  148.     struct sockaddr_in sin;        /* so much for protcol independance */
  149.     FILE *f;
  150.     int s;
  151.  
  152.     if( (s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
  153.     perror("socket");
  154.     return( FALSE );
  155.     } /* socket failed */
  156.  
  157.     bzero( (char *) &sin, sizeof( sin ) );
  158.     bcopy( (char *) addr, (char *) &sin.sin_addr, sizeof( sin.sin_addr ) );
  159.     sin.sin_family = AF_INET;
  160.     sin.sin_port = port;
  161.  
  162. # ifndef DONT_SAY_TRYING
  163.     /* show all non-local addrs? */
  164.     /* only show if multi-homed */
  165.     /* only show address on error w/ multi-homed host? */
  166.     printf("Trying %s...\n", inet_ntoa(*addr) );
  167. # endif /* DONT_SAY_TRYING not defined */
  168.  
  169.     if( connect( s, (char *) &sin, sizeof( sin ) ) < 0 ) {
  170.     perror("connect");
  171.     close(s);
  172.     return( FALSE );
  173.     }
  174.  
  175.     /*
  176.      *    Build into one buffer for the host
  177.      *    terminate with CR-LF
  178.      */
  179.  
  180.     buf[0] = EOS;
  181.     if( sw_whois )
  182.     strcat(buf," /w ");
  183.  
  184.     while( rup != NULL ) {
  185.     strcat(buf,rup->ru_name) ;
  186.     if( (rup = rup->ru_next) != NULL )
  187.         strcat(buf,",");
  188.     } /* while rup */
  189.  
  190.     strcat(buf,"\r\n") ;
  191.     /*
  192.      *    Send request
  193.      */
  194.     if( write(s, buf, strlen( buf ) ) < 0 ) {
  195.     perror("write");
  196.     close(s);
  197.     return( FALSE );
  198.     }
  199.  
  200.     /*
  201.      *    Read and display result
  202.      */
  203.     f = fdopen(s, "r");
  204.     while( fgets(buf, BUFSIZ, f) != NULL ) {
  205.     /* blast \r as well? */
  206.     if( (cp = index( buf, '\n' )) != NULL )    /* strip newlines */
  207.         *cp = EOS;
  208.     outline( buf );                /* output as much as will fit */
  209.     } /* while */
  210.     fclose( f );
  211.     return( TRUE );
  212. } /* doremote */
  213.  
  214. LOCAL void
  215. prhost( name )
  216. char *name;
  217. {
  218.     char buf[255];
  219.  
  220.     blankline();
  221.     sprintf(buf, "[%s]", name);     /* format string */
  222.     outline( HZUP(buf) );        /* output it (upper cased) */
  223.     fflush( stdout );
  224. } /* prhost */
  225.  
  226. /*
  227.  * Local variables:
  228.  * comment-column: 40
  229.  * End:
  230.  */
  231.