From: sysop                           
Subject: CLOCK_SERVER Part 2/2
News-Software: VAX/VMS VNEWS 1.4-b1  
Organization: Department of Nuclear Engineering Sciences
Date:  9 Sep 1992 12:08 EST  


Here is part 2 of CLOCK_SERVER.

-------------------------------------------------------------------------------
Shawn A. Clifford, System Manager | Internet: sysop@robot.nuceng.ufl.edu
Nuclear Engineering Sciences      |		sac@eng.ufl.edu
University of Florida             | Home Phone: 904/335-4914
Gainesville, Florida  32611       | Work Phone: 904/392-1450  FAX: 904/392-3380
-------------------------------------------------------------------------------

-+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+
X        static  char            hostname`5B256`5D;  /* Name of local host.
V        */
X`09int`09flag;
X`09int`09retval;`09`09`09`09/* helpful for debugging */
X`09int`09shut = FALSE;`09`09`09/* flag to cleanup */
X
X
X`09/*
X`09 * Check input parameters.
X`09 */
X`09if (argc != 3 )
X`09`09`7B
X`09`09printf("Usage: client hostname portnumber.\n");
X`09`09exit();
X`09`09`7D
X
X
X`09/*
X`09 * Open socket 1: AF_INET, SOCK_STREAM.`20
X`09 */
X        if ((sock_1 = socket (AF_INET, SOCK_STREAM, 0)) == -1)`20
X`09`09`7B
X                perror( "socket");
X`09`09exit();
X`09`09`7D
X
X
X`09/*
X`09 *Get pointer to network data structure for socket 2 (remote host).`20
X`09 */
X        if ((hostentptr = gethostbyname (argv`5B1`5D)) == NULL)`20
X`09`09`7B
X                perror( "gethostbyname");
X`09`09cleanup(shut, sock_1);
X`09`09`7D
X`09`09
X
X
X`09/*
X`09 * Copy hostent data to safe storage.`20
X`09 */
X        hostentstruct = *hostentptr;
X
X
X`09/*
X`09 * Fill in the name & address structure for socket 2.`20
X`09 */
X        sock2_name.sin_family = hostentstruct.h_addrtype;
X`09sock2_name.sin_port = htons(atoi(argv`5B2`5D));
X        sock2_name.sin_addr = * ((struct in_addr *) hostentstruct.h_addr);
X
X
X`09/*
X`09 * Connect socket 1 to sock2_name.
X`09 */
X`09retval = connect(sock_1, &sock2_name, sizeof (sock2_name));
X`09if (retval)
X`09`09`7B
X`09`09perror("connect");
X`09`09cleanup(shut, sock_1);
X`09`09`7D
X
X
X`09/*
X`09 * Send message to socket 2.
X`09 */
X`09flag = 0;`09/* maybe 0 or MSG_OOB */
X`09retval = send(sock_1, message ,sizeof (message), flag);
X`09if (retval < 0)
X`09`09`7B
X`09`09perror ("send");
X`09`09shut = TRUE;`09
X`09`09`7D
X
X
X`09/*
X`09 * Call cleanup to shutdown and close socket.
X`09 */
X`09cleanup(shut, sock_1);
X
X `7D /* end main */
X
X/*-----------------------------------------------------------*/
X
Xcleanup(shut, socket)
Xint`09shut;
Xint`09socket;
X`09
X`7B
X`09int`09retval;
X
X`09/*
X`09 * Shutdown socket completely -- only if it was connected`20
X`09 */
X`09if (shut) `7B
X`09`09retval = shutdown(socket,2);
X`09`09if (retval == -1)
X`09`09`09perror ("shutdown");
X`09`7D
X
X
X`09/*
X`09 * Close socket.
X`09 */
X        retval = close (socket);
X`09if (retval)
X`09`09perror ("close");
X
X`09exit();
X
X `7D /* end main */
X
$ CALL UNPACK VCLIENT.C;1 778835980
$ create 'f'
X/*
X*  NOTICE:
X*`09To link in VAXC/VMS you must have the following
X*`09entries in your .opt file:
X*`09   sys$library:ucx$ipc.olb/lib
X*`09   sys$share:vaxcrtl.exe/share
X*
X*`09To run this server effectively, use something like:
X*
X*`09$ run sys$common:`5Butil`5Dclock_server -
X*`09   /noaccounting -
X*`09   /noauthorize -
X*`09   /detached -
X*`09   /error=nl: -
X*`09   /input=nl: -
X*`09   /output=nl: -
X*`09   /priority=6 -
X*`09   /privileges=(noall,detach,netmbx,tmpmbx) -
X*`09   /process_name="Clock Server" -
X*`09   /uic=`5B1,4`5D
X*
X*  AUTHORS:
X*`09Shawn Clifford
X*`09UCX Developer`09
X*
X*  CREATION DATE: May 23, 1989`20
X*
X*  MODIFICATION HISTORY:
X*
X*`0913-MAY-1992 (SC) Modified DEC's example code to provide the service
X*`09`09for the DEC X-clock.  Added the $CREPRC, etc.
X*`0915-MAY-1992 (SC) Added lookup of client's address/name for entry into
X*`09`09NODE.NAME file for verification by CLOCK.COM.
X*/
X
X
X/*
X*
X*  INCLUDE FILES
X*
X*/
X#include  <errno.h>
X#include  <types.h>
X#include  <stdio.h>
X#include  <socket.h>
X#include  <in.h>
X#include  <netdb.h>`09`09/* change hostent to comply with BSD 4.3 */
X#include  <inet.h>
X#include  <ucx$inetdef.h>`09/* INET symbol definitions */
X#include  <descrip.h>
X#include  <lib$routines.h>
X
X/*
X* Functional Description
X*
X*`09This examples creates a socket of type SOCK_STREAM (TCP),
X*`09binds and listens on the socket, receives a message`20
X*`09and closes the connection.`09
X*`09Error messages are printed to the screen.
X*
X*`09IPC calls used:`20
X*`09accept
X*`09bind
X*`09close
X*`09gethostbyname
X*`09listen
X*`09recv`09
X*`09shutdown
X*`09socket`09
X*
X*
X* Formal Parameters
X*`09The server program expects one parameter:
X*`09portnumber ... port number where it will listen
X*
X*
X* Routine Value
X*
X*`09Status`09
X*/
X
X
Xstruct dsc$descriptor image = `7B23,
X`09`09`09DSC$K_DTYPE_T,
X`09`09`09DSC$K_CLASS_S,
X`09`09`09"SYS$SYSTEM:LOGINOUT.EXE"`7D;
X
Xstruct dsc$descriptor input = `7B39,
X`09`09`09DSC$K_DTYPE_T,
X`09`09`09DSC$K_CLASS_S,
X`09`09`09"SYS$COMMON:`5BUTIL.CLOCK_SERVER`5DCLOCK.COM"`7D;
X
Xstruct dsc$descriptor output = `7B3,
X`09`09`09DSC$K_DTYPE_T,
X`09`09`09DSC$K_CLASS_S,
X`09`09`09"NL:"`7D;
X
Xstruct dsc$descriptor error = `7B3,
X`09`09`09DSC$K_DTYPE_T,
X`09`09`09DSC$K_CLASS_S,
X`09`09`09"NL:"`7D;
X
Xstruct dsc$descriptor pname = `7B10,
X`09`09`09DSC$K_DTYPE_T,
X`09`09`09DSC$K_CLASS_S,
X`09`09`09"ClockSTART"`7D;
X
X#define param_file "SYS$COMMON:`5BUTIL.CLOCK_SERVER`5DNODE.NAME"
X
X/*--------------------------------------------------------------------*/
X
Xmain(argc,argv)
Xint`09argc;
Xchar`09**argv;
X`7B
X
X        int     sock_2, sock_3;                 /* sockets */
X        static  char  `09`09message`5BBUFSIZ`5D;`20
Xstatic `09struct  sockaddr_in sock2_name;         /* Address struct for sock
Vet2.*/
Xstatic `09struct  sockaddr_in retsock2_name;      /* Address struct for sock
Vet2.*/
X        struct  hostent         hostentstruct;  /* Storage for hostent data.
V  */
X        struct  hostent         *hostentptr;    /* Pointer to hostent data.
V   */
X        static  char            hostname`5B256`5D;  /* Name of local host.
V        */
X`09int`09flag;
X`09int`09retval;`09`09`09`09/* Return codes               */
X`09int`09namelength;`09`09`09
Xunsigned long`09pid;`09`09`09`09/* Process id                 */
X`09FILE`09*fp;`09`09`09`09/* Mr. File Pointer`09      */
X
X`09/*
X`09 * Open socket 2: AF_INET, SOCK_STREAM.`20
X`09 */
X        if ((sock_2 = socket (AF_INET, SOCK_STREAM, 0)) == -1)`20
X`09`09`7B
X                perror( "socket");
X`09`09exit();
X`09`09`7D
X
X`09/*
X`09 * Get the host local name.`20
X`09 */
X        retval = gethostname(hostname,sizeof hostname);
X`09if (retval)
X`09`09`7B
X`09`09perror ("gethostname");
X`09`09cleanup (1, sock_2, 0);
X`09`09`7D
X
X`09/*
X`09 * Get pointer to network data structure for socket 2.`20
X`09 */
X        if ((hostentptr = gethostbyname (hostname)) == NULL)`20
X`09`09`7B
X                perror( "gethostbyname");
X`09`09cleanup(1, sock_2, 0);
X`09`09`7D
X
X`09/*
X`09 * Copy hostent data to safe storage.`20
X`09 */
X        hostentstruct = *hostentptr;
X
X`09/*
X`09 * Fill in the name & address structure for socket 2.`20
X`09 */
X        sock2_name.sin_family = hostentstruct.h_addrtype;
X`09sock2_name.sin_port = htons(92);`09/* Port to listen on */
X        sock2_name.sin_addr = * ((struct in_addr *) hostentstruct.h_addr);
X
X`09/*
X`09 * Bind name to socket 2.
X `09 */
X`09retval = bind (sock_2, &sock2_name, sizeof sock2_name);
X        if (retval)
X`09`09`7B
X`09`09perror("bind");
X`09`09cleanup(1, sock_2, 0);
X`09`09`7D
X
X
X
X   /* Here is the listener loop ... */
X   while (1) `7B
X
X`09/*
X`09 * Listen on socket 2 for connections.`20
X`09 */
X        retval = listen (sock_2, 5);
X        if (retval)
X`09`09`7B
X`09`09perror("listen");
X`09`09cleanup(1, sock_2, 0);
X`09`09`7D
X
X`09/*
X`09 * Accept connection from socket 2: `09   `20
X`09 * accepted connection will be on socket 3.`20
X`09 */
X`09namelength = sizeof (sock2_name);
X        sock_3 = accept (sock_2, &sock2_name, &namelength);
X`09if (sock_3 == -1)
X`09`09`7B
X`09`09perror ("accept");
X`09`09cleanup( 2, sock_2, sock_3);
X`09`09`7D
X
X`09/*
X`09 * Receive message from socket 1.`20
X`09 */
X`09flag = 0;`09/* maybe 0 or MSG_OOB or MSG_PEEK */
X
X`09retval = recv(sock_3, message ,sizeof (message), flag);
X`09if (retval == -1)
X`09`09`7B
X`09`09perror ("receive");
X`09`09cleanup( 2, sock_2, sock_3);
X`09`09`7D
X`09else`09`09/* We got a connection !!! */
X`09`09`7B
X
X`09`09/* Get the client info from sock2_name */
X`09`09hostentptr = gethostbyaddr (&sock2_name.sin_addr,
X`09`09`09`09`09sizeof (struct in_addr),
X`09`09`09`09`09sock2_name.sin_family);
X
X`09`09/* Write the client's FQDN to the param_file for
X`09`09   the comfile to read */
X`09`09fp = fopen(param_file, "w");
X`09`09fprintf (fp, "%s\n", hostentptr->h_name);
X`09`09fclose (fp);
X
X`09`09/* Create the process that will run the input comfile */
X`09`09retval = sys$creprc (&pid, &image, &input, &output, &error,
X`09`09`09`090,0, &pname, 6,0,0,0);
X
X`09`09/* Check if CREATE went Ok
X`09`09if ((retval & 1) == 0) `7B
X`09`09`09printf("Failed to CREATE\n");
X`09`09`09lib$signal (retval);
X`09`09`09`7D
X`09`09else
X`09`09`09`7B
X`09`09`09printf ("ClockSTART process %x created.\n", pid);
X`09`09`09`7D
X`09`09*/
X
X`09`09`7D;
X
X   `7D;`09`09`09/* END of WHILE */
X
X
X`09/*
X`09 * Call cleanup to shutdown and close sockets.
X`09 */
X`09cleanup(2, sock_2, sock_3);
X
X
X`7D /* end main */
X
X
X/*-----------------------------------------------------------*/
X
Xcleanup(how_many, sock1, sock2)
Xint`09how_many;
Xint`09sock1, sock2;
X`09
X`7B
X`09int`09retval;
X
X`09/*
X`09 * Shutdown and close sock1 completely.
X`09 */
X`09retval = shutdown(sock1,2);
X`09if (retval == -1)
X`09`09perror ("shutdown");
X
X        retval = close (sock1);
X`09if (retval)
X`09`09perror ("close");
X
X
X`09/*
X`09 * If given, shutdown and close sock2.`20
X`09 */
X`09if (how_many == 2)
X`09`7B
X`09`09retval = shutdown(sock2,2);
X`09`09if (retval == -1)
X`09`09`09perror ("shutdown");
X
X        `09retval = close (sock2);
X`09`09if (retval)
X`09`09`09perror ("close");
X`09`7D
X
X`09exit();
X
X`7D /* end cleanup*/
$ CALL UNPACK VSERVER.C;1 946836702
$ v=f$verify(v)
$ EXIT