From: sysop                           
Subject: DECW$CLOCK Client/Server using UCX
News-Software: VAX/VMS VNEWS 1.4-b1  
Organization: Department of Nuclear Engineering Sciences
Date:  9 Sep 1992 12:03 EST  

Group,
	Here is a client/server application that is based largely on the
UCX ICP example code.  This server will kick off DECW$CLOCK on the display
of the client (if the client is in an authorization file).  Should be easy
to modify the server to provide greater functionality.  Hope that this is 
readable enough to be of service to the people who were looking for example
code.

Posted in 2 parts.

-------------------------------------------------------------------------------
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
-------------------------------------------------------------------------------

$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-010  25-Jun-1992
$!   On  9-SEP-1992 10:09:47.37   By user SYSOP 
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$!+ THIS PACKAGE DISTRIBUTED IN 2 PARTS, TO KEEP EACH PART
$!  BELOW 30 BLOCKS
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. AAAREADME.TXT;1
$!       2. AUTHORIZED_CLOCK.CLIENTS;1
$!       3. CLOCK.COM;1
$!       4. CLOCK_SERVER.COM;1
$!       5. CLIENT_SERVER.OPT;1
$!       6. MAKE_CLIENT.COM;1
$!       7. MAKE_SERVER.COM;1
$!       8. VCLIENT.C;1
$!       9. VSERVER.C;1
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ x = P1 - f$parse(P1,,,"version")
$ y = f$search(x)
$ if y .eqs. "" then $ goto file_absent
$ x = f$integer(f$parse(P1,,,"version")-";")
$ y = f$integer(f$parse(y,,,"version")-";")
$ if x .gt. y then $ goto file_absent
$ if f$mode() .eqs. "INTERACTIVE" then $ goto file_interactive
$ if x .eq. y then e "-W-EXISTS, File ''P1' exists. Skipped."
$ if x .ne. y then e "-W-NEWERVERSION, of File ''P1' exists. Skipped."
$file_delete:
$ delete 'f'*
$ exit
$file_interactive:
$ if x .eq. y then e "-W-EXISTS, File ''P1' exists."
$ if x .ne. y then e "-W-NEWERVERSION, of File ''P1' exists."
$ read/error=file_delete/end=file_delete-
  /prompt="Create new version [y/n]: " -
  sys$command x
$ if .not. x then $ e "-W-SKIPPED, File ''P1' skipped."
$ if .not. x then $ goto file_delete
$ P1 = P1 - f$parse(P1,,,"version")
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
"output_file"));ENDPROCEDURE;Unpacker;QUIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create 'f'
XThis file contains a description of all the files packaged with CLOCK_SERVER
V,
Xand which files need to be modified for your site.
XThe server/client code is based on the UCX IPC server/client code in
XSYS$EXAMPLES UCX.DIR that came with UCX V1.3.
X
X
X- VSERVER.C (.EXE) is the VAX clock server.  There are some VMS specific
X`09calls in VSERVER, such as $CREPRC.  VSERVER listens on port 92 for
X`09an inbound connection.  As soon as it gets a connection, it creates
X`09a file named NODE.NAME which contains the Fully Qualified Domain Name
X`09(FQDN) of the client.  VSERVER then creates a process which runs
X`09CLOCK.COM (see below), and then goes back to listening.  You may notice
X`09that the server never gets to the cleanup routines.
X
X- VCLIENT.C (.EXE) is the client that initiates a connection to the server.
X`09It compiled directly for me (w/o mods) on a Sun SPARC 2.  All that you
X`09need to do with VCLIENT is specify a host and the port to connect to.
X
X`09Eg. (VMS):   $ MCR `5B`5DVCLIENT fully.qualified.domain.name 92
X`09Eg. (Unix):  % vclient fully.qualified.domain.name 92
X
X- CLOCK.COM is the DCL file that creates a display for the client and runs
X`09DECW$CLOCK on that display.  It may be run either interactively, or
X`09if the file NODE.NAME exists, it will run batch.  CLOCK.COM needs the
X`09FQDN of the client to execute, and the client's FQDN must be entered
X`09in the file AUTHORIZED_CLOCK.CLIENTS.
X
X- NODE.NAME is a temporary file that is created by VSERVER for passing the
X`09FQDN to CLOCK.COM.  This file is deleted after being read.
X
X- AUTHORIZED_CLOCK.CLIENTS is a text file containing the FQDNs for all
X`09authorized clients of VSERVER.
X
X- CLOCK_SERVER.COM is a DCL file that will start the VSERVER running on your
X`09VMS machine.
X
X- MAKE_SERVER.COM is a DCL file that will create VSERVER.EXE for you.
X
X- MAKE_CLIENT.COM is a DCL file that will create VCLIENT.EXE for you.
X
X- CLIENT_SERVER.OPT is the linker option file that will link the source code
X`09with the UCX IPC object library and the shareable VAXC image library.
X
XYou will need to modify the following to run at your site:
X---------------------------------------------------------
X
XVSERVER.C - Change the descriptors for CLOCK.COM and NODE.NAME.  Don't forge
Vt
X`09to change the length of the descriptor appropriately.
X
XCLOCK.COM - Change the 'fname' entry to point to NODE.NAME at your site.
X
XCLOCK_SERVER.COM - Change the directory to run VSERVER from.
$ CALL UNPACK AAAREADME.TXT;1 1129797020
$ create 'f'
Xrobot4d.nuceng.ufl.edu
Xrobot.nuceng.ufl.edu
Xsun-robot.nuceng.ufl.edu
Xfrenulum.eng.ufl.edu
Xwasp.eng.ufl.edu
Xcimar.me.ufl.edu
Xbigguy.eng.ufl.edu
Xatlantis.cis.ufl.edu
Xcrane.cis.ufl.edu
Xradio.astro.ufl.edu
$ CALL UNPACK AUTHORIZED_CLOCK.CLIENTS;1 39390312
$ create 'f'
X$! -------------------------------------------------------------------------
X$! Title:`09CLOCK.COM
X$! Author:`09Shawn A. Clifford
X$! Date:`0911-May-1992
X$! Purpose:`09Starts up DEC's X-Clock and displays it on the Sun SPARC 2.
X$!
X$! Modification History:
X$!
X$! Who`09When`09What
X$! -------------------------------------------------------------------------
X$! (SC)`095/15/92`09Modified code to display clock on any INTERNET node.  Th
Ve
X$!`09`09program will get the Fully Qualified Domain Name (FQDN) from
X$!  either an interactive user, or from an input file (NODE.NAME) if this
X$!  routine is being called by the Clock Server, for the node on which to
X$!  display the clock.  The FQDN will be compared against a list of authoriz
Ved
X$!  clients, stored in (AUTHORIZED_CLOCK.CLIENTS), and if the client is
X$!  authorized, then the clock will be started on that node.
X$!
X$! -------------------------------------------------------------------------
X$!
X$! 'f$verify(0)`09`09`09! Quietly turn off verify
X$!
X$ set noon
X$ set symbol/scope=(nolocal,noglobal)
X$ w:=write sys$output
X$!
X$!`09Get the FQDN from the user if interactive
X$!
X$ w ""
X$ fname := sys$common:`5Butil.clock_server`5Dnode.name
X$ if (f$search("''fname'") .nes. "") then goto from_file
X$ if (p1 .nes. "")
X$ then
X$    FQDN := 'p1'
X$    FQDN := 'f$edit(FQDN,"collapse,upcase")
X$    goto check_auth
X$ endif
X$ if (f$mode() .eqs. "INTERACTIVE" .and. p1 .eqs. "")
X$ then
X$    read/prompt="_Fully_Qualified_Domain_Name:  " sys$command FQDN
X$    FQDN := 'f$edit(FQDN,"collapse,upcase")
X$    if (FQDN .eqs. "") then exit ($status)
X$    goto check_auth
X$ endif
X$!
X$!`09Get the FQDN from file if not interactive user
X$!
X$ from_file:
X$ open/read/error=open_err infile 'fname'
X$ read infile FQDN
X$ close infile
X$ delete/noconfirm 'fname';*
X$ FQDN := 'f$edit(FQDN,"collapse,upcase")
X$!
X$!`09Check if the node is authorized
X$!
X$ check_auth:
X$ auth := FALSE
X$ fname := sys$common:`5Butil.clock_server`5Dauthorized_clock.clients
X$ open/read/error=open_err infile 'fname'
X$ read_loop:
X$    read/end=close_file infile entry
X$    entry := 'f$edit(entry,"collapse,upcase")
X$    if (entry .eqs. FQDN)
X$    then
X$`09auth := TRUE
X$`09goto close_file
X$    endif
X$ goto read_loop
X$ close_file:
X$    close infile
X$!
X$!`09Display some info
X$!
X$ if (auth .eqs. "TRUE")
X$ then
X$    w "''FQDN'  is an authorized client"
X$ else
X$    w "''FQDN'  is NOT an authorized client"
X$    exit ($status)
X$ endif
X$ w "FQDN:         ''FQDN'"
X$ PName = f$extract(0,9,FQDN)+" Clock"
X$ w "PName:        ''PName'"
X$ DispName = f$extract(0,12,FQDN)+"_Display"
X$ w "DisplayName:  ''DispName'"
X$!
X$!
X$!`09Start the clock
X$!
X$ if (f$trnlnm("''DispName'") .eqs. "") then -
X   set disp/create/node='FQDN'/trans=tcpip "''DispName'"
X$ w ""
X$ w "Starting process for ''FQDN' on "+f$trnlnm("''DispName'")+" ..."
X$ run/det/out='f$trnlnm(DispName)/err=nl:/inp=nl:/proc="''PName'" -
X`09sys$system:decw$clock
X$ w ""
X$!
X$!`09Wait for awhile if $CREPRC process (f$mode() => OTHER) or NETWORK
X$!
X$ get_pid:`09`09! Wait for our process to get named by the system
X$    wait 0:0:1
X$    temp=f$context("process",pidctx,"prcnam","''PName'","eql")
X$    pid=f$pid(pidctx)
X$    if (pid .eqs. "") then goto get_pid
X$!
X$ wait_loop:`09`09! Wait until the clock is fully alive before exiting
X$    wait 0:0:1
X$    if (f$getjpi(pid,"state") .nes. "LEF") then goto wait_loop
X$ exit($status)
X$!
X$!`09Open error handler
X$!
X$ open_err:
X$`09w ""
X$`09w "Open Error:  Could not open ''fname'"
X$`09w ""
X$ exit ($status)
$ CALL UNPACK CLOCK.COM;1 877474790
$ create 'f'
X$! Startup file for the DEC X-window clock server    (SC)  5/13/92
X$ run sys$common:`5Butil`5Dclock_server -
X   /noaccounting -
X   /noauthorize -
X   /detached -
X   /error=nl: -
X   /input=nl: -
X   /output=nl: -
X   /priority=6 -
X   /privileges=(noall,detach,netmbx,tmpmbx) -
X   /process_name="Clock Server" -
X   /uic=`5B1,4`5D
X$ exit ($status)
$ CALL UNPACK CLOCK_SERVER.COM;1 957434799
$ create 'f'
Xsys$library:ucx$ipc.olb/lib
Xsys$share:vaxcrtl.exe/share
$ CALL UNPACK CLIENT_SERVER.OPT;1 437344392
$ create 'f'
X$ set verify
X$ cc/nodeb/opt vclient
X$ link/nodeb/notrac vclient, client_server/opt
X$ delete/noconfirm *.obj;*
X$ purge vclient.exe
X$ set noverify
$ CALL UNPACK MAKE_CLIENT.COM;1 1648823850
$ create 'f'
X$ set verify
X$ cc/nodeb/opt vserver
X$ link/nodeb/notrac vserver, client_server/opt
X$ delete/noconfirm *.obj;*
X$ purge vserver.exe
X$ set noverify
$ CALL UNPACK MAKE_SERVER.COM;1 1901857687
$ create 'f'
X/*====================================================================
X*
X*`09`09`09  COPYRIGHT (C) 1989 BY
X*`09      DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
X*
X* This software is furnished under a license and may be used and  copied
X* only  in  accordance  with  the  terms  of  such  license and with the
X* inclusion of the above copyright notice.  This software or  any  other
X* copies  thereof may not be provided or otherwise made available to any
X* other person.  No title to and ownership of  the  software  is  hereby
X* transferred.
X*
X* The information in this software is subject to change  without  notice
X* and  should  not  be  construed  as  a commitment by DIGITAL EQUIPMENT
X* CORPORATION.
X*
X* DIGITAL assumes no responsibility for the use or  reliability  of  its
X* software on equipment which is not supplied by DIGITAL.
X*
X*
X*
X*  FACILITY:
X*`09INSTALL`20
X*     `20
X*
X*  ABSTRACT:
X*`09This is an example of a TCP/IP client using the IPC`20
X*`09socket interface.
X*     `20
X*
X*  ENVIRONMENT:
X*`09UCX V1.2 or higher, VMS V5.2 or higher `20
X*
X*`09This example is portable to Ultrix. The include
X*`09files are conditionally defined for both systems, and`20
X*`09"perror" is used for error reporting.
X*
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*  AUTHORS:
X*`09UCX Developer`09
X*
X*  CREATION DATE: May 23, 1989`20
X*
X*  MODIFICATION HISTORY:
X*
X*/
X
X
X/*
X*
X*  INCLUDE FILES
X*
X*/
X
X#ifdef VAXC
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#else
X#include <errno.h>
X#include <sys/types.h>
X#include <stdio.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <netdb.h>
X#include <arpa/inet.h>
X#include <sys/uio.h>
X#endif
X
X
X/*
X*
X*   MACRO DEFINITIONS
X*
X*/
X
X#ifndef vms
X#define TRUE 1
X#define FALSE 0
X#endif
X
X/*
X* Functional Description
X*
X*`09This example creates a socket of type SOCK_STREAM (TCP),
X*`09initiates a connection to the remote host, sends
X*`09a message to the remote host, and closes the connection.`09
X*`09Error messages are printed to the screen.
X*
X*`09IPC calls used:`20
X*`09close
X*`09connect
X*`09gethostbyname
X*`09send
X*`09shutdown
X*`09socket`09
X*
X*
X* Formal Parameters
X*`09The client program expects two parameters:
X*`09hostname ... name of remote host`20
X*`09portnumber ... port where remote host(server) is listening
X*
X*
X* Routine Value
X*
X*`09Status`09
X*/
X
X
X`0C
X
X/*--------------------------------------------------------------------*/
Xmain(argc,argv)
Xint`09argc;
Xchar`09**argv;
X`7B
X
X        int     sock_1;               `09`09/* socket */
Xstatic  char  `09message`5B`5D = "Hi there.";
Xstatic `09struct  sockaddr_in sock2_name;    `09/* Address struct for socket
V2.*/
X        struct  hostent         hostentstruct;  /* Storage for hostent data.
V  */
X        struct  hostent         *hostentptr;    /* Pointer to hostent data.
V   */
+-+-+-+-+-+-+-+-  END  OF PART 1 +-+-+-+-+-+-+-+-