From:	CRDGW2::CRDGW2::MRGATE::"SMTP::UBVMSC.CC.BUFFALO.EDU::SYSTEM" 23-JUN-1989 19:42
To:	MRGATE::"ARISIA::EVERHART"
Subj:	DISK$ACSDISK2:[VMSSERV.VAX]VMSSERV.1_OF_4;1

Message-Id:  <8906231651.AA04847@crdgw1.ge.com>
Date: Fri, 23 Jun 89 12:42 EDT
From: SYSTEM@ubvmsc.cc.buffalo.edu
Subject: DISK$ACSDISK2:[VMSSERV.VAX]VMSSERV.1_OF_4;1
To: everhart@arisia.decnet
X-Vms-To: IN%"everhart%arisia.decnet@crdgw1.ge.com"

$! ................... Cut between dotted lines and save. ...................
$!...........................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.10 7-FEB-1989.
$!
$! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from
$! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au).
$!
$! To unpack, simply save, concatinate all parts into one file and
$! execute (@) that file.
$!
$! This archive was created by user GERLAND (Jim Gerland - SUNY/Buffalo)
$! on 31-MAR-1989 11:39:28.02.
$!
$! ATTENTION: To keep each article below 63 blocks (32256 bytes), this
$!            program has been transmitted in 4 parts.  You should
$!            concatenate ALL parts to ONE file and execute (@) that file.
$!
$! It contains the following 8 files:
$!        MAKEFILE.
$!        START-VMSSERV.COM
$!        VMSSERV.C
$!        VMSSERV.RNO
$!        VMSSERV.RNT
$!        VMSSERV_INTERNET.HELP
$!        VMSSERV_NOTFOUND.TEXT
$!        VMSSERV_TRANSFER_INFO.TEXT
$!
$!============================================================================
$ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL )
$ VERSION = F$GETSYI( "VERSION" )
$ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK
$ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", -
    "VMS_SHARE V06.10 7-FEB-1989 requires VMS V4.4 or higher."
$ EXIT 44 ! SS$_ABORT
$VERSION_OK:
$ GOTO START
$!
$UNPACK_FILE:
$ WRITE SYS$OUTPUT "Creating ''FILE_IS'"
$ DEFINE/USER_MODE SYS$OUTPUT NL:
$ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION -
    VMS_SHARE_DUMMY.DUMMY
b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) )
; s_file_spec := GET_INFO( COMMAND_LINE, "output_file" ); SET( OUTPUT_FILE
, b_part, s_file_spec ); b_errors := CREATE_BUFFER( "{Errors}" ); i_errors 
:= 0; pat_beg_1 := ANCHOR & "-+-+-+ Beginning"; pat_beg_2 := LINE_BEGIN 
& "+-+-+-+ Beginning"; pat_end := ANCHOR & "+-+-+-+-+ End"; POSITION
( BEGINNING_OF( b_part ) ); LOOP EXITIF SEARCH( SPAN( ' ' )@r_trail 
& LINE_END, FORWARD) = 0; POSITION( r_trail ); ERASE( r_trail ); ENDLOOP
; POSITION( BEGINNING_OF( b_part ) ); i_append_line := 0; LOOP EXITIF MARK
( NONE ) = END_OF( b_part ); s_x := ERASE_CHARACTER( 1 )
; IF s_x = '+' THEN r_skip := SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip 
<> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF
; ENDIF; IF s_x = '-' THEN r_skip := SEARCH( pat_end, FORWARD, EXACT )
; IF r_skip <> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip 
:= MARK( NONE ); r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip 
<> 0 THEN POSITION( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET )
; MOVE_VERTICAL( 1 ); MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part ) 
); ENDIF; ERASE( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF
; IF s_x = 'V' THEN s_x := ''; IF i_append_line <> 0 THEN APPEND_LINE
; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF; i_append_line := 1
; MOVE_VERTICAL( 1 ); ENDIF; IF s_x = 'X' THEN s_x := ''; IF i_append_line 
<> 0 THEN APPEND_LINE; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF
; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; IF s_x <> '' THEN i_errors 
:= i_errors + 1; s_text := CURRENT_LINE; POSITION( b_errors ); COPY_TEXT
( "The following line could not be unpacked properly:" ); SPLIT_LINE
; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part ); MOVE_VERTICAL
( 1 ); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP r_x := SEARCH
( "`", FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x ); ERASE_CHARACTER( 1 
); COPY_TEXT( ASCII( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDLOOP
; IF i_errors = 0 THEN SET( NO_WRITE, b_errors, ON ); ELSE POSITION
( BEGINNING_OF( b_errors ) ); COPY_TEXT( FAO
( "The following !UL errors were detected while unpacking !AS", i_errors
, s_file_spec ) ); SPLIT_LINE; SET( OUTPUT_FILE, b_errors, "SYS$COMMAND" )
; ENDIF; EXIT; 
$ DELETE VMS_SHARE_DUMMY.DUMMY;*
$ CHECKSUM 'FILE_IS
$ WRITE SYS$OUTPUT " CHECKSUM ", -
  F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!!,passed." )
$ RETURN
$!
$START: 
$ FILE_IS = "MAKEFILE."
$ CHECKSUM_IS = 1534201282
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X# makefile for vmsserv
X
X%SPAWN
X
Xvmsserv: vmsserv.exe vmsserv.doc vmsserv.hlp
X
Xvmsserv.exe: vmsserv.obj
X   link vmsserv,sys$input/options`032
X   jan_lib:janshr.exe /share $
X   sys$share:vaxcrtl.exe /share $
X   purge /log
X
Xvmsserv.obj: vmsserv.c
X   cc vmsserv.c
X
Xvmsserv.doc : vmsserv.rno`032
X   runoff /var=doc /intermediate=vmsserv.brn /nooutput vmsserv.rno
X   runoff /contents /output=vmsserv.rnt vmsserv.brn
X   edit /edt  /nocommand vmsserv.rnt`032
X      '.page size'                                    $
X      sub/.page size , 70/.page size , 76/            $
X      exit                                            $
X   runoff /var=doc /output=vmsserv.doc vmsserv.rno`032
X   runoff /variant=doc vmsserv.rno /output=vmsserv.doc
X   purge /log
X
Xvmsserv.hlp : vmsserv.rno
X   runoff /variant=help vmsserv.rno /output=vmsserv.hlp
X   purge /log
$ GOSUB UNPACK_FILE

$ FILE_IS = "START-VMSSERV.COM"
$ CHECKSUM_IS = 1495294053
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X$ Node   = F$Trnlnm ("SYS$NODE") - "_" - "::"
X$ If Node .NES. "UBVMSD" Then GoTo Exit
X$ If P1 .EQS. "WARM" Then GoTo No_Logicals
X$    def/sys/exec/nolog kerfiles_all                  vmsserv_disk
X$    def/sys/exec/nolog listserver_hook_name          vmsserv
X$    def/sys/exec/nolog vmsserv_batch_queue           fastbatchd
X$    def/sys/exec/nolog vmsserv_batch_username        vmsserv
X$    def/sys/exec/nolog vmsserv_default_listname      vmsserv
X$    def/sys/exec/nolog vmsserv_defer_send_filesize   200
X$    def/sys/exec/nolog vmsserv_disk                  disk$acsdisk2
V$    def/sys/exec/nolog vmsserv_files                 vmsserv_disk:[ubserve..
X.]
V$    def/sys/exec/nolog vmsserv_file_location_vmsserv vmsserv_disk:[ubserve..
X.]
X$    def/sys/exec/nolog vmsserv_internet_reply_agent  pmdf
X$    def/sys/exec/nolog vmsserv_login_directory       vmsserv_disk:[ubserve]
X$    def/sys/exec/nolog vmsserv_process_mail          yes
V$    def/sys/exec/nolog vmsserv_scratch_directory    vmsserv_disk:[ubserve.wo
Xrk]
X$    def/sys/exec/nolog vmsserv_time_stamp_interval   "0 02:00:00.00"
X$    def/sys/exec/nolog vmsserv_wakeup_timer          "0 00:01:00.00"
X$ No_Logicals:
X$    If p1 .eqs. "LOGICALS" Then GoTo Exit
X$    Run /Proc="VMSserv_Daemon" -
X         /UIC=[1,4] -
X         /Output=Jan_Sys:vmsserv.Err -
X         /Error=Jan_Sys:vmsserv.Err -
X         /Privilege=(SAME) -
X         /Priority=6 -
X         jan_sys:vmsserv
X$ Exit:
X$   Exit
X$   def/sys/exec/nolog vmsserv_binary      vmsserv_disk:[ubserve.binary]
X$   def/sys/exec/nolog vmsserv_bitnet      vmsserv_disk:[ubserve.bitnet]
X$   def/sys/exec/nolog vmsserv_cms_doc     vmsserv_disk:[ubserve.doc.cms]
X$   def/sys/exec/nolog vmsserv_consult     vmsserv_disk:[ubserve.consult]
X$   def/sys/exec/nolog vmsserv_dir         vmsserv_disk:[ubserve]
X$   def/sys/exec/nolog vmsserv_doc         vmsserv_disk:[ubserve.doc]
X$   def/sys/exec/nolog vmsserv_ibm         vmsserv_disk:[ubserve.ibm]
X$   def/sys/exec/nolog vmsserv_interface   vmsserv_disk:[ubserve.interface]
X$   def/sys/exec/nolog vmsserv_kermit      vmsserv_disk:[ubserve.kermit]
X$   def/sys/exec/nolog vmsserv_micro       vmsserv_disk:[ubserve.micro]
X$   def/sys/exec/nolog vmsserv_micro_notes vmsserv_disk:[ubserve.micro.notes]
X$   def/sys/exec/nolog vmsserv_tex         vmsserv_disk:[ubserve.tex]
X$   def/sys/exec/nolog vmsserv_vax         vmsserv_disk:[ubserve.vax]
X$   def/sys/exec/nolog vmsserv_vms_doc     vmsserv_disk:[ubserve.doc.vms]
X$   def/sys/exec/nolog vmsserv_work_dir    vmsserv_disk:[ubserve.work]
X$   def/sys/exec/nolog vmsserv_dir_all     vmsserv_binary, -
X                                           vmsserv_bitnet, -
X                                           vmsserv_cms_doc, -
X                                           vmsserv_consult, -
X                                           vmsserv_dir, -
X                                           vmsserv_doc, -
X                                           vmsserv_ibm, -
X                                           vmsserv_interface, -
X                                           vmsserv_kermit, -
X                                           vmsserv_micro, -
X                                           vmsserv_micro_notes, -
X                                           vmsserv_tex, -
X                                           vmsserv_vax, -
X                                           vmsserv_vms_doc
$ GOSUB UNPACK_FILE

$ FILE_IS = "VMSSERV.C"
$ CHECKSUM_IS = 2130960087
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/*
X23-APR-1985 09:02 Brian Nelson`009`009`009`009`009
X`009`009`009`009`009`009`009`009
XEdits:`009`009`009`009`009`009`009`009
X`009`009`009`009`009`009`009`009`009
X29-APR-1985 BDN`009Fix DIR command if no argument (force *.*)`009
X30-APR-1985 BDN`009Check $STATUS after DIR and SEND. Add SET NOON`009
X11-SEP-1985 BDN Fix bugs introduced with VAX C v2 (and bad code)
X02-Apr-1986 BDN Jnet version 2 mods`009`009`009`009
X21-OCT-1986 BDN Change from Daemon to run as a hook.`009`009
X21-OCT-1986 BDN PUNCH command (include :READ File Type     Date)
X 4-NOV-1986 BDN Remove trailing spaces from USER and NODE`009
X10-NOV-1986 BDN Remove call to STAT(), replace with FSTAT() due to a bug
X`009`009in C RTL version of STAT.`009`009
X20-APR-1987 BDN Treat SYSTEM messages as no-ops. Got into a loop with
X`009`009ARIZMIS sending messages telling VMSSERV to send messages
X`009`009to explicit vaxcluster nodes.`009
X
X 4-MAR-1988 BDN`009Major rewrites
X12-MAR-1988 BDN Comment the code a little (uggh...) It is assumed that the
X`009`009reader has access to the jnet doc and is familiar with the
X`009`009functioning of jnet.
XVERSION 1.00
X24-Mar-1988 JRG`009Added Jnet logging info
X`009`009Added * to prefix messages to indicate program generatated
X`009`009messages
X                Added Version Number
X31-Mar-1988 BDN`009Merg Jim's changes, add more logging
XVERSION 1.01
X06-Apr-1988 BDN`009Finish up internet mail replies.
XVERSION 1.02
X08-Apr-1988 JRG Changed all references of KERMSRV to VMSSERV
X                Added start-up & logical definitions comments
X                Added "F" to file-logging and rearranged log message
X
XVersion 1.03
X
X26-APR-1988 BDN`009Re-do the INDEX command (see SEND_MAIL_INDEX() and
X`009`009SENDINDEX().
X
XVersion 1.04
X
X01-May-1988 BDN`009Screwed up the arg list for DO_MAIL(), resulting in pure
X`009`009bitnet addresses derived from the RSCS tag to be swapped,
X`009`009if, UOFT02@BRIAN. Sorry, Jim
X
XVersion 1.05
X
X31-May-1988 BDN`009Was doing a FREE() prematurely in CREATE_BATCH_JOB().
X
XVersion 1.06
X
X01-Jun-1988 BDN`009Redo SENDBATCH() to work correctly when passing parameters
X`009`009to a batch job.
X`009`009Modify DO_MAIL() to scan for multiple headers
X`009`009Abort mail command processing upon finding unknown command
X
XVersion 1.07
X
X02-Jun-1988 BDN`009Fixed the 'run time library corrupted' problem.  Replaced
X`009`009malloc and free with xmalloc and xfree, which use the lib
X`009`009rtl routines LIB$CREATE_VM_ZONE, LIB$GET_VM and LIB$FREE_VM
X
XVersion 1.08
X
V08-Jun-1988 BDN`009Minor changes for moving the log file, deleting DIR listin
Xgs
X`009`009and such.
X
XVersion 1.09
X
X06-Jul-1988 BDN Add support for $PACKAGE files.
X
XVersion 1.10
X
X16-Jul-1988 BDN Kludge in IBM NOTE format mail.  Also insure that the server
X`009`009will never try to respond to itself. Both mods in DO_MAIL().
X`009`009The server basically got stuck in an  endless loop the other
X`009`009day when it picked up a NOTE format file which ended up with
X`009`009the server sending itself 1500 mails complaining about the
X`009`009response.
X`009`009Also changed some of the replies for invalid requests.
X`009`009For an example of what happened, see the following log:
X
X`009`009  Date:     Fri, 15 Jul 88 04:55 EDT
X`009`009  Original_From:  IN%"KERBATCH@UOFT02"
X`009`009  Comments: This is gatewayed mail.  Warning:  Mail may not`032
X`009`009            necessarily be returnable through this path.
X`009`009  From:     General Delivery <POSTMASTER@UOFT02>
X`009`009  Subject:  SYS$SYSROOT:[KERMSRV]gqc019533.MSG
X`009`009  To:       kermsrv@uoft02
X`009`009  Original_To:  KERBATCH@UOFT02
X`009`009`032
X`009`009  Date: Fri, 15 Jul 88 04:55 EST
X`009`009  From: KERBATCH@UOFT02
X`009`009  Subject: SYS$SYSROOT:[KERMSRV]gqc019533.MSG
X`009`009  To: KERBATCH@UOFT02
X`009`009  X-VMS-To: IN%"KERBATCH@UOFT02"
X`032
X`032
X`009`009  Your request YOUR to KERMSRV is unknown.
X`009`009  Please resubmit with a HELP command
X`032
X
XVersion 1.11
X
X19-JUL-1988 BDN`009Remove leading spaces from interactive message. Seems
X`009`009to be a problem with ANL nje messages.
X`009`009Fix printf format for PUNCH command
X`009`009Simple check $PACKAGE file calling itself
X
XVersion 1.12
X
X27-Jul-1988 BDN`009Change package processing. A command of SEND XYZ.PACKAGE
X`009`009now looks for path_name:XYZ.$PACKAGE and reads it for
X`009`009filenames. A command of SEND XYZ.$PACKAGE send the actual
X`009`009file.
X`009`009Fix minor problem with PUNCH and wildcards
X
XVersion 1.13
X
X08-Aug-1988 BDN`009Support lsw continuation lines for a header, ie, process
X`009`009folding in address fields per RFC822. This is supported
X`009`009only for from: headers, ie:
X
X`009`009from: "brian nelson" <brian@uoft02.bitnet>
X
X`009`009is equivalent to:
X
X`009`009from: "brian nelson"
X`009`009  <brian@
X`009`009   uoft02.bitnet>
X
X
X`009`009Ain't mail processing fun!!
X
XVersion 1.14
X
X09-Aug-1988 BDN`009Insert the users command into package processing, ie,
X`009`009if VMSDUMP XYZ.PACKAGE, then do so.`032
X
XVersion 1.15
X
X11-Aug-1988 BDN Misc mods, STATUS cmd (interactive only)
X
XVersion 1.16
X
X12-Aug-1988 BDN Typo for statistics collecting. Fix package processing
X
XVersion 1.17
X
X17-Aug-1988 BDN Fixes for INDEX listname. Added logical called
X`009`009hookname_files_available so the manager can turn
X`009`009off the server without having to remove the server.
X
X
XVersion 1.18
X
X19-Aug-1988 BDN`009Added OFFLINE and ONLINE commands. Must come from
X`009`009local postmaster, ie, 'hookname'_postmaster_userid.
X`009`009Add support for alternate logical name table, by
X`009`009defining a logical called LISTSERVER_TABLE_NAME
X`009`009in LNM$SYSTEM_TABLE to translate into the desired
X`009`009logical name.
X
X26-Sep-1988 BDN`009Insure the function char *collapse() removes control
X`009`009characters. LIB$FINDFILE under vms v5 barfs on line
X`009`009feeds (from the $PACKAGE files).
X
X27-Sep-1988 BDN`009Fix up offline processing for received mail.
X
X
X
X03-Jan-1989 BDN`009WARNING -- In both VMS v4 and VMS v5.0-2 there is a
X`009`009problem with SYS$SNDJBC. If the com and/or log files
X`009`009are placed in a search list, the job controller will
X`009`009never deallocate the channel. Insure that the scratch
X`009`009directory tranlates to single root!
X
XVersion 1.19
X
X10-Mar-1989 BDN`009Changes in mail to self looping (caused when a gateway
X`009`009rejects an address and returns the mail). Specifically,
X`009`009the problem arose after changing the local PMDF.CNF
X`009`009file to support WIN/TPC and changing the rules such
X`009`009that all incoming bitnet mail now reads U@H.BITNET.
X
X`012
X$ cc VMSSERV
X$ link VMSSERV,sys$input:/opt
Xjan_common:[lib]janshr/share
Xsys$share:vaxcrtl/sha
X$ cop VMSSERV.exe jan_sys:
X$ jcp remove VMSSERV
X$ If P1 .EQS. "WARM" Then GoTo No_Logicals
X$ create/name/nolog/par=lnm$system_directory lnm_servers
X$!
X$ def /sys /exec /nolog/tab=lnm$system_table listserver_hook_name  vmsserv
V$ def /sys /exec /nolog/tab=lnm$system_table listserver_table_name lnm_server
Xs
X$!
X$ def /sys/nolog/tab=lnm_servers vmsserv_batch_queue    sys$kermit_batch
X$ def /sys/nolog/tab=lnm_servers vmsserv_wakeup_timer   "0 00:01:00.00"
X$ def /sys/nolog/tab=lnm_servers vmsserv_batch_username  kerbatch
V$ def /sys/nolog/tab=lnm_servers vmsserv_login_directory sys$sysroot:[vmsserv
X]
V$ def /sys/nolog/tab=lnm_servers vmsserv_scratch_directory sys$sysroot:[vmsse
Xrv]
X$ def /sys/nolog/tab=lnm_servers vmsserv_time_stamp_interval  "0 02:00:00.00"
X$ def /sys/nolog/tab=lnm_servers vmsserv_default_listname    vmsserv
X$ def /sys/nolog/tab=lnm_servers vmsserv_file_location_hispanist -
X      sys$sysroot:[hispaniaj.pd]
X$ def /sys/nolog/tab=lnm_servers vmsfiles_all -
X      sys$sysroot:[hispaniaj.pd],kerfiles_all
V$ def /sys/nolog/tab=lnm_servers vmsserv_file_location_kermit   "kerfiles_all
X:"
V$ def /sys/nolog/tab=lnm_servers vmsserv_file_location_default  "vmsfiles_all
X:"
V$ def /sys/nolog/tab=lnm_servers vmsserv_file_location_vmsserv  "vmsfiles_all
X:"
X$ def /sys/nolog/tab=lnm_servers vmsserv_defer_send_filesize 200
X$ def /sys/nolog/tab=lnm_servers vmsserv_internet_reply_agent pmdf
X$ def /sys/nolog/tab=lnm_servers vmsserv_process_mail        yes
X$ def /sys/nolog/tab=lnm_servers vmsserv_internet_helpfile  -
X       sys$sysroot:[vmsserv]vmsserv_internet.help
X$ def /sys/nolog/tab=lnm_servers vmsserv_not_found  -
X       sys$sysroot:[vmsserv]vmsserv_notfound.text
X$ def /sys/nolog/tab=lnm_servers vmsserv_transfer_info -
X       sys$sysroot:[vmsserv]vmsserv_transfer_info.text
X$ No_Logicals:
X$ If p1 .eqs. "LOGICALS" Then GoTo Exit
X$ Run /Proc="VMSserv_Daemon" -
X      /UIC=[1,4] -
X      /Output=Jan_Sys:vmsserv.Err -
X      /Error=Jan_Sys:vmsserv.Err -
X      /Privilege=(SAME) -
X      /Priority=6 -
X      jan_sys:vmsserv
X$ Exit:
X$   Exit
X
XMuch of the code is entirely my own fault, some of it is terrible. Please
Xendure it. What better way to pick up on C than to force oneself to write
Xsomething in it (of course, that was three years ago). \Brian
X*/
X
X
X`012
X
X#include <descrip>
X
X
X/* This is the DEFAULT hook name, which is used if the translation
X   LISTSERVER_HOOK_NAME (from LNM$SYSTEM_TABLE) should fail. */
X
X
X$DESCRIPTOR(hook_name,"VMSSERV") ;
X$DESCRIPTOR(table_name,"LNM$SYSTEM_TABLE") ;
X
X
X
X/*  The pointers with the suffix of  '_logical'  are initialized in
X 'Generate_logicals(),  as  well are  the pointers of the same name
X without the 'logical' suffix.  The former point to generated names
X names of the form 'Hook_name_namestring',  and the latter point to
X translations of these names,  or if no translation was found, then
X a default. For example, if the hook name is 'VMSSERV', translation
X of the system logical name 'VMSSERV_BATCH_QUEUE' will be attempted
X to determine what batch queue to use.
X
X  The STRUCT  'logicals'  is  nothing  more  than  a  set  of  four
X pointers.  The first is a pointer to the prototype for the logical
X name. As mentioned above, this string is appended to the hook name
X to generate the logical name  to  translate.  The  second  pointer
X defines  a  DEFAULT string to use for the logical name translation
X if such should fail. The third entry is  a  pointer  to  a  string
X pointer  where  the logical name that is generated will be stored.
X This field is not really needed, but it may be desirable  at  some
X point  to  have  the  name  around  in  case  another  attempt  at
X translation is made. The allocation for this string is  done  with
X MALLOC().  The  last entry is the actual translation (a pointer to
X the pointer). Again, this is allocated via MALLOC() at startup.
X
X  The use of the struct is  merely  for  the  convienience  of  the
X function  generate_logicals(),  and to simplify adding new entries
X in the future.`032
X
X*/
X
X
X
Xchar *timer_interval_logical ;
Xchar *batch_queue_logical ;
Xchar *login_dir_logical ;
Xchar *scratch_dir_logical ;
Xchar *batch_username_logical ;
Xchar *time_stamp_interval_logical ;
Xchar *defer_send_filesize_logical ;
Xchar *default_listname_logical ;
Xchar *internet_reply_agent_logical ;
Xchar *process_mail_logical ;
Xchar *internet_helpfile_logical ;
Xchar *not_found_logical ;
Xchar *xfer_info_logical ;
Xchar *postmaster_userid_logical ;
Xchar *test_mode_logical ;
Xchar *requests_since_boot_logical ;
Xchar *files_available_logical ;
X
Xchar *timer_interval ,*batch_queue ,*login_dir ,*scratch_dir ;
Xchar *batch_username ,*time_stamp_interval,*default_listname ;
Xchar *defer_send_filesize ,*internet_reply_agent ,*process_mail ;
Xchar *not_found,*internet_helpfile,*xfer_info,*postmaster_userid ;
Xchar *test_mode,*requests_since_boot,*files_available ;
X
Xchar *file_location_proto = "_FILE_LOCATION_" ;
Xchar *file_location_def,file_location_def_logical ;
Xchar *file_location ;
X
X`012
X
X
Xstruct logicals `123 char *pro ;
X`009`009  char *def   ;
X`009`009  char **log   ;
X`009`009  char **xla   ;
X`009`009`125
X
X       loglist[] = `123`009"_WAKEUP_TIMER",
X`009`009      `009"0 00:01:00.00",
X`009`009`009&timer_interval_logical,
X`009`009`009&timer_interval,
X`009`009`009
X`009`009`009"_BATCH_QUEUE" ,
X`009`009`009"VMSSERV_BATCH" ,
X`009`009`009&batch_queue_logical ,
X`009`009`009&batch_queue ,
X
X`009`009`009"_BATCH_USERNAME" ,
X`009`009`009"VMSSERV     " ,
X`009`009`009&batch_username_logical ,
X`009`009`009&batch_username ,
X
X`009`009`009"_LOGIN_DIRECTORY" ,
X`009`009`009"SYS$SYSROOT:[VMSSERV]" ,
X`009`009`009&login_dir_logical  ,
X`009`009`009&login_dir ,
X
X`009`009`009"_SCRATCH_DIRECTORY" ,
X`009`009`009"SYS$SYSROOT:[VMSSERV]" ,
X`009`009`009&scratch_dir_logical ,
X`009`009`009&scratch_dir ,
X
X`009`009`009"_TIME_STAMP_INTERVAL" ,
X`009`009      `009"0 02:00:00.00",
X`009`009`009&time_stamp_interval_logical ,
X`009`009`009&time_stamp_interval ,
X
X`009`009`009"_DEFAULT_LISTNAME" ,
X`009`009`009"VMSSERV" ,
X`009`009`009&default_listname_logical ,
X`009`009`009&default_listname ,
X
X`009`009`009"_DEFER_SEND_FILESIZE" ,
X`009`009`009"200" ,
X`009`009`009&defer_send_filesize_logical ,
X`009`009`009&defer_send_filesize ,
X
X`009`009`009"_INTERNET_REPLY_AGENT",
X`009`009`009"PMDF" ,
X`009`009`009&internet_reply_agent_logical ,
X`009`009`009&internet_reply_agent ,
X
X`009`009`009"_PROCESS_MAIL" ,
X`009`009`009"YES" ,
X`009`009`009&process_mail_logical ,
X`009`009`009&process_mail ,
X
X`009`009`009"_INTERNET_HELPFILE" ,
X`009`009`009"SYS$SYSROOT:[VMSSERV]VMSSERV_INTERNET.HELP" ,
X`009`009`009&internet_helpfile_logical ,
X`009`009`009&internet_helpfile ,
X
X`009`009`009"_NOT_FOUND" ,
X`009`009`009"SYS$SYSROOT:[VMSSERV]VMSSERV_NOTFOUND.TEXT" ,
X`009`009`009&not_found_logical ,
X`009`009`009&not_found ,
X
X`009`009`009"_TRANSFER_INFO" ,
X`009`009`009"SYS$SYSROOT:[VMSSERV]VMSSERV_TRANSFER_INFO.TEXT" ,
X`009`009`009&xfer_info_logical ,
X`009`009`009&xfer_info ,
X
X`009`009`009"_POSTMASTER_USERID" ,
X`009`009`009"SYSTEM" ,
X`009`009`009&postmaster_userid_logical ,
X`009`009`009&postmaster_userid ,
X
X`009`009`009"_TEST_MODE" ,
X`009`009`009"NO" ,
X`009`009`009&test_mode_logical ,
X`009`009`009&test_mode ,
X
X`009`009`009"_FILE_LOCATION_DEFAULT" ,
X`009`009`009"VMSSERV_ALL:" ,
X`009`009`009&file_location_def_logical ,
X`009`009`009&file_location_def ,
X
X`009`009`009"_REQUESTS_SINCE_BOOT" ,
X`009`009`009"0" ,
X`009`009`009&requests_since_boot_logical ,
X`009`009`009&requests_since_boot ,
X
X`009`009`009"_FILES_AVAILABLE" ,
X`009`009`009"YES" ,
X`009`009`009&files_available_logical ,
X`009`009`009&files_available ,
X
X`009`009`009"","",0,0 `125 ;
X
X
X
Xchar *listserver_hook_name_logical = "LISTSERVER_HOOK_NAME" ;
Xchar *listserver_hook_name ;
Xchar *listserver_table_name_logical = "LISTSERVER_TABLE_NAME" ;
Xchar *listserver_table_name ;
Xchar *mynode ;
X
Xchar *version = "1.19 10-Mar-1989" ;
X
X
X`012
X
X/* If the hook name were VMSSERV, then the following logicals
X   could be defined.
X
XVMSSERV_BATCH_QUEUE`009     The batch queue to send all jobs to.
XVMSSERV_BATCH_USERNAME`009     The username to submit all batch jobs under
XVMSSERV_DEFAULT_LISTNAME     Default list name.
VVMSSERV_DEFER_SEND_FILESIZE  A numeric value to defer sending of a file large
Xr
X`009`009`009     than this value.
VVMSSERV_INTERNET_HELPFILE    Translates to a file spec to use for HELP reques
Xts
X`009`009`009     from mail.
XVMSSERV_INTERNET_REPLY_AGENT The package used to send Internet mail
X                             (PMDF or GMail).
XVMSSERV_LOGIN_DIRECTORY`009     SYS$LOGIN for VMSSERV_BATCH_USERNAME
XVMSSERV_NOT_FOUND`009     Translates to a file spec to use when sending
X`009`009`009     file not found messages.
VVMSSERV_PROCESS_MAIL         Yes or No depending on whether your server shoul
Xd
X                             process commands sent to it via mail.
XVMSSERV_POSTMASTER_USERID    Where to report errors to (defaults to SYSTEM).
XVMSSERV_SCRATCH_DIRECTORY    A directory for creating work files in, normally
X`009`009`009     would be the same as the SYS$LOGIN directory
VVMSSERV_TIME_STAMP_INTERVAL  A delta time to trigger an opcom timestamp messa
Xge
XVMSSERV_TRANSFER_INFO`009     This is a prefix file to attach to the start of
X`009`009`009     directory listings.
XVMSSERV_WAKEUP_TIMER`009     A delta time to trigger a timer ast for periodic
X`009`009`009     housecleaning functions.
X
XA second type of logical will be generated 'on the fly', that is, for every
Xrequest. The name has the form:
X
X`009hookname_FILE_LOCATION_listname
X
Xie, for VMSSERV files and a server called VMSSERV, with the translation of
Xof VMSSERV_DEFAULT_LISTNAME being VMSSERV, it would be:
X
X`009VMSSERV_FILE_LOCATION_VMSSERV
X
X On this node (UOFT02.BITNET) it would translate to VMSSERV_ALL. The logical
Xname is built in GENERATE_PATH(suffix)
X
X
XFiles that are received are put into the scratch directory with a filename
Xof 'hook_name'.receive, as in:
X
X`009sprintf(dst,"%s%s.RECEIVE",scratch_dir,hook_name.dsc$a_pointer) ;
X
Xfor example, if hook name is VMSSERV, then files go into:
X
X`009VMSSERV_SCRATCH_DIRECTORY:VMSSERV.RECEIVE
X
Xor whatever default is for the directory if the logical was not defined.
XThis can be changed and the actual name used, of course, but for the
Xpurposes of a simple server, one name should suffice.
X
X*/
X
X`012
X
X/*
X  Message and file processing are handled via internal dispatching,
X ie, when the process wakes up, it calls a series  of  routines  to
X process  the  event  that  caused  the transition from HIB to CUR.
X Again, for simplicity in adding functions  in  the  future,  these
X tasks  are  defined  in a struct and dispatched much like a simple
X round-robin scheduler. It is the duty of  each  called  'task'  to
X determine if it needs to do any processing.`032
X  The same is done for timer initiated events, there is a queue for
X tasks  that  need  to  run  on  a  fixed  delta time. This list is
X currently only used for resetting the timer ast, but  is  included
X for  future  applications  where  it  may  be desirable to perform
X housekeeping funtions indepenant of external events.
X  In both cases, a parameter must be passed  to  the  called  task,
X this is to specify if the task is to perform initialization chores
X or if it is to perform it's normal funtions.`032
X
X Consider:
X
X`009while (1) `123
X`009  sys$hiber() ;
X`009  current = 0 ;
X`009  while ( hiber_tasks[current].task != 0 ) `123
X`009    hiber_tasks[current].task_status =
X`009    (*hiber_tasks[current].task) (PROCESS_PHASE) ;
X`009    current++ ;
X`009  `125 ;
X`009`125 ;
X
X  The  purpose  of  this  is  to  wait  until  an event awakens the
X process, then to call each routine in the HIBER_TASKS  list.  When
X this  is  complete, the process then hibernates again until awoken
X by some Jnet event, such as file or message arrival. Meanwhile, of
X course, a timer ast will trigger the same for the timer task list.
X
X*/
X
X
X
X#define INIT_PHASE 1
X#define PROCESS_PHASE 2
X
X#define MAXTASKS 2
X#define MAXTIMERS 2
X
Xint process_message(),process_file(),reset_timer(),watchdog() ;
X
Xstruct dispatch `123 int (*task) () ;
X`009`009  int task_status ;
X`009`009`125`032
X
X`009`009 hiber_tasks[MAXTASKS+1]  = `123 &process_message,0,
X`009`009`009`009`009      &process_file   ,0,
X`009`009`009`009`009      0,0
X`009`009`009`009`009    `125 ,
X
X`009`009 timer_tasks[MAXTIMERS+1] = `123 &reset_timer    ,0,
X`009`009`009`009`009      &watchdog`009      ,0,
X`009`009`009`009`009      0,0
X`009`009`009`009`009    `125 ;
X`009`009 `032
X
X
X
X
X#include`009<stdio.h>
X#include`009<opcdef>
X#include`009<stat>
X#include`009<ssdef>
X#include`009<rms>
X#include`009<time>
X#define`009then
X
X#define`009PACKAGE_NOTFOUND`0090
X#define PACKAGE_COMPLETED`0091
X#define PACKAGE_FNF`009`0092
X
X
Vextern char *getmsg(),*malloc(),*strchr() , *strcat() , *strcpy() , *tmpnam()
X ;
X       char *upcase(),*tranlog(),*generate_path(),*generate_mail_agent() ;
X       char *expand_name(),*strip(),*collapse(),*lowcase() ;
X       char *xmalloc() ;
X
Xstruct dsc `123
X`009`009int len ;
X`009`009char *addr ;
X`009   `125 ;
X
X
XFILE *infile ,*header_file ;
Xchar *list_name ;
Xchar *null_batch_params[] = `123 "","","","","","","","" `125 ;
Xint  requests_since_restart = 0 ;
Xstruct tm start_time ;
Xchar *start_time_string ;
X
X
X`012
X
Xmain(argc,argv)
Xint argc ;
Xchar *argv[] ;
X`123
X`009char *cp ;
X`009int current,mode ;
X
X`009mynode = strip(upcase(tranlog("JAN_LOCAL_NODE"))) ;
X`009if ( *( cp = tranlog(listserver_hook_name_logical) ) != '\0' ) `123
X`009  hook_name.dsc$a_pointer = cp ;
X`009  hook_name.dsc$w_length  = strlen( cp ) ;
X`009`125 ;`032
X`009listserver_hook_name = hook_name.dsc$a_pointer ;
X
X`009if ( *( cp = tranlog(listserver_table_name_logical) ) != '\0' ) `123
X`009  table_name.dsc$a_pointer = cp ;
X`009  table_name.dsc$w_length  = strlen( cp ) ;
X`009`125 ;`032
X`009listserver_table_name = table_name.dsc$a_pointer ;
X
X`009mode = 2 ;
X`009if ( jan_hook_init(&mode,&hook_name) == 0 ) return(0) ;
X
X`009generate_logicals() ;
X`009init_logfile() ;
X
X`009current = 0 ;
X`009while ( hiber_tasks[current].task != 0 )
X`009  (*hiber_tasks[current++].task) (INIT_PHASE) ;
X
X`009current = 0 ;
X`009while ( timer_tasks[current].task != 0 )
X`009  (*timer_tasks[current++].task) (INIT_PHASE) ;
X
X
X`009while (1) `123
X`009  sys$setast(1) ;
X`009  sys$hiber() ;
X`009  sys$setast(0) ;
X`009  current = 0 ;
X`009  while ( hiber_tasks[current].task != 0 ) `123
X`009    hiber_tasks[current].task_status =
X`009    (*hiber_tasks[current].task) (PROCESS_PHASE) ;
X`009    current++ ;
X`009  `125 ;
X`009`125 ;
X`125
X
X
X
Xscan_timerqueue()
X`123
X`009int current, status ;
X
X`009current = 0 ;
X`009while ( timer_tasks[current].task != 0 ) `123
X`009  timer_tasks[current].task_status =`032
X`009  (*timer_tasks[current].task) (PROCESS_PHASE) ;
X`009  current++ ;
X`009`125 ;
X`125
X
X`012
X
X
Xreset_timer(phase)
Xint phase ;
X`123
X
X`009int time_stamp() ;
X`009static struct dsc tim ;
X`009static unsigned int bintim[2], status ;
X
X`009if ( phase == INIT_PHASE ) `123
-+-+-+-+-+ End of part 1 +-+-+-+-+-
