home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / socket / socket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-07  |  6.0 KB  |  271 lines

  1. /*
  2.  
  3. $Header: socket.c[1.17] Wed Sep  9 16:23:14 1992 nickel@cs.tu-berlin.de proposed $
  4. This file is part of socket(1).
  5. Copyright (C) 1992 by Juergen Nickelsen <nickel@cs.tu-berlin.de>
  6. Please read the file COPYRIGHT for further details.
  7.  
  8. */
  9.  
  10. #include <sys/types.h>
  11. #include <sys/socket.h>
  12. #include <netinet/in.h>
  13. #include <netdb.h>
  14. #include <errno.h>
  15. #include <stdio.h>
  16. #ifdef SEQUENT
  17. #include <strings.h>
  18. #else
  19. #include <string.h>
  20. #endif
  21. #include "globals.h"
  22.  
  23. /* global variables */
  24. int forkflag = 0 ;        /* server forks on connection */
  25. int serverflag = 0 ;        /* create server socket */
  26. int loopflag = 0 ;        /* loop server */
  27. int verboseflag = 0 ;        /* give messages */
  28. int readonlyflag = 0 ;        /* only read from socket */
  29. int writeonlyflag = 0 ;        /* only write to socket */
  30. int quitflag = 0 ;        /* quit connection on EOF */
  31. int crlfflag = 0 ;        /* socket expects and delivers CRLF */
  32. int backgflag = 0 ;        /* put yourself in background */
  33. int active_socket ;        /* socket with connection */
  34. char *progname ;        /* name of the game */
  35. char *pipe_program = NULL ;    /* program to execute in two-way pipe */
  36.  
  37. void server A((int port, char *service_name)) ;
  38. void handle_server_connection A((void)) ;
  39. void client A((char *host, int port, char *service_name)) ;
  40.  
  41. int main(argc, argv)
  42. int argc ;
  43. char **argv ;
  44. {
  45.     char *cp ;            /* to point to '/' in argv[0] */
  46.     int opt ;            /* option character */
  47.     int error = 0 ;        /* usage error occurred */
  48.     extern int optind ;        /* from getopt() */
  49.     char *host ;        /* name of remote host */
  50.     int port ;            /* port number for socket */
  51.     char *service_name ;    /* name of service for port */
  52.  
  53.     /* print version ID if requested */
  54.     if (argv[1] && !strcmp(argv[1], "-version")) {
  55.     puts(so_release()) ;
  56.     exit(0) ;
  57.     }
  58.  
  59.     /* set up progname for later use */
  60.     progname = argv[0] ;
  61.     if (cp = strrchr(progname, '/')) progname = cp + 1 ;
  62.  
  63.     /* parse options */
  64.     while ((opt = getopt(argc, argv, "bcflp:qrsvw?")) != -1) {
  65.     switch (opt) {
  66.       case 'f':
  67.         forkflag = 1 ;
  68.         break ;
  69.       case 'c':
  70.         crlfflag = 1 ;
  71.         break ;
  72.       case 'w':
  73.         writeonlyflag = 1 ;
  74.         break ;
  75.       case 'p':
  76.         pipe_program = argv[optind - 1] ;
  77.         break ;
  78.       case 'q':
  79.         quitflag = 1 ;
  80.         break ;
  81.       case 'r':
  82.         readonlyflag = 1 ;
  83.         break ;
  84.       case 's':
  85.         serverflag = 1 ;
  86.         break ;
  87.       case 'v':
  88.         verboseflag = 1 ;
  89.         break ;
  90.       case 'l':
  91.         loopflag = 1 ;
  92.         break ;
  93.       case 'b':
  94.         backgflag = 1 ;
  95.         break ;
  96.       default:
  97.         error++ ;
  98.     }
  99.     }
  100.     if (error ||        /* usage error? */
  101.     argc - optind + serverflag != 2) { /* number of args ok? */
  102.     usage() ;
  103.     exit(15) ;
  104.     }
  105.  
  106.     /* check some option combinations */
  107. #define senseless(s1, s2) \
  108.     fprintf(stderr, "It does not make sense to set %s and %s.\n", (s1), (s2))
  109.  
  110.     if (writeonlyflag && readonlyflag) {
  111.     senseless("-r", "-w") ;
  112.     exit(15) ;
  113.     }
  114.     if (loopflag && !serverflag) {
  115.     senseless("-l", "not -s") ;
  116.     exit(15) ;
  117.     }
  118.     if (backgflag && !serverflag) {
  119.      senseless("-b", "not -s") ;
  120.      exit(15) ;
  121.     }
  122.     if (forkflag && !serverflag) {
  123.     senseless("-f", "not -s") ;
  124.     }
  125.  
  126.     /* set up signal handling */
  127.     init_signals() ;
  128.  
  129.     /* get port number */
  130.     port = resolve_service(argv[optind + 1 - serverflag],
  131.                "tcp", &service_name) ;
  132.     if (port < 0) {
  133.     fprintf(stderr, "%s: unknown service\n", progname) ;
  134.     exit(5) ;
  135.     }
  136.  
  137.     /* and go */
  138.     if (serverflag) {
  139.     if (backgflag) {
  140.         background() ;
  141.     }
  142.     server(port, service_name) ;
  143.     } else {
  144.     client(argv[optind], port, service_name) ;
  145.     }           
  146.     exit(0) ;
  147. }
  148.  
  149.  
  150. void server(port, service_name)
  151. int port ;
  152. char *service_name ;
  153. {
  154.     int socket_handle, alen ;
  155.  
  156.     /* allocate server socket */
  157.     socket_handle = create_server_socket(port, 1) ;
  158.     if (socket_handle < 0) {
  159.     perror2("server socket") ;
  160.     exit(1) ;
  161.     }
  162.     if (verboseflag) {
  163.     fprintf(stderr, "listening on port %d", port) ;
  164.     if (service_name) {
  165.         fprintf(stderr, " (%s)", service_name) ;
  166.     }
  167.     fprintf(stderr, "\n") ;
  168.     }
  169.  
  170.     /* server loop */
  171.     do {
  172.     struct sockaddr_in sa ;
  173.         
  174.     alen = sizeof(sa) ;
  175.  
  176.     /* accept a connection */
  177.     if ((active_socket = accept(socket_handle,
  178.               (struct sockaddr *) &sa,
  179.               &alen)) == -1) {
  180.         perror2("accept") ;
  181.     } else {
  182.         /* if verbose, get name of peer and give message */
  183.         if (verboseflag) {
  184.         struct hostent *he ;
  185.         long norder ;
  186.         char dotted[20] ;
  187.  
  188.         he = gethostbyaddr(&sa.sin_addr.s_addr,
  189.                    sizeof(sa.sin_addr.s_addr), AF_INET) ;
  190.         if (!he) {
  191.             norder = htonl(sa.sin_addr.s_addr) ;
  192.             sprintf(dotted, "%d.%d.%d.%d",
  193.                 (norder >> 24) & 0xff,
  194.                 (norder >> 16) & 0xff,
  195.                 (norder >>  8) & 0xff,
  196.                 norder & 0xff) ;
  197.         }
  198.         fprintf(stderr, "connection from %s\n",
  199.             (he ? he->h_name : dotted)) ;
  200.         }
  201.         if (forkflag) {
  202.         switch (fork()) {
  203.           case 0:
  204.             handle_server_connection() ;
  205.             exit(0) ;
  206.           case -1:
  207.             perror2("fork") ;
  208.             break ;
  209.           default:
  210.             close(active_socket) ;
  211.             wait_for_children() ;
  212.         }
  213.         } else {
  214.         handle_server_connection() ;
  215.         }
  216.     }
  217.     } while (loopflag) ;
  218. }
  219.  
  220.  
  221. void handle_server_connection()
  222. {
  223.     /* open pipes to program, if requested */
  224.     if (pipe_program != NULL) {
  225.     open_pipes(pipe_program) ;
  226.     }
  227.     /* enter IO loop */
  228.     do_io() ;
  229.     /* connection is closed now */
  230.     close(active_socket) ;
  231.     if (pipe_program) {
  232.     /* remove zombies */
  233.     wait_for_children() ;
  234.     }
  235. }
  236.  
  237.  
  238. void client(host, port, service_name)
  239. char *host ;
  240. int port ;
  241. char *service_name ;
  242. {
  243.     /* get connection */
  244.     active_socket = create_client_socket(&host, port) ;
  245.     if (active_socket == -1) {
  246.     perror2("client socket") ;
  247.     exit(errno) ;
  248.     } else if (active_socket == -2) {
  249.     fprintf(stderr, "%s: unknown host %s\n", progname, host) ;
  250.     exit(13) ;
  251.     }
  252.     if (verboseflag) {
  253.     fprintf(stderr, "connected to %s port %d", host, port) ;
  254.     if (service_name) {
  255.         fprintf(stderr, " (%s)", service_name) ;
  256.     }
  257.     fprintf(stderr, "\n") ;
  258.     }
  259.  
  260.     /* open pipes to program if requested */
  261.     if (pipe_program != NULL) {
  262.     open_pipes(pipe_program) ;
  263.     }
  264.     /* enter IO loop */
  265.     do_io() ;
  266.     /* connection is closed now */
  267.     close(active_socket) ;
  268. }
  269.  
  270. /*EOF*/
  271.