home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume36 / slurp / part02 / sockets.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-12  |  5.8 KB  |  259 lines

  1. /*
  2.  * sockets - open a socket connection and read/write to nntp server
  3.  *
  4.  * Copyright (C) 1992/93 Stephen Hebditch. All rights reserved.
  5.  * TQM Communications, BCM Box 225, London, WC1N 3XX.
  6.  * steveh@orbital.demon.co.uk  +44 836 825962
  7.  *
  8.  * See README for more information and disclaimers
  9.  *
  10.  * Obtain the current time from the remote server in standard unix time
  11.  * format for use with the next NEWNEWS. If the client is unable to
  12.  * connect to the time server, then local time is used instead.
  13.  *
  14.  * $Id: sockets.c,v 1.5 1993/03/01 18:00:18 root Exp $
  15.  *
  16.  * $Log: sockets.c,v $
  17.  * Revision 1.5  1993/03/01  18:00:18  root
  18.  * Use ferror to detect erros, not return code.
  19.  *
  20.  * Revision 1.4  1993/02/14  16:22:42  root
  21.  * No longer have get_server return a return code. Makes this module
  22.  * no longer compatible with nntp 1.6 client library, but there ya go...
  23.  * Changed error detection in put_server for no other reason than to
  24.  * be consistent with elsewhere.
  25.  *
  26.  * Revision 1.3  1992/12/15
  27.  * Removed unnecessary close() in close_server.
  28.  * Syslog log level for connected message changed to LOG_INFO.
  29.  *
  30.  * Revision 1.1  1992/12/04
  31.  * Print line before it is sent to server when debugging is on.
  32.  *
  33.  * Revision 1.0  1992/11/29
  34.  * Adapted from nntpxfer-e code.
  35.  * Incorporate code to set up a tcp connection, plus cleaned up the
  36.  * existing code.
  37.  *
  38.  */
  39.  
  40. #include "slurp.h"
  41.  
  42. #include <signal.h>
  43. #include <setjmp.h>
  44. #include <unistd.h>
  45. #include <netdb.h>
  46. #include <sys/socket.h>
  47. #include <netinet/in.h>
  48. #include <arpa/inet.h>
  49.  
  50. #ifndef INADDR_NONE
  51.   #define INADDR_NONE 0xffffffff
  52. #endif
  53.  
  54. struct sockaddr_in serv_addr;
  55. struct servent serv_info;
  56. struct hostent host_info;
  57.  
  58. static int server;
  59. static FILE *server_rd_fp;
  60. static FILE *server_wr_fp;
  61.  
  62.  
  63. /*
  64.  * tcp_open - Open a tcp connection to 'host' for service 'service',
  65.  * returning a file descriptor for the socket.
  66.  */
  67.  
  68.     int
  69. tcp_open (char *host, char *service)
  70.     {
  71.     int sockfd, on;
  72.     unsigned long inaddr;
  73.     struct servent *sp;
  74.     struct hostent *hp;
  75.  
  76.     bzero ((char *) &serv_addr, sizeof (serv_addr));
  77.     serv_addr.sin_family = AF_INET;
  78.  
  79.     /* Get service information */
  80.     if ((sp = getservbyname (service, "tcp")) == NULL)
  81.         {
  82.         log_ret ("tcp_open: Unknown service %s/tcp", service);
  83.         return (-1);
  84.         }
  85.     serv_info = *sp;
  86.     serv_addr.sin_port = sp->s_port;
  87.  
  88.     /* Try to convert host name as dotted decimal */
  89.     if ((inaddr = inet_addr (host)) != INADDR_NONE)
  90.         {
  91.         bcopy ((char *) &inaddr, (char *) &serv_addr.sin_addr,
  92.                sizeof (inaddr));
  93.         host_info.h_name = NULL;
  94.         }
  95.     /* If that failed, then look up the host name */
  96.     else
  97.         {
  98.         if ((hp = gethostbyname (host)) == NULL)
  99.             {
  100.             log_ret ("tcp_open: Host name error: %s", host);
  101.             return (-1);
  102.             }
  103.         host_info = *hp;
  104.         bcopy (hp->h_addr, (char *) &serv_addr.sin_addr, hp->h_length);
  105.         }
  106.  
  107.     if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  108.         {
  109.         log_ret ("tcp_open: Can't create TCP socket");
  110.         return (-1);
  111.         }
  112.  
  113.     if (connect (sockfd, (struct sockaddr *) &serv_addr,
  114.         sizeof (serv_addr)) < 0)
  115.         {
  116.         log_ret ("tcp_open: Can't connect to server %s", host);
  117.         (void) close (sockfd);
  118.         return (-1);
  119.         }
  120.  
  121.     on = 1;
  122.     if (setsockopt (sockfd, SOL_SOCKET, SO_KEEPALIVE, 
  123.                     (char *) &on, sizeof (on)) < 0)
  124.         log_ret ("tcp_open: Can't set KEEPALIVE on socket");
  125.  
  126.     return (sockfd);
  127.     }
  128.  
  129. /*
  130.  * server_init - Open a connection to the NNTP server. Returns -1 if an
  131.  * error occurs, otherwise the server's initial response code.
  132.  */
  133.  
  134.     int
  135. server_init (char *hostname)
  136.     {
  137.     char line [NNTP_STRLEN];
  138.  
  139.     /* First try and make the connection */
  140.     if ((server = tcp_open (hostname,"nntp")) < 0)
  141.         return (-1);
  142.  
  143.     /* Now fdopen to enable buffering of incoming data */
  144.     if ((server_rd_fp = fdopen (server, "r")) == NULL)
  145.         {
  146.         log_ret ("server_init: Can't fdopen socket for reading");
  147.         return (-1);
  148.         }
  149.     if ((server_wr_fp = fdopen (server, "w")) == NULL)
  150.         {
  151.         log_ret ("server_init: Can't fdopen socket for writing");
  152.         return (-1);
  153.         }
  154.  
  155.     /* Inform everyone that we're there */
  156. #ifdef SYSLOG
  157.     if (!debug_flag)
  158.         syslog(LOG_INFO, "Connected to nntp server at %s", hostname);
  159.     else
  160. #endif
  161.         (void) fprintf (stderr, "Connected to nntp server at %s\n", hostname);
  162.  
  163.     /* Get the greeting herald */
  164.     get_server (line, sizeof (line));
  165.     if (debug_flag)
  166.         (void) fprintf (stderr, "-> %s\n", line);
  167.  
  168.     /* Return the banner code */
  169.     return (atoi (line));
  170.     }
  171.  
  172.  
  173. /*
  174.  * close_server - Close down the NNTP server connection
  175.  */
  176.  
  177.     void
  178. close_server ()
  179.     {
  180.     char line [NNTP_STRLEN];
  181.  
  182.     if (debug_flag)
  183.         (void) fprintf (stderr, "<- QUIT\n");
  184.     put_server ("QUIT");
  185.     get_server (line, sizeof (line));
  186.     if (debug_flag)
  187.         (void) fprintf (stderr, "-> %s\n", line);
  188.  
  189.     (void) fclose (server_rd_fp);
  190.     (void) fclose (server_wr_fp);
  191.     }
  192.  
  193.  
  194. static jmp_buf env_alrm;
  195.  
  196.     static void
  197. sig_alrm (int signo)
  198.     {
  199.     longjmp (env_alrm, 1);
  200.     }
  201.  
  202. /*
  203.  * get_server - Read a line up to CRLF from the socket into a buffer.
  204.  */
  205.  
  206.     void
  207. get_server (char *line, int size)
  208.     {
  209.     int esave;
  210.     char *pos;
  211.  
  212.     /* Set up an alarm to handle socket timeout */
  213.     if (setjmp (env_alrm))
  214.         {
  215.         (void) alarm (0);                    /* Reset alarm clock */
  216.         (void) signal (SIGALRM, SIG_DFL);
  217.         errno = EPIPE;
  218.         log_sys ("get_server: Read error on server socket");
  219.         }
  220.  
  221.     (void) signal (SIGALRM, sig_alrm);
  222.     (void) alarm (TIMEOUT);
  223.  
  224.     /* Read line */
  225.     (void) fgets (line, size, server_rd_fp);
  226.  
  227.     /* Reset the alarm */
  228.     esave = errno;
  229.     (void) alarm (0);
  230.     (void) signal (SIGALRM, SIG_DFL);
  231.     errno = esave;
  232.  
  233.     /* Report any error */
  234.     if (ferror (server_rd_fp))
  235.         log_sys ("get_server: Read error on server socket");
  236.  
  237.     /* Kill the CRLF */
  238.     if (pos = strchr (line, '\r'))
  239.         *pos = '\0';
  240.     if (pos = strchr (line, '\n'))
  241.         *pos = '\0';
  242.     }
  243.  
  244. /*
  245.  * put_server - write a line from a linefer to a socket
  246.  */
  247.  
  248.     void
  249. put_server (char *line)
  250.     {
  251.  
  252.     (void) fprintf (server_wr_fp, "%s\r\n", line);
  253.     if (ferror (server_wr_fp))
  254.         log_sys ("put_server: Write error on server socket");
  255.     (void) fflush (server_wr_fp);
  256.     }
  257.  
  258. /* END-OF-FILE */
  259.