Search

Saturday, November 19, 2016

DECNET: Connecting Two Digital DEC OpenVMS Servers on Different Internet Hosts to HECNET via a Single Bridge (Multi-Host DECNET Bridge Configuration for HECNET)


DECnet forever! My SIMH OpenVMS VAXen - QCOCAL (1.550) VAX Server 3900 Series in Washington DC and CLOUDY (1.551) VAX 11/780 in Kitchener, Ontario, Canada talk to the HECnet primary router MIM (1.13) - a real PDP-11 in Uppsala, Sweden running RSX-11M-PLUS and, through it, to numerous VAXen and PDPs across the world.


My first SIMH VAX Server 3900 series has been up now for almost a year. I call it "QCOCAL", in memory of a real VAX I used during my stint with Digital Equipment Corporation. The new QCOCAL lives inside a Centos 7 virtual machine on my DELL PowerEdge 2950 in the basement of our house in the Washington, DC metro area. It is connected to HECnet - the global hobbyist DECnet, using the DECnet bridge program written by Johnny Billquist.

Having recently procured a couple of Virtual Private Servers, I installed a second SIMH VAX-11/780 on one of them, calling the VAX "CLOUDY" (because it lives inside a cloud VPS). The VPS is hosted in a data-center in Kitchener, Ontario, Canada.

A view of just internet connectivity of the servers and the simulated VAXen looks like Diagram 1. The NICs of the Linux host servers are bridged and then tun/tap taps are used to connect the SIMH Vaxen. This is because the SIMH simulator grabs the entire configured NIC and we cannot really let it have the host's NIC all for itself (more information see "CHAPTER 3: Creating a TUN/TAP Pseudo Network Device and Bridging to the Host Network Interface").

Diagram 1 - internet connection schematic of two VAX servers to HECnet

To facilitate DECnet protocol communication, the DECnet Bridge program grabs DECnet packets from the ethernet taps (i.e. tap0, tap1), encapsulates them in UDP packets and sends them over the internet connections to be converted back into DECnet packets on the other side. Conceptually, it looks like diagram 2.

Diagram 2: DECnet Bridge connecting VAX Servers over Internet to HECnet 

Here is the network configuration of the SIMH host sanyalnet-openvms-vax.freeddns.org which is also LAN accessible as dormarth.sanyalnet.lan (CentOS 6) for QCOCAL:

[root@dormarth ~]# hostname
dormarth.sanyalnet.lan
[root@dormarth ~]# ip address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 08:00:27:a1:81:b6 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::a00:27ff:fea1:81b6/64 scope link
       valid_lft forever preferred_lft forever
3: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 500
    link/ether 5e:e0:9a:25:cc:41 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::5ce0:9aff:fe25:cc41/64 scope link
       valid_lft forever preferred_lft forever
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 08:00:27:a1:81:b6 brd ff:ff:ff:ff:ff:ff
    inet 10.42.2.2/24 brd 10.42.2.255 scope global br0
    inet6 fe80::a00:27ff:fea1:81b6/64 scope link
       valid_lft forever preferred_lft forever
[root@dormarth ~]# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
10.42.2.0       0.0.0.0         255.255.255.0   U         0 0          0 br0
0.0.0.0         10.42.2.1       0.0.0.0         UG        0 0          0 br0


and QCOCAL (OpenVMS 7.3) itself :


$ SHOW NETWORK /FULL

The following network services are available at this time:

Product:  DECnet                Manufacturer:  Digital Equipment Corporation
Node:  QCOCAL                   Address(es):  1.550
Network Type:  DNA V            Interface(s):  net 0

Node 0 
at 2016-11-19-23:45:48.385+00:00Iinf

Identifiers

    Name                              = LOCAL:.QCOCAL
    Address                           = 
       {
          (
          [ DNA_CMIP-MICE ] ,
          [ DNA_SessionControlV3 , number = 19 ] ,
          [ DNA_OSItransportV1 , 'DEC0'H ] ,
          [ DNA_OSInetwork , 49::00-01:AA-00-04-00-26-06:21 (LOCAL:.QCOCAL) ]
          ) ,
          (
          [ DNA_CMIP-MICE ] ,
          [ DNA_SessionControlV2 , number = 19 ] ,
          [ DNA_OSItransportV1 , 'DEC0'H ] ,
          [ DNA_IP , 0.0.0.0 ]
          ) ,
          (
          [ DNA_CMIP-MICE ] ,
          [ DNA_SessionControlV3 , number = 19 ] ,
          [ DNA_NSP ] ,
          [ DNA_OSInetwork , 49::00-01:AA-00-04-00-26-06:20 (LOCAL:.QCOCAL) ]
          )
       }

Status

    UID                               = 06E08000-DF79-11D4-8001-AA0004000104
    State                             = On
    Functions Enabled                 = 
       {
          Address Watcher ,
          CMIP Listener
       }
    ID                                = AA-00-27-FD-99-EC

Characteristics

    Version                           = T5.0.3
    Implementation                    = 
       {
          [
          Name = OpenVMS VAX ,
          Version = "V7.3    "
          ] ,
          [
          Name = Compaq DECnet-Plus for OpenVMS ,
          Version = "V7.3 30-DEC-2000 00:04:42.43"
          ]
       }
    Script Location                   = <Default value>
    Maximum Listeners                 = 0
    Listener Template                 = <Default value>
    Secondary Names                   = 
       {
       }

Counters

    Creation Time                     = 2016-05-14-17:20:11.690+00:00Iinf
    Renames                           = 8
    Changes of ID                     = 108
    IDROM Check Failures              = 0
    Changes of Address                = 0


Node 0 Session Control Port *
at 2016-11-19-23:45:49.115+00:00Iinf

command failed due to:
 no such object instance


Node 0 Session Control
at 2016-11-19-23:45:50.025+00:00Iinf

Counters

    Creation Time                     = 2016-11-19-09:42:57.390+00:00Iinf
    Access Control Violations         = 0
    Backtranslation Deletions         = 0
    Deleted Maintained Objects        = 0
    Dangling Links                    = 0
    Verification Failures             = 0


Product:  TCP/IP                Manufacturer:  Compaq Computer Corporation
Node:  sanyalnet-vax.sanyalnet.lan Address(es):  10.42.2.5
Network Type:  TCP/IP           Interface(s):   

  Compaq TCP/IP Services for OpenVMS VAX Version V5.1
  on a VAXserver 3900 Series running OpenVMS V7.3    

                              
                            Port                       Remote
Device_socket  Type    Local  Remote  Service           Host

  bg3         DGRAM      520       0                   *
  bg10        STREAM      21       0  FTP              *
  bg14        DGRAM      123       0  NTP              *
  bg15        DGRAM      123       0  NTP              *
  bg16        DGRAM      123       0  NTP              *
  bg25        STREAM      25       0  SMTP             *
  bg29        STREAM      23       0  TELNET           *
  bg54        DGRAM      750       0                   *
  bg55        DGRAM       88       0                   *
  bg57        STREAM     749       0                   *
  bg58        DGRAM      464       0                   *
  bg65        STREAM    3333       0  NOTES            *
  bg69        STREAM      80       0                   *
  bg2196      DGRAM    49883       0                   *
  bg2200      DGRAM    49885       0                   *
  bg4031      STREAM      23   53896  TELNET           10.100.0.1
  bg5686      STREAM      23   46942  TELNET           123.120.100.141

Communication Parameters

Local host:      sanyalnet-vax          Domain:   sanyalnet.lan

                                 Maximum     Current        Peak
Proxies                               20
  

Remote Terminal
  Large buffers:           0
  UCBs:                    0
  Virtual term:     disabled

Similarly, here is the Linux network configuration of the CentOS 7 server that hosts CLOUDY:

[root@sanyalnet-cloud-vps2 openvms]# ip address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP qlen 1000
    link/ether 00:50:56:a4:55:80 brd ff:ff:ff:ff:ff:ff
3: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP qlen 500
    link/ether 62:cb:23:2b:ad:77 brd ff:ff:ff:ff:ff:ff
4: tap1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP qlen 500
    link/ether be:61:88:db:42:78 brd ff:ff:ff:ff:ff:ff
5: tap2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN qlen 500
    link/ether c2:4b:67:23:11:5d brd ff:ff:ff:ff:ff:ff
6: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 00:50:56:a4:55:80 brd ff:ff:ff:ff:ff:ff
    inet 64.137.228.122/24 brd 64.137.228.255 scope global br0
       valid_lft forever preferred_lft forever
[root@sanyalnet-cloud-vps2 openvms]# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         64.137.228.1    0.0.0.0         UG        0 0          0 br0
64.137.228.0    0.0.0.0         255.255.255.0   U         0 0          0 br0


And the network configuration on CLOUDY itself:

$ SHOW NETWORK/FULL

The following network services are available at this time:

Product:  DECnet                Manufacturer:  Digital Equipment Corporation
Node:  CLOUDY                   Address(es):  1.551
Network Type:  DNA V            Interface(s):  net 0

Node 0 
at 2016-11-20-00:04:46.390+00:00Iinf

Identifiers

    Name                              = LOCAL:.CLOUDY
    Address                           = 
       {
          (
          [ DNA_CMIP-MICE ] ,
          [ DNA_SessionControlV3 , number = 19 ] ,
          [ DNA_OSItransportV1 , 'DEC0'H ] ,
          [ DNA_OSInetwork , 49::00-01:AA-00-04-00-27-06:21 (LOCAL:.CLOUDY) ]
          ) ,
          (
          [ DNA_CMIP-MICE ] ,
          [ DNA_SessionControlV2 , number = 19 ] ,
          [ DNA_OSItransportV1 , 'DEC0'H ] ,
          [ DNA_IP , 0.0.0.0 ]
          ) ,
          (
          [ DNA_CMIP-MICE ] ,
          [ DNA_SessionControlV3 , number = 19 ] ,
          [ DNA_NSP ] ,
          [ DNA_OSInetwork , 49::00-01:AA-00-04-00-27-06:20 (LOCAL:.CLOUDY) ]
          )
       }

Status

    UID                               = 06E08000-DF79-11D4-8001-AA0004002706
    State                             = On
    Functions Enabled                 = 
       {
          Address Watcher ,
          CMIP Listener
       }
    ID                                = 08-00-2B-80-15-C8

Characteristics

    Version                           = T5.0.3
    Implementation                    = 
       {
          [
          Name = OpenVMS VAX ,
          Version = "V7.3    "
          ] ,
          [
          Name = Compaq DECnet-Plus for OpenVMS ,
          Version = "V7.3 30-DEC-2000 00:04:42.43"
          ]
       }
    Script Location                   = <Default value>
    Maximum Listeners                 = 0
    Listener Template                 = <Default value>
    Secondary Names                   = 
       {
       }

Counters

    Creation Time                     = 2016-11-17-05:26:45.540+00:00Iinf
    Renames                           = 6
    Changes of ID                     = 23
    IDROM Check Failures              = 0
    Changes of Address                = 0


Node 0 Session Control Port SCL$PORT$12010012
at 2016-11-20-00:04:47.870+00:00Iinf

Identifiers

    Name                              = SCL$PORT$12010012

Status

    Client                            = Session Control Application 42
    Local End User Address            = number = 42
    Transport Port                    = NSP Port NSP$PORT_00010013
    Direction                         = Incoming
    Remote End User Address           = UIC = [0,0]SANYAL
    Node Name Sent                    = <Default value>
    Version Sent                      = V2
    Outgoing Network Priority         = 0
    Incoming Network Priority         = 0
    Process Identifier                = "00000113"

Counters

    Creation Time                     = 2016-11-20-00:04:07.930+00:00Iinf


Node 0 Session Control
at 2016-11-20-00:04:48.910+00:00Iinf

Counters

    Creation Time                     = 2016-11-19-01:40:49.410+00:00Iinf
    Access Control Violations         = 0
    Backtranslation Deletions         = 0
    Deleted Maintained Objects        = 0
    Dangling Links                    = 0
    Verification Failures             = 0


Product:  TCP/IP                Manufacturer:  Compaq Computer Corporation
Node:  sanyalnet-cloudy-vax.gama-digital.com Address(es):  64.137.228.85
Network Type:  TCP/IP           Interface(s):   

  Compaq TCP/IP Services for OpenVMS VAX Version V5.1
  on a VAX-11/780 running OpenVMS V7.3    

                              
                            Port                       Remote
Device_socket  Type    Local  Remote  Service           Host

  bg7         STREAM      21       0  FTP              *
  bg11        DGRAM      123       0  NTP              *
  bg12        DGRAM      123       0  NTP              *
  bg13        DGRAM      123       0  NTP              *
  bg16        STREAM      25       0  SMTP             *
  bg18        STREAM      23       0  TELNET           *

Communication Parameters

Local host:      sanyalnet-cloudy-vax   Domain:   gama-digital.com

                                 Maximum     Current        Peak
Proxies                               20
  

Remote Terminal
  Large buffers:           0
  UCBs:                    0
  Virtual term:     disabled


BRINGING IT ALL TOGETHER: DECnet BRIDGE SETUP

Diagram 3: HECnet multi-host bridge configuration:
Connecting two OpenVMS Servers over DECnet and over a single bridge to HECnet 
DECnet end-node QCOCAL (1:550) is hosted on sanyalnet-openvms-vax.freeddns.org which runs the DECnet bridge process in multi-host configuration, listening on port 4711 and bridging in
  1. HECnet itself via psilo.update.uu.se on port 4711, and
  2. sanyalnet-cloud-vps2.freeddns.org on port 4712 which runs it's own bridge to DECnet end-node CLOUDY (1.551).
The bridge process is launched with the command line "bridge -p 4711" specifying the listening port, and here is the bridge.conf configuration file:

! This is the bridge configuration file.
!
! Comments start with a '!'. Empty lines are ignored. The file
! is re-read on a SIGHUP.
!
! *************************************************************
!
! The bridge section defines all sources and destinations for
! this bridge program.
!
! Packets will not be accepted from other sources than these,
! and these destinations are used in the different options
! further down.
!
! If a name starts with tilde '~', that host is considered a passive
! host, and no packets will be transmitted to it unless packets are
! received from it. A timeout of 120 sec is used to consider the
! host active.
!
[bridge]
!<name> <ip>:<port>
! or
!<name> <etherdevice>
!
!vax tap0
!pdp tap2
!--
! Vax is on tap0, PDP is on tap2
! But both are tapping into br0
! So use br0, do not duplicate bridges
!--
vax-and-pdp br0
remote sanyalnet-openvms-vax.freeddns.org:4711
#update tempo.update.uu.se:4711
update psilo.update.uu.se:4711
!
! The DECnet section specify which bridges to send DECnet packets
! that appear on the local ethernet.
!
[decnet]
!<name>
!
!vax
vax-and-pdp
remote
update
!
! The LAT section specify which bridges to send LAT packets
! that appear on the local ethernet.
!
[lat]
!<name>
!
!vax
vax-and-pdp
remote
update

CLOUDY (1.551) is hosted on sanyalnet-cloud-vps2.freeddns.org which runs the DECnet bridge process listening on port 4712 and bridging to sanyalnet-openvms-vax.freeddns.org on port 4711 which in turn bridges in the HECnet network as well as QCOCAL. The DECnet bridge here is launched using the command line "bridge -p 4712" and the bridge.conf is simple:

! This is the bridge configuration file.
!
! Comments start with a '!'. Empty lines are ignored. The file
! is re-read on a SIGHUP.
!
! *************************************************************
!
! The bridge section defines all sources and destinations for
! this bridge program.
!
! Packets will not be accepted from other sources than these,
! and these destinations are used in the different options
! further down.
!
! If a name starts with tilde '~', that host is considered a passive
! host, and no packets will be transmitted to it unless packets are
! received from it. A timeout of 120 sec is used to consider the
! host active.
!
[bridge]
!<name> <ip>:<port>
! or
!<name> <etherdevice>
!
local tap0
remote sanyalnet-openvms-vax.freeddns.org:4711
!
! The DECnet section specify which bridges to send DECnet packets
! that appear on the local ethernet.
!
[decnet]
!<name>
!
local
remote
!
! The LAT section specify which bridges to send LAT packets
! that appear on the local ethernet.
!
[lat]
!<name>
!
local
remote
view raw bridge.conf hosted with ❤ by GitHub

DECnet forever!


Monday, November 14, 2016

OpenVMS Log Files Remote Logging to Unix/Linux SYSLOG Facility RSYSLOG

OpenVMS 7.3 on VAX logs on a remote Linux RSYSLOG syslog server
I gather all the logs I can from my many hobbyist servers and systems in a central place on one of my Virtual Private Servers running a rsyslog logger daemon on CentOS 7.

I wanted to add my QCOCAL hobbyist OpenVMS 7.3 VAX system logs to this central syslog server on my VPS.

Fortunately, all the work has already been done by Doug O'Neal from Homewood Academic Computing at Johns Hopkins University, whose SYSLOGD.C program pretty much worked out of the box.

The only tweak I made to Doug's SYSLOGD.C is to support a second OpenVMS Logical "SYSLOGD_PORT" to specify the UDP port number of my remote RSYSLOG Linux server, since I am not running it on the standard port (514). This is in addition to the "SYSLOGD_SERVER" Logical already supported by Doug's code.

Both Logicals need to be defined in the SYSTEM Logical Table LNM$SYSTEM_TABLE. Something like the following three lines in the OpenVMS startup file (SYS$MANAGER:SYSTARTUP_VMS.COM for my OpenVMS 7.3 VAX installation) suffice to start the VMS SYSLOG client at boot time;

$ define/system syslogd_server "64.137.248.212" ! IP address sanyalnet-cloud-vps.freeddns.org
$ define/system syslogd_port "65514"            ! UDP Port that remote syslogd is listening on
$ run/detached/process_name=syslogd/input=nl:/output=nl:/error=nl: DUA0:[TOOLS.SYSLOGD]SYSLOGD.EXE

Below is the SYSLOGD.C source code originally by Doug with the minor modifications by me. All credit to Doug O'Neal. This code compiles fine on my installation of Compaq C V6.4-005 on OpenVMS VAX V7.3 and I suspect it will on other versions, including OpenVMS ALPHA per Doug's comments at the top of the code. To build a binary,

$ CC  SYSLOGD
$ LINK  SYSLOGD

Some warning and informationals are generated by the compiler and linker, but nothing to stop SYSLOGD.EXE from being generated and used.

You can also download the source and OpenVMS VAX V7.3 binary executable from my FAL area on QCOCAL over HECNET or over the internet from QCOCAL served by WASD.

Making it secure


The OpenVMS SYSLOGD facility sends log content to the remote RSYSLOG server with no encryption, in cleartext over UDP. This is totally insecure - any rookie hacker could sniff the packets and learn a lot about what is going on with our OpenVMS server.

We need to make the transmission of the logs to the remote server secure.

Fortunately, I have recently setup a secure tunnel for logging to my remote central log server from my other hobbyist servers, as described in this post. This makes it really easy to secure OpenVMS log transmissions to the central server.

First, I identified a syslog server on the local LAN that is already configured as a secure tunnel (stunnel) client to my central log server. I decided to use the same Linux host (10.42.2.2) that is running the SIMH OpenVMS VAX for this purpose. It is directly and quickly accessible from the SIMH VAX (10.42.2.5) because the SIMH VAX network link is just a tun/tap bridge on the same server.

I opened up /etc/rsyslog.conf on this SIMH host Linux server, and uncommented the following lines to allow rsyslog to accept logger connections over network.

# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514

# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514

The TCP syslog reception port did not really need to be opened up for this rsyslog daemon to accept log entries over UDP from SYSLOGD.EXE on OpenVMS VAX, but may come in useful for later projects.

A restart of the rsyslog daemon on the Linux host is required after editing /etc/rsyslog.conf:

# service rsyslog restart

Then I logged into the OpenVMS VAX server and modified the OpenVMS SYSLOGD startup commands to point to the Linux SIMH host instead of the remote syslog server:

$ define/system syslogd_server "10.42.2.2"      ! IP address of the host this SIMH VAX is running on
$ define/system syslogd_port "514"              ! UDP Port of the host rsyslog server

SYSLOG then needs to be restarted on OpenVMS VAX:

$ show system
$ stop/id=<id of SYSLOGD>
$ run/detached/process_name=syslogd2vps/input=nl:/output=nl:/error=nl: DUA0:[TOOLS.SYSLOGD]SYSLOGD.EXE

Going back to the Linux host, an examination of the logs now reveals the VAX Server is sending logs here:

OpenVMS VAX SYSLOGD,EXE logging to rsyslog logger daemon running on it's own SIMH VAX linus host

And here is the fun part. Since this rsyslog daemon is already configured to use stunnel to send logs securely to the remote server, the logs from OpenVMS VAX are also forwarded to the remote syslogd daemon over the same secure tunnel.

Sure enough, checking my remote VPS central syslog server log, I see the OpenVMS VAX logs dutifully forwarded by the local SIMH host Linux box.

syslog entries on central rsyslog linux server from OpenVMS VAX forwarded by SIMH VAX Linux host over stunnel secure tunnel



/*
* syslogd.c
* Take OPCOM messages received over a set of pseduo-ttys and redirect
* them to a UNIX syslogd. Tested with Multinet and UCX software under
* VMS 1.5 & 6.1 (AXP) and VMS 5.5 & 6.0 (VAX).
*
* The chan structure defines the translation of the opcom classes to
* Unix facilities/priorities. The Unix server is defined via the
* logical name SYSLOGD_SERVER in the LNM$SYSTEM_TABLE logical name table.
* Either a host name or an IP address may be used.
*
* must be linked against either
* multinet:multinet_socket_library/share
* or
* sys$share:ucx$ipc_shr/share
*
* On an AXP system with UCX 3.1, /STANDARD=VAXC must be specified for CC.
*
* Doug O'Neal
* Homewood Academic Computing
* Johns Hopkins University
* doug@jhuvms.hcf.jhu.edu
*
* Modified by Supratim Sanyal (supratim at riseup.net):
* - 14-NOV-2016: Added logical name SYSLOGD_PORT to specify the port number of
* remote syslog server - required in addition to SYSLOGD_SERVER
* in the LNM$SYSTEM_TABLE logical name table.
* - 01-NOV-2017: Worked around ftname[retlen-1] which was crashing in EXE by
* HP C V7.3-009 on OpenVMS Alpha V8.3
* http://supratim-sanyal.blogspot.com/2016/11/openvms-log-files-remote-logging-to.html
*/
#define UCX 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <ssdef.h>
#include <dvidef.h>
#include <descrip.h>
#include <stsdef.h>
#include <lnmdef.h>
#include <iodef.h>
#include <opcdef.h>
#ifdef MULTINET
#include "multinet_root:[multinet.include.sys]types.h"
#include "multinet_root:[multinet.include.sys]socket.h"
#include "multinet_root:[multinet.include.netinet]in.h"
#include "multinet_root:[multinet.include]netdb.h"
#endif
#ifdef UCX
#include <types.h>
#include <socket.h>
#include <in.h>
#include <netdb.h>
#include <ucx$inetdef.h>
#endif
unsigned int PTD$CREATE();
unsigned int PTD$READ();
unsigned int PTD$READW();
unsigned int SYS$QIOW();
unsigned int SYS$EXPREG();
unsigned int SYS$GETDVIW();
unsigned int SYS$SNDOPR();
unsigned int SYS$TRNLNM();
unsigned int write_syslog();
int sockfd;
struct sockaddr_in cli_addr, serv_addr;
#define FT_DATA_MAX (unsigned short) 508
struct ft_buffer {
unsigned short status, count;
unsigned char data[FT_DATA_MAX];
};
struct iosb {
unsigned short condition, transfer_count;
unsigned long info;
};
// #define SERV_UDP_PORT 514
// #define SERV_UDP_PORT 65514
int SERV_UDP_PORT=514;
/*
* Facility codes
*/
#define LOG_KERN (0<<3) /* kernel messages */
#define LOG_USER (1<<3) /* random user-level messages */
#define LOG_MAIL (2<<3) /* mail system */
#define LOG_DAEMON (3<<3) /* system daemons */
#define LOG_AUTH (4<<3) /* security/authorization messages */
#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
#define LOG_LPR (6<<3) /* line printer subsystem */
#define LOG_NEWS (7<<3) /* netnews subsystem */
#define LOG_UUCP (8<<3) /* uucp subsystem */
#define LOG_CRON (15<<3) /* cron/at subsystem */
#define LOG_LOCAL0 (16<<3) /* reserved for local use */
#define LOG_LOCAL1 (17<<3) /* reserved for local use */
#define LOG_LOCAL2 (18<<3) /* reserved for local use */
#define LOG_LOCAL3 (19<<3) /* reserved for local use */
#define LOG_LOCAL4 (20<<3) /* reserved for local use */
#define LOG_LOCAL5 (21<<3) /* reserved for local use */
#define LOG_LOCAL6 (22<<3) /* reserved for local use */
#define LOG_LOCAL7 (23<<3) /* reserved for local use */
/*
* Priorities (these are ordered)
*/
#define LOG_EMERG 0 /* system is unusable */
#define LOG_ALERT 1 /* action must be taken immediately */
#define LOG_CRIT 2 /* critical conditions */
#define LOG_ERR 3 /* error conditions */
#define LOG_WARNING 4 /* warning conditions */
#define LOG_NOTICE 5 /* normal but signification condition */
#define LOG_INFO 6 /* informational */
#define LOG_DEBUG 7 /* debug-level messages */
struct {
unsigned short chan;
unsigned int class, priority;
struct ft_buffer *buffer;
} chan[] =
{ {0, OPC$M_NM_CENTRL|OPC$M_NM_REPLY, LOG_USER|LOG_NOTICE, 0},
{0, OPC$M_NM_PRINT|OPC$M_NM_CARDS, LOG_LPR|LOG_INFO, 0},
{0, OPC$M_NM_TAPES|OPC$M_NM_DISKS|OPC$M_NM_DEVICE, LOG_KERN|LOG_ERR, 0},
{0, OPC$M_NM_NTWORK, LOG_DAEMON|LOG_INFO, 0},
{0, OPC$M_NM_CLUSTER, LOG_KERN|LOG_CRIT, 0},
{0, OPC$M_NM_SECURITY, LOG_AUTH|LOG_WARNING, 0},
{0, OPC$M_NM_SOFTWARE|OPC$M_NM_LICENSE, LOG_KERN|LOG_WARNING, 0},
{0, OPC$M_NM_OPER1|OPC$M_NM_OPER2|OPC$M_NM_OPER3|OPC$M_NM_OPER4|
OPC$M_NM_OPER5|OPC$M_NM_OPER6|OPC$M_NM_OPER7|OPC$M_NM_OPER8|
OPC$M_NM_OPER9|OPC$M_NM_OPER10|OPC$M_NM_OPER11|OPC$M_NM_OPER12,
LOG_LOCAL0|LOG_INFO, 0}
};
#ifdef UCX
void bzero(c,length)
char *c; int length;
{
char *c1;
for (c1=c; length--; ) *c1++=0;
}
void bcopy(c1, c2, length)
char *c1, *c2; int length;
{
if (length==0 || c1==c2) return;
if (c1 > c2) {
for (;length--;) *c2++ = *c1++;
} else {
c1 += length;
c2 += length;
for (;length--;) *--c2 = *--c1;
}
}
#endif
main(argc, argv)
int argc; char *argv[];
{
unsigned int status, acmode, charbuff, buflen, astadr, astprm;
unsigned int ast_acmode, inadr[2], retlen;
unsigned short i;
unsigned int nchan, ichan;
struct {
unsigned short length, code;
unsigned long bufaddr, retlenaddr;
unsigned long zero;
} itemlist;
struct {
unsigned char class, type;
unsigned short width;
unsigned char basic[3], length;
unsigned int extended;
} term_char;
struct {
unsigned char type, enab[3];
unsigned int mask;
unsigned short ounit;
unsigned char str_length, string[16];
} msgbuf;
char ftname[64];
struct dsc$descriptor_s enable;
struct iosb iosb;
$DESCRIPTOR(tabnam,"LNM$SYSTEM_TABLE");
$DESCRIPTOR(syslog_host,"SYSLOGD_SERVER");
$DESCRIPTOR(syslog_port,"SYSLOGD_PORT");
char serv_host_name[255];
char serv_port[255];
struct hostent *serv_host_addr;
nchan = sizeof chan / sizeof chan[0];
memset(ftname,0,sizeof(ftname));
/*
* Set up the UDP connection to the syslog server
*/
/*
* Fill in the structure "serv_addr" with the address of the
* server that we want to send to.
*/
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
/*
* first, check that we can get the IP address of the syslogd server
*/
itemlist.length = sizeof(serv_host_name);
itemlist.code = LNM$_STRING;
itemlist.bufaddr = serv_host_name;
itemlist.retlenaddr = &retlen;
itemlist.zero = 0;
status = SYS$TRNLNM(0,&tabnam,&syslog_host,0,&itemlist);
if (!($VMS_STATUS_SUCCESS(status))) {
fprintf(stderr,"Cannot translate logical name %s in table %s\n",syslog_host.dsc$a_pointer,tabnam.dsc$a_pointer);
exit (status);
}
serv_host_addr=gethostbyname(serv_host_name);
if (!serv_host_addr) {
serv_addr.sin_addr.s_addr = inet_addr(serv_host_name);
if (serv_addr.sin_addr.s_addr == -1) {
fprintf(stderr,"Cannot resolve name %s\n",serv_host_name);
exit (1);
}
} else {
bcopy(serv_host_addr->h_addr, (char *) &serv_addr.sin_addr,
serv_host_addr->h_length);
}
/*
* then, check that we can get the port number of the syslogd server
*/
itemlist.length = sizeof(serv_port);
itemlist.code = LNM$_STRING;
itemlist.bufaddr = serv_port;
itemlist.retlenaddr = &retlen;
itemlist.zero = 0;
status = SYS$TRNLNM(0,&tabnam,&syslog_port,0,&itemlist);
if (!($VMS_STATUS_SUCCESS(status))) {
fprintf(stderr,"Cannot translate logical name %s in table %s\n",syslog_port.dsc$a_pointer,tabnam.dsc$a_pointer);
exit (status);
}
SERV_UDP_PORT=atoi(serv_port);
if(0==SERV_UDP_PORT) {
fprintf(stderr,"Cannot translate port number from logical %s\n",syslog_host.dsc$a_pointer);
exit (1);
}
serv_addr.sin_port = htons(SERV_UDP_PORT);
/*
* Open a UDP socket (an Internet datagram socket).
*/
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("client: can't open datagram socket\n");
exit (1);
}
/*
* Bind any local address for us.
*/
bzero((char *) &cli_addr, sizeof(cli_addr)); /* zero out */
cli_addr.sin_family = AF_INET;
cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
cli_addr.sin_port = htons(0);
if (bind(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0) {
perror("client: can't bind local address\n");
exit (1) ;
}
/*
* set up a pseudoterminal device for each operator class defined
* and enable that device through opcom
*/
for (ichan=0; ichan<nchan; ichan++) {
/* set aside memory for the pty device */
acmode = 0;
charbuff = 0;
buflen = 0;
astadr = 0;
astprm = 0;
ast_acmode = 0;
status = SYS$EXPREG(1,inadr,0,0);
if (!($VMS_STATUS_SUCCESS(status))) exit (status);
/* create the pty device */
chan[ichan].buffer = inadr[0];
status = PTD$CREATE(&chan[ichan].chan, acmode, charbuff, buflen, astadr,
astprm, ast_acmode, inadr);
if (!($VMS_STATUS_SUCCESS(status))) exit (status);
/* set the pty device to maximum page width, infinite page length */
status = SYS$QIOW(0, chan[ichan].chan, IO$_SENSECHAR, &iosb, 0, 0,
&term_char, sizeof(term_char), 0, 0, 0, 0);
if (!($VMS_STATUS_SUCCESS(status))) exit (status);
term_char.width=511;
term_char.length=0;
status = SYS$QIOW(0, chan[ichan].chan, IO$_SETCHAR, &iosb, 0, 0,
&term_char, sizeof(term_char), 0, 0, 0, 0);
if (!($VMS_STATUS_SUCCESS(status))) exit (status);
/* get the pty device name */
itemlist.length = sizeof(ftname);
itemlist.code = DVI$_FULLDEVNAM;
itemlist.bufaddr = ftname;
itemlist.retlenaddr = &retlen;
itemlist.zero = 0;
status = SYS$GETDVIW(0,chan[ichan].chan,0,&itemlist,0,0,0,0);
if (!($VMS_STATUS_SUCCESS(status))) exit (status);
/* ftname[retlen-1]='\0'; -- This crashes on OpenVMS 8.3 Alpha, memsetting this at declaration above - Supratim Sanyal 01-NOV-201
7 */
msgbuf.type = OPC$_RQ_TERME;
msgbuf.enab[0] = 1;
msgbuf.mask = chan[ichan].class;
for (i=retlen-2; i>0; i--) {
if ((ftname[i] >= 'A') && (ftname[i] <= 'Z')) {
msgbuf.ounit = (short) atoi(&ftname[i+1]);
ftname[i+1] = '\0';
break;
}
}
msgbuf.str_length = strlen(ftname);
strncpy(msgbuf.string,ftname,msgbuf.str_length);
enable.dsc$w_length = sizeof(msgbuf);
enable.dsc$b_dtype = DSC$K_DTYPE_T;
enable.dsc$b_class = DSC$K_CLASS_S;
enable.dsc$a_pointer = &msgbuf;
status = SYS$SNDOPR(&enable,0);
if (!($VMS_STATUS_SUCCESS(status))) exit (status);
}
/*
* Now set up async reads to each channel. As various opcom messages come
* in, the appropriate ast will fire and the message logged. Another read
* will then be queued.
*/
for (ichan=0; ichan<nchan; ichan++) {
status = PTD$READ(0, chan[ichan].chan, &write_syslog, ichan,
chan[ichan].buffer, FT_DATA_MAX);
if (!($VMS_STATUS_SUCCESS(status))) exit (status);
}
status = SYS$HIBER();
exit(status);
}
unsigned int write_syslog(ichan)
unsigned int ichan;
{
unsigned int i;
char header[1024], buffer[512], *c1;
time_t now;
(void) SYS$SETAST(0); /* block new ast's */
time(&now);
c1 = buffer;
for (i=0; i<=chan[ichan].buffer->count; i++) {
if (chan[ichan].buffer->data[i]=='\015') { /* CR delimited */
*c1 = '\0';
sprintf(header,"<%d>%.15s [OPCOM] ", chan[ichan].priority,
(ctime(&now)+4));
strcat(header,buffer);
sendto(sockfd, header, strlen(header), 0, &serv_addr,
sizeof serv_addr);
c1 = buffer;
} else if (isprint(chan[ichan].buffer->data[i])) {
*c1 = chan[ichan].buffer->data[i];
c1++;
}
}
/* queue a new read */
(void) PTD$READ(0, chan[ichan].chan, &write_syslog, ichan,
chan[ichan].buffer, FT_DATA_MAX);
(void) SYS$SETAST(1); /* re-enable ast's */
return(0);
}
view raw SYSLOGD.C hosted with ❤ by GitHub

Friday, November 11, 2016

Yet another OpenVMS DCL Command Procedure to Crawl and Report HECNET the Hobbyist DECNET in HTML served by WASD - OpenVMS VAX 7.3

"What is HECnet?

HECnet is a DECnet that connects different people who play around with different machines that have the DECnet protocol suite. The network should not be regarded as a serious networking setup, nor should it be expected to work 24/7. It's a hobby project between people who think it's fun to create a DECnet network.

HECnet is basically a DECnet phase IV network. Currently, the main router is a PDP-11 running RSX-11M-PLUS. The machine is located in Uppsala, Sweden.

The connectivity between nodes can be anything that works. The current connectivity is with an ethernet bridge between sites, DECnet over IP using Multinet on VMS or RSX, and DECnet over IP on Cisco. Other solutions that have been used are a virtual serial async. connection talking DDCMP. Other possibilities are GRE and DECnet over IP." - read more at http://www.update.uu.se/~bqt/hecnet.html

DECNET Architecture Network Stack

A DCL command procedure to copy over the latest list of HECNET nodes. Execute this using
$ @HECNET-NODENAMES-UPDATE.COM

$! Runs at 5 AM system time every day to copy nodenames.dat from MIM:: to DUA2:[FAL$SERVER]
$ set noon
$ mynameis = f$environment("PROCEDURE")
$ goto 'f$mode()'
$interactive:
$ on warning then goto submit_error
$ submit /after="tomorrow+5:00"/noprint/keep 'mynameis'
$ write sys$output "Periodic job has been requeued"
$ exit
$network:
$other:
$ write sys$output "Unable to process commands in this mode"
$ exit
$submit_error:
$ set noon
$! mail nla0: system /subject="Nightly batch job has encountered an error"
$ exit
$batch:
$ on warning then goto submit_error
$ submit /after="tomorrow+5:00"/noprint/keep 'mynameis'
$ set noon
$! now for what we were created for, include the DCL commands to execute daily
$!
$ set proc/priv=all
$ copy mim::nodenames.dat dua2:[fal$server]
$ exit

The DCL script HECNET-SCAN.COM to crawl HECNET and generate the HTML pages. You can run this by itself for testing, or invoke this periodically (once a day or once a week) from a scheduled batch queue job.

$! SET NOVERIFY
$ SET NOON
$ ON CONTROL_Y THEN GOTO ERR_EXIT
$!
$! -----------------------
$! HECNET-SCAN.COM
$!
$! READS LIST OF HECnet NODES, CREATES HTML FILES CONTAINING LIST, AND DETAILED STATUS OF INDIVIDUAL REACHABLE NODES
$! SEE THE FOLLOWING URL FOR OUTPUT OF THIS PROCEDURE:
$! http://sanyalnet-openvms-vax.freeddns.org:82/falserver/hecnet-status.html
$!
$! CONFIGURATION:
$!
$! NODENAME_DAT_FILE: FULL PATH AND FILENAME OF HECnet NODES LIST (MAINTAINED ON MIM:: (1.13) BY JOHNNY)
$!
$! OUTPUT_HTML: FULL PATH AND FILENAME OF HECnet NODE SUMMARY LIST INDEX FILE; THIS FILE LINKS TO SEPARATE FILES PER REACHABLE NODE
$!
$! NODEDETAIL_DIR: DIRECTORY WHERE INDIVIDUAL NODE DETAILS HTML FILES WILL BE PLACED (FILENAMES ARE GENERATED BY THE SCRIPT)
$!
$! NODEDETAIL_DIR_URI_BASE: URI OF DIRECTORY OF NODE DETAILS FILES AS SERVED BY WEB-SERVER; FILENAMES OF NODE DETAIL FILES WILL
$! BE GENERATED AND APPENDED TO THIS BY THE SCRIPT WHEN GENERATING THE HTML FILES
$!
$! HECNET_TEST_NODE: DECNET ADDRESS OF HECnet NODE TO TEST FOR HECnet ACCESSIBLILITY. IF THIS NODE IS UNREACHABLE, SCRIPT DOES NOTHING AND EXITS.
$!
$! VERSION HISTORY
$!
$! NOV 11, 2016: REV 1.0 INITIAL RELEASE
$! NOV 13, 2016: REV 1.1 ADDED VIEWPORT,FAVICON IN HTML HEAD
$! NOV 17, 2016: REV 1.2 ADDED FREEFIND.COM SITE SEARCH BOX
$! NOV 27, 2016: REV 2.0 ADDED SUPPORT FOR PHASE IV AND PHASE V OSI NODES
$! MAKE NODE-SPECIFIC URLS LOWERCASE
$! DEC 02, 2016: REV 2.1 SPECIFY GNU AGPLv3 LICENSE
$! SEP 26, 2017: REV 2.2 ADD DESCRIPTION IN HEAD
$! NOV 19, 2017: REV 2.3 ADD BREADCRUMBS
$! FEB 10, 2019: REV 2.4 ADD CANONICAL URL, ADJACENT NODES
$! MAR 07, 2019: REV 2.5 USE NCP LOOP FOR INITIAL REACHABLE TEST
$! USE NCP SHOW EXEC STATUS TO TRY TO IDENTIFY
$! PHASE IV OR V, OR CISCO ROUTERS WITH NO NML OBJECT
$!
$! (C) SUPRATIM SANYAL <SUPRATIM AT RISEUP DOT NET>
$! FREELY USABLE AND REDISTRIBUTABLE UNDER GNU AGPLv3
$! LICENSE: http://tuklusan.decsystem.org/agpl-3.0-standalone.html
$! -----------------------
$!
$! -- START CONFIGURATION
$! NODENAME_DAT_FILE="DUA1:[SANYAL.MISC]x.dat"
$ NODENAME_DAT_FILE="DUA2:[FAL$SERVER]NODENAMES.DAT"
$ OUTPUT_HTML="DUA2:[FAL$SERVER]HECNET-STATUS.HTML"
$ NODEDETAIL_DIR="DUA2:[FAL$SERVER.HECNET-NODE-DETAILS]"
$ NODEDETAIL_DIR_URI_BASE="/falserver/hecnet-node-details"
$ HECNET_TEST_NODE="1.13" ! MIM::
$! -- END CONFIGURATION
$!
$!
$ TEMPFILE_UNREACHABLE="SYS$SCRATCH:HECNET-SCAN-NOK.TMP"
$ TEMPFILE_REACHABLE="SYS$SCRATCH:HECNET-SCAN-OK.TMP"
$ LOCALNODENAME=F$GETSYI("NODENAME")
$ LOCALAREA=F$GETSYI("NODE_AREA")
$ LOCALNODE=F$GETSYI("NODE_NUMBER")
$ LOCALHOST="''LOCALAREA'.''LOCALNODE'"
$ NCP="MCR NCP"
$ NCL="MCR NCL"
$!
$! IF TEST NODE IS UNREACHABLE HECNET IS DOWN OR UNREACHABLE, DO NOTHING IN THAT CASE
$! TEST NODE IS PHASE IV - USE NCP
$ NCP TELL 'HECNET_TEST_NODE' SHOW NODE 'HECNET_TEST_NODE' STATUS
$ NCPSTAT=$STATUS
$ IF NCPSTAT .NE. %X10000001
$ THEN
$ WRITE SYS$OUTPUT "%HECNET-E-UNREACHABLE HECNET SEEMS TO BE UNREACHABLE, EXITING."
$ WRITE SYS$ERROR "%HECNET-E-UNREACHABLE HECNET SEEMS TO BE UNREACHABLE, EXITING."
$ EXIT
$ ENDIF
$!
$!
$ OPEN/READ/ERROR=ERR_EXIT NODENAMES 'NODENAME_DAT_FILE'
$ OPEN/WRITE/ERROR=ERR_EXIT TEMPFILEOK 'TEMPFILE_REACHABLE'
$ OPEN/WRITE/ERROR=ERR_EXIT TEMPFILENOK 'TEMPFILE_UNREACHABLE'
$ OPEN/WRITE/ERROR=ERR_EXIT OUTPUTHTML 'OUTPUT_HTML'_TMP
$!
$ WRITE OUTPUTHTML F$FAO("<HTML><HEAD><TITLE>VIEW OF HECnet FROM !AS (!AS) AT !%D</TITLE><META NAME=""AUTHOR"" CONTENT=""SUPRATIM SANYAL (SUPRATIM AT RISEUP DOT NET)""><link rel=""stylesheet"" href=""/styles/styles.css"">",LOCALNODENAME,LOCALHOST,0)
$ WRITE OUTPUTHTML F$FAO("<link rel=""canonical"" href=""http://sanyalnet-openvms-vax.freeddns.org:82/falserver/hecnet-status.html"">")
$ WRITE OUTPUTHTML F$FAO("<link rel=""shortcut icon"" href=""/favicon.ico""><link rel=""icon"" href=""/favicon.ico""><meta name=""viewport"" content=""initial-scale=1"">")
$ WRITE OUTPUTHTML "</HEAD><BODY>"
$!
$! Breadcrumb
$ WRITE OUTPUTHTML "<p><a href=""/"">QCOCAL VAX</a>&nbsp;&raquo;&nbsp;<a href=""/falserver/hecnet-status.html"">HECnet</a></p>"
$!
$ WRITE OUTPUTHTML F$FAO("<P><IMG WIDTH="260" HEIGHT="162" SRC=""/qcocal-logo.jpg"" ALT=""QCOCAL DIGITAL DEC OPENVMS VAX SANYALnet HOBBYIST SERVER VAXserver 3900 Series with OPENVMS 7.3 Operating System""></P><P></P>")
$ WRITE OUTPUTHTML F$FAO("<H1>VIEW OF HECnet FROM !AS (!AS)</H1><H2>!%D</H2>",LOCALNODENAME,LOCALHOST,0)
$!
$ WRITE OUTPUTHTML "<p>Search for HECnet Nodes and More on this server:</p><!-- freefind.com http://sanyalnet-openvms-vax.freeddns.org:82/ freefindcom1 at tuklusan dot 33mail dot com -->"
$ WRITE OUTPUTHTML "<!-- start of freefind search box html --><table cellpadding=0 cellspacing=0 border=0 ><tr><td style=""font-family: Arial, Helvetica, sans-serif; font-size: 7.5pt;"">"
$ WRITE OUTPUTHTML "<center><table width=""90%"" cellpadding=0 cellspacing=0 border=0 style=""font-family: Arial, Helvetica, sans-serif; font-size: 7.5pt;"" ><tr>"
$ WRITE OUTPUTHTML "<td style=""font-family: Arial, Helvetica, sans-serif; font-size: 7.5pt;"" align=left ><a href=""http://search.freefind.com/siteindex.html?si=74775162"">index</a></td>"
$ WRITE OUTPUTHTML "<td style=""font-family: Arial, Helvetica, sans-serif; font-size: 7.5pt;"" align=center><a href=""http://search.freefind.com/find.html?si=74775162&amp;m=0&amp;p=0"">sitemap</a></td>"
$ WRITE OUTPUTHTML "<td style=""font-family: Arial, Helvetica, sans-serif; font-size: 7.5pt;"" align=right><a href=""http://search.freefind.com/find.html?si=74775162&amp;pid=a"">advanced</a></td>"
$ WRITE OUTPUTHTML "</tr></table></center><form style=""margin:0px; margin-top:4px;"" action=""http://search.freefind.com/find.html"" method=""get"" accept-charset=""utf-8"" target=""_self"">"
$ WRITE OUTPUTHTML "<input type=""hidden"" name=""si"" value=""74775162""><input type=""hidden"" name=""pid"" value=""r""><input type=""hidden"" name=""n"" value=""0""><input type=""hidden"" name=""_charset_"" value="""">"
$ WRITE OUTPUTHTML "<input type=""hidden"" name=""bcd"" value=""&#247;""><input type=""text"" name=""query"" size=""32"">"
$ WRITE OUTPUTHTML "<input type=""submit"" value=""search""></form></td></tr><tr>"
$ WRITE OUTPUTHTML "<td style=""text-align:center; font-family: Arial, Helvetica, sans-serif;font-size: 7.5pt; padding-top:4px;"">"
$ WRITE OUTPUTHTML "<a style=""text-decoration:none; color:gray;"" href=""http://www.freefind.com"" >site search</a><a style=""text-decoration:none; color:gray;"" href=""http://www.freefind.com"" > by"
$ WRITE OUTPUTHTML "<span style=""color: #606060;"">freefind</span></a></td></tr></table><!-- end of freefind search box html -->"
$!
$ WRITE TEMPFILEOK F$FAO("<H2>REACHABLE HECnet NODES</H2><OL>")
$ WRITE TEMPFILENOK F$FAO("<H2>UNREACHABLE HECnet NODES</H2><OL>")
$!
$! Skip over first four heading lines
$ READ/END_OF_FILE=NODELIST_EXIT NODENAMES LINE
$ READ/END_OF_FILE=NODELIST_EXIT NODENAMES LINE
$ READ/END_OF_FILE=NODELIST_EXIT NODENAMES LINE
$ READ/END_OF_FILE=NODELIST_EXIT NODENAMES LINE
$!
$Disk_ReadLoop:
$ READ/END_OF_FILE=NODELIST_EXIT NODENAMES LINE
$!1.2 ERNIE
$ DECNETADDR=F$EDIT(F$EXTRACT(0,12,LINE),"TRIM,COMPRESS")
$ NODENAME=F$EDIT(F$EXTRACT(12,6,LINE),"TRIM,COMPRESS")
$!
$ IF DECNETADDR .EQS. LOCALHOST
$ THEN
$ GOTO Disk_ReadLoop ! SKIP THIS LOCALHOST
$ ENDIF
$
$! -- START OLD CODE --
$! DECNET_PHASE=0
$!! TRY PHASE IV NCP
$!! NCP TELL 'DECNETADDR' SHOW NODE 'DECNETADDR' STATUS ! Does not work on DOS NML V5.0.001 (on WFW311)
$! NCP TELL 'DECNETADDR' SHOW EXECUTOR SUMMARY
$! NCPSTAT=$STATUS
$! IF NCPSTAT .EQ. %X10000001
$! THEN
$! DECNET_PHASE=4
$! ELSE
$!! TRY PHASE V OSI NCL
$! NCL SHOW NODE 'DECNETADDR'
$! NCPSTAT=$STATUS
$! IF NCPSTAT .EQ. %X10000001
$! THEN
$! DECNET_PHASE=5
$! ENDIF
$! ENDIF
$! IF DECNET_PHASE .EQ. 0
$! -- END OLD CODE --
$
$! TRY A LOOP COMMAND; IF RESULT IS ANYTHING EXCEPT "%SYSTEM-F-UNREACHABLE" ASSUME NODE IS REACHABLE
$ PIPE (NCP LOOP NODE 'DECNETADDR') | SEARCH SYS$INPUT "%SYSTEM-F-UNREACHABLE"
$ NCPSTAT=$STATUS ! SEARCH RESULT: %X10000001 = SUCCESS, %X18D78053 = FAILED
$ IF NCPSTAT .EQ. %X10000001 ! NODE IS UNREACHABLE
$ THEN
$ NODESTATUS=F$FAO("<LI><PRE>!6AS !7AS UNREACHABLE</PRE></LI>", NODENAME, DECNETADDR)
$ WRITE TEMPFILENOK "''NODESTATUS'"
$ ELSE ! IS REACHABLE
$! TRY TO FIGURE OUT IF THIS IS A PHASE-IV, PHASE-V or CISCO ROUTER NODE
$ DECNET_PHASE=0
$ NCP TELL 'DECNETADDR' SHOW EXECUTOR STATUS
$ NCPSTAT=$STATUS
$ IF NCPSTAT .EQ. %X10000001 ! PHASE-IV NODE
$ THEN
$ DECNET_PHASE=4
$ ELSE
$ IF NCPSTAT .EQ. %X11F88800 ! PROBABLY A PHASE-V NODE
$ THEN
$ DECNET_PHASE=5
$ ELSE
$ IF NCPSTAT .EQ. %X11F8807A ! NO NML OBJECT - PROBABLY CISCO ROUTER
$ THEN
$ DECNET_PHASE=9
$ ENDIF
$ ENDIF
$ ENDIF
$!
$ CALL GET_NODE_INFO 'DECNETADDR' 'NODENAME' 'DECNET_PHASE'
$!
$ ENDIF
$!
$ GOTO Disk_ReadLoop
$!
$NODELIST_EXIT:
$ CLOSE NODENAMES
$!
$ WRITE TEMPFILEOK "</OL><P></P>"
$!
$ WRITE TEMPFILENOK "</OL><P></P><H2>HECnet</H2>"
$ WRITE TEMPFILENOK "<P>HECnet is the oldest world-wide hobbyist DECnet network connecting people who play around with different machines that have the DECnet protocol suite. "
$ WRITE TEMPFILENOK "Visit the <A HREF=""http://www.update.uu.se/~bqt/hecnet.html"" TARGET=""_BLANK"">HECnet Official Website</A>.</P>"
$!
$! START GOOGLE CSE SEARCH BOX
$ WRITE TEMPFILENOK "<p></p><p>Search SANYALNET Hobbyist Servers and Services</p><div id=""google-cse""><!-- Google Custom Search via sanyal.duckdns.org.openvms.vax at gmail --><script>"
$ WRITE TEMPFILENOK F$FAO("(function() { var cx = '015567988034387983255:4ulgqks3d_a'; var gcse = document.createElement('script'); gcse.type = 'text/javascript'; gcse.async = true;")
$ WRITE TEMPFILENOK F$FAO(" gcse.src = 'https://cse.google.com/cse.js?cx=' + cx; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gcse, s); })(); </script>")
$ WRITE TEMPFILENOK F$FAO(" <gcse:search></gcse:search></div><p></p>")
$! END GOOGLE CSE SEARCH BOX
$!
$ WRITE TEMPFILENOK "<P>Proudly generated by a DCL Command Procedure and served by WASD Web Server from a Digital DEC VAXserver 3900 Series computer running OpenVMS VAX 7.3 Operating System.</P>"
$ WRITE TEMPFILENOK "<P>&copy; SUPRATIM SANYAL (<A HREF=""https://goo.gl/FqzyBW"" TARGET=""_BLANK"">EMAIL</A>)"
$ WRITE TEMPFILENOK " (<A HREF=""http://supratim-sanyal.blogspot.com/"" TARGET=""_BLANK"">BLOG</A>)"
$ WRITE TEMPFILENOK " (<A HREF=""http://www.sanyal.org/"" TARGET=""_BLANK"">Website</A>)"
$ WRITE TEMPFILENOK "</P><P><A HREF=""/"">HOME</A></P>"
$ WRITE TEMPFILENOK "<!-- McAfee SECURE Certification --><script type=""text/javascript"" src=""https://cdn.ywxi.net/js/1.js"" async></script></BODY></HTML>"
$!
$ CLOSE TEMPFILENOK
$ CLOSE TEMPFILEOK
$!
$ CLOSE OUTPUTHTML
$ APPEND 'TEMPFILE_REACHABLE' 'OUTPUT_HTML'_TMP
$ APPEND 'TEMPFILE_UNREACHABLE' 'OUTPUT_HTML'_TMP
$ COPY/NOLOG/NOCONF 'OUTPUT_HTML'_TMP 'OUTPUT_HTML'
$!
$ SET FILE/PROT=(W:R) 'OUTPUT_HTML'
$ PURGE/KEEP=2 'OUTPUT_HTML'_TMP
$ PURGE/KEEP=2 'OUTPUT_HTML'
$ DELETE/NOLOG/NOCONF 'TEMPFILE_REACHABLE';*
$ DELETE/NOLOG/NOCONF 'TEMPFILE_UNREACHABLE';*
$ EXIT
$!
$ERR_EXIT:
$! Close files just in case they are still open
$ CLOSE OUTPUTHTML
$ CLOSE TEMPFILENOK
$ CLOSE TEMPFILEOK
$ CLOSE NODENAMES
$ CLOSE TEMPDETAILFILE
$ EXIT
$!
$! ---------------------------------
$GET_NODE_INFO:
$ SUBROUTINE
$! ---------------------------------
$!
$! Parameters: P1=REMOTE DECNET ADDRESS (X.Y), P2=REMOTE DECNET NODENAME, P3=REMOTE DECNET PHASE: 4 OR 5, OR 9=NO NML(CISCO SWITCH?)
$!
$ SET NOON
$!
$ REMOTE_DECNET_AREA=F$ELEMENT(0,".",P1)
$ REMOTE_DECNET_NODENUM=F$ELEMENT(1,".",P1)
$ REMOTE_DECNET_PHASE=P3
$!
$ NODEDETAIL_URL=F$FAO("!AS/!AS_!AS-!AS.html",NODEDETAIL_DIR_URI_BASE, REMOTE_DECNET_AREA, REMOTE_DECNET_NODENUM, F$EDIT(P2,"TRIM,LOWERCASE")) ! MUST BE SAME FILENAME AS NODEDETAIL_FILE THREE LINES BELOW
$ NODESTATUS=F$FAO("<LI><PRE>!6AS !7AS <A HREF=""""!AS"""" TARGET=""""_BLANK"""">DECnet DETAILS</A></PRE></LI>",P2,P1,NODEDETAIL_URL)
$ WRITE TEMPFILEOK "''NODESTATUS'"
$!
$ NODEDETAIL_FILE=F$FAO("!AS!AS_!AS-!AS.html",NODEDETAIL_DIR, REMOTE_DECNET_AREA, REMOTE_DECNET_NODENUM, F$EDIT(P2,"TRIM,LOWERCASE"))
$!
$ OPEN/WRITE/ERROR=SUB_EXIT TEMPDETAILFILE 'NODEDETAIL_FILE'
$!
$ WRITE TEMPDETAILFILE F$FAO("<HTML><HEAD><link rel=""stylesheet"" href=""/styles/styles.css"">")
$ WRITE TEMPDETAILFILE F$FAO("<TITLE>OPENVMS VAX DECNET | HECnet NODE !AS (!AS) REPORT FROM !AS (!AS) DIGITAL DEC VAXserver 3900</TITLE><META NAME=""AUTHOR"" CONTENT=""SUPRATIM SANYAL (SUPRATIM AT RISEUP DOT NET)"">",P2,P1,LOCALNODENAME,LOCALHOST)
$ WRITE TEMPDETAILFILE F$FAO("<META NAME=""DESCRIPTION"" CONTENT=""DECnet node information reported by !AS (!AS) to !AS (!AS) Digital DEC VAX VAXserver 3900 running OpenVMS 7.3 operating system over HECnet"">",P2,P1,LOCALNODENAME,LOCALHOST)
$ WRITE TEMPDETAILFILE F$FAO("<link rel=""shortcut icon"" href=""/favicon.ico""><link rel=""icon"" href=""/favicon.ico""><meta name=""viewport"" content=""initial-scale=1""></HEAD><BODY>")
$!
$! Breadcrumb
$ WRITE TEMPDETAILFILE "<p><a href=""/"">QCOCAL VAX</a>&nbsp;&raquo;&nbsp;<a href=""/falserver/hecnet-status.html"">HECnet</a>&nbsp;&raquo;&nbsp;"
$ WRITE TEMPDETAILFILE "<a href=""''NODEDETAIL_URL'"">''P2' (''P1')</a></p>"
$!
$!
$ WRITE TEMPDETAILFILE F$FAO("<P><IMG WIDTH="260" HEIGHT="162" SRC=""/qcocal-logo.jpg"" ALT=""QCOCAL DIGITAL DEC OPENVMS VAX SANYALNET HOBBYIST SERVER VAXserver 3900 Series with OPENVMS 7.3 Operating System""></P>")
$!
$ WRITE TEMPDETAILFILE "<p>Search for HECnet Nodes and More on this server:</p><!-- freefind.com http://sanyalnet-openvms-vax.freeddns.org:82/ freefindcom1 at tuklusan dot 33mail dot com -->"
$ WRITE TEMPDETAILFILE "<!-- start of freefind search box html --><table cellpadding=0 cellspacing=0 border=0 ><tr><td style=""font-family: Arial, Helvetica, sans-serif; font-size: 7.5pt;"">"
$ WRITE TEMPDETAILFILE "<center><table width=""90%"" cellpadding=0 cellspacing=0 border=0 style=""font-family: Arial, Helvetica, sans-serif; font-size: 7.5pt;"" ><tr>"
$ WRITE TEMPDETAILFILE "<td style=""font-family: Arial, Helvetica, sans-serif; font-size: 7.5pt;"" align=left ><a href=""http://search.freefind.com/siteindex.html?si=74775162"">index</a></td>"
$ WRITE TEMPDETAILFILE "<td style=""font-family: Arial, Helvetica, sans-serif; font-size: 7.5pt;"" align=center><a href=""http://search.freefind.com/find.html?si=74775162&amp;m=0&amp;p=0"">sitemap</a></td>"
$ WRITE TEMPDETAILFILE "<td style=""font-family: Arial, Helvetica, sans-serif; font-size: 7.5pt;"" align=right><a href=""http://search.freefind.com/find.html?si=74775162&amp;pid=a"">advanced</a></td>"
$ WRITE TEMPDETAILFILE "</tr></table></center><form style=""margin:0px; margin-top:4px;"" action=""http://search.freefind.com/find.html"" method=""get"" accept-charset=""utf-8"" target=""_self"">"
$ WRITE TEMPDETAILFILE "<input type=""hidden"" name=""si"" value=""74775162""><input type=""hidden"" name=""pid"" value=""r""><input type=""hidden"" name=""n"" value=""0""><input type=""hidden"" name=""_charset_"" value="""">"
$ WRITE TEMPDETAILFILE "<input type=""hidden"" name=""bcd"" value=""&#247;""><input type=""text"" name=""query"" size=""32"">
$ WRITE TEMPDETAILFILE "<input type=""submit"" value=""search""></form></td></tr><tr>"
$ WRITE TEMPDETAILFILE "<td style=""text-align:center; font-family: Arial, Helvetica, sans-serif;font-size: 7.5pt; padding-top:4px;"">"
$ WRITE TEMPDETAILFILE "<a style=""text-decoration:none; color:gray;"" href=""http://www.freefind.com"" >site search</a><a style=""text-decoration:none; color:gray;"" href=""http://www.freefind.com"" > by"
$ WRITE TEMPDETAILFILE "<span style=""color: #606060;"">freefind</span></a></td></tr></table><!-- end of freefind search box html --><P></P>"
$!
$ WRITE TEMPDETAILFILE F$FAO("<P></P><H1>HECnet NODE !AS - !AS</H1><H2>!%D</H2><P></P>",P2,P1,0)
$!
$! ++ -- Disabling retrieval of INFO.TXT - causes unwanted access attempts logged at target nodes that don't have it
$! WRITE TEMPDETAILFILE "<H3>INFO.TXT</H3><PRE>"
$! DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$! TYPE 'P1'::INFO.TXT
$! WRITE TEMPDETAILFILE "</PRE>"
$! --
$!
$ IF REMOTE_DECNET_PHASE .EQ. 4
$ THEN
$ WRITE TEMPDETAILFILE "<H3>DECnet PHASE IV REPORT FOR NODE ''P2' (''P1')</H3>"
$ WRITE TEMPDETAILFILE "<PRE>"
$ DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$ NCP TELL 'P1' SHOW NODE 'P1' SUMMARY
$ DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$ NCP TELL 'P1' SHOW NODE 'P1' STATUS
$ WRITE TEMPDETAILFILE "</PRE><H3>KNOWN LINES</H3><PRE>"
$!
$ DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$ NCP TELL 'P1' SHOW KNOWN LINES
$ WRITE TEMPDETAILFILE "</PRE><H3>EXECUTOR AND CIRCUIT CHARACTERISTICS</H3><PRE>"
$!
$ DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$ NCP TELL 'P1' SHOW EXECUTOR CHARACTERISTICS
$!
$ DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$ NCP TELL 'P1' SHOW KNOWN CIRCUIT CHARACTERISTICS
$ WRITE TEMPDETAILFILE "</PRE><H3>KNOWN AREAS / ROUTING</H3><PRE>"
$!
$ DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$ NCP TELL 'P1' SHOW KNOWN AREA
$ WRITE TEMPDETAILFILE "</PRE><H3>ADJACENT NODES</H3><PRE>"
$!
$ DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$ NCP TELL 'P1' SHOW ADJACENT NODES
$! +++ Do not make FAL contents public on the internet ---
$! WRITE TEMPDETAILFILE "</PRE><H3>SHARED FILES</H3><PRE>"
$!
$! DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$! DIR/SIZE/DATE 'P1'::
$! ---
$ WRITE TEMPDETAILFILE "</PRE>"
$ ELSE
$ IF REMOTE_DECNET_PHASE .EQ. 5
$ THEN
$ WRITE TEMPDETAILFILE "<H3>DECnet PHASE V OSI REPORT FOR NODE ''P2' (''P1')</H3>"
$ WRITE TEMPDETAILFILE "<P>PHASE-V OR DECnet-PLUS DATA NOT AVAILABLE</P>"
$! -- NO PHASE-V DATA AVAILABLE
$! WRITE TEMPDETAILFILE "<H3>EXECUTOR SUMMARY</H3><PRE>"
$! DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$! NCL SHOW NODE 'P1' ALL STATUS
$! DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$! NCL SHOW NODE 'P1' SESSION CONTROL ALL STATUS
$! DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$! NCL SHOW NODE 'P1' NSP ALL STATUS
$! DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$! NCL SHOW NODE 'P1' ROUTING ALL STATUS
$! WRITE TEMPDETAILFILE "</PRE>"
$!!
$! WRITE TEMPDETAILFILE "<H3>EXECUTOR CHARACTERISTICS</H3><PRE>"
$! DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$! NCL SHOW NODE 'P1' ALL CHAR
$! DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$! NCL SHOW NODE 'P1' SESSION CONTROL ALL CHAR
$! DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$! NCL SHOW NODE 'P1' NSP ALL CHAR
$! DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$! NCL SHOW NODE 'P1' ROUTING ALL CHAR
$! WRITE TEMPDETAILFILE "</PRE>"
$!!
$! WRITE TEMPDETAILFILE "<H3>NSP CHARACTERISTICS</H3><PRE>"
$! DEFINE/USER SYS$OUTPUT TEMPDETAILFILE ! Valid for only next image execution
$! NCL SHOW NODE 'P1' NSP ALL CHAR
$! WRITE TEMPDETAILFILE "</PRE>"
$! ----
$ ELSE
$ IF REMOTE_DECNET_PHASE .EQ. 9
$ THEN
$ WRITE TEMPDETAILFILE "<H3>DECnet REPORT FOR NODE ''P2' (''P1')</H3>"
$ WRITE TEMPDETAILFILE "<P>NOT AVAILABLE - NO REMOTE NML OBJECT (POSSIBLY A CISCO ROUTER OR SWITCH)</P>"
$ ELSE
$ WRITE SYS$OUTPUT "%DECNET-PHASE-INVALID UNKNOWN DECNET PHASE ''REMOTE_DECNET_PHASE' FOR NODE ''P1'"
$ WRITE SYS$ERROR "%DECNET-PHASE-INVALID UNKNOWN DECNET PHASE ''REMOTE_DECNET_PHASE' FOR NODE ''P1'"
$ GOTO SUB_EXIT
$ ENDIF
$ ENDIF
$ ENDIF
$ WRITE TEMPDETAILFILE "<P></P><H2>HECnet</H2><P>HECnet is the oldest world-wide hobbyist DECnet network connecting people who play around with different machines that have the DECnet protocol suite. "
$ WRITE TEMPDETAILFILE "Visit the <A HREF=""http://www.update.uu.se/~bqt/hecnet.html"" TARGET=""_BLANK"">HECnet Official Website</A>.</P>"
$!
$! START GOOGLE CSE SEARCH BOX
$ WRITE TEMPDETAILFILE "<p></p><p>Search SANYALnet Hobbyist Servers and Services:</p><div id=""google-cse""><!-- Google Custom Search via sanyal.duckdns.org.openvms.vax at gmail --><script>"
$ WRITE TEMPDETAILFILE F$FAO("(function() { var cx = '015567988034387983255:4ulgqks3d_a'; var gcse = document.createElement('script'); gcse.type = 'text/javascript'; gcse.async = true;")
$ WRITE TEMPDETAILFILE F$FAO(" gcse.src = 'https://cse.google.com/cse.js?cx=' + cx; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gcse, s); })(); </script>")
$ WRITE TEMPDETAILFILE F$FAO(" <gcse:search></gcse:search></div><p></p>")
$! END GOOGLE CSE SEARCH BOX
$!
$ WRITE TEMPDETAILFILE "<P></P><P>Proudly generated by a DCL Command Procedure and served by WASD Web Server from a Digital DEC VAXserver 3900 Series computer running OpenVMS VAX 7.3 Operating System.</P>"
$ WRITE TEMPDETAILFILE "<P>&copy; SUPRATIM SANYAL (<A HREF=""https://goo.gl/FqzyBW"" TARGET=""_BLANK"">EMAIL</A>)"
$ WRITE TEMPDETAILFILE " (<A HREF=""http://supratim-sanyal.blogspot.com/"" TARGET=""_BLANK"">BLOG</A>) (<A HREF=""http://www.sanyal.org/"" TARGET=""_BLANK"">Website</A>)</P>"
$ WRITE TEMPDETAILFILE "<P><A HREF=""/falserver/hecnet-status.html"">HECnet NODE SUMMARY</A>&nbsp;&nbsp;|&nbsp;&nbsp;<A HREF=""/"">HOME</A></P>"
$ WRITE TEMPDETAILFILE "<!-- McAfee SECURE Certification --><script type=""text/javascript"" src=""https://cdn.ywxi.net/js/1.js"" async></script></BODY></HTML>"
$!
$!
$SUB_EXIT:
$ CLOSE TEMPDETAILFILE
$ SET FILE/PROT=(W:R) 'NODEDETAIL_FILE'
$ PURGE/NOLOG/NOCONFIRM/KEEP=2 'NODEDETAIL_FILE'
$!
$ ENDSUBROUTINE
view raw HECNET-SCAN.COM hosted with ❤ by GitHub

The scheduled Batch Queue job for scheduled runs of the above command script. To enable, use the DCL command procedure HECNET-SCAN-BATCH.COM:
$ @HECNET-SCAN-BATCH.COM

$! Runs every seven days at 4 AM from current time to update HECnet node status HTML files served by WASD
$ set noon
$ mynameis = f$environment("PROCEDURE")
$ goto 'f$mode()'
$interactive:
$ on warning then goto submit_error
$ submit /after="TODAY+7-04:00"/noprint/keep 'mynameis'
$ write sys$output "Periodic job has been requeued"
$ exit
$network:
$other:
$ write sys$output "Unable to process commands in this mode"
$ exit
$submit_error:
$ set noon
$! mail nla0: system /subject="Nightly batch job has encountered an error"
$ exit
$batch:
$ on warning then goto submit_error
$ submit /after="TODAY+7-04:00"/noprint/keep 'mynameis'
$ set noon
$! now for what we were created for, include the DCL commands scheduled to execute
$!
$ set proc/priv=all
$ @DUA1:[SANYAL.MISC]hecnet-scan.com
$! REBOOT
$ exit




Sunday, November 6, 2016

Install WASD OpenVMS Web Server | A Simple Minimal HTTP Server Configuration on Digital DEC OpenVMS VAX 7.3

WASD 11.0.2 Web Server on DEC Digital VAX 3900 OpenVMS VAX 7.3


This is what I did to bring up a minimal WASD web server on my VAX running OpenVMS 7.3. I did manage to have my website run from a separate user account than WASD and even link to my FAL$SERVER directory for HTTP access in addition to DECNET access to my FAL server.


Preparation


First, follow this post to install CPQ-VAXVMS-SSL-V0101-B-1.PCSI-DCX_VAXEXE and VMSPORTS-VAXVMS-ZLIB-V0102-8-1.ZIP. You should go ahead and follow the entire post to install CURL for OpenVMS VAX 7.3 anyway, CURL is a pretty useful tool to have on your VAX. The SSL version this obtained will remain unused by WASD but the installer will proceed. The installer will use ZLIB.

Then head to the WASD VMS Web Services Download Page and download the latest version for WASD for OpenVMS VAX 7.3. I downloaded the latest version at the time of writing: WASD1102.ZIP. You can also grab it from QCOCAL over HECNET or now by internet, thanks to WASD, from here.

Create a new directory WASD_ROOT on a device with at least 630,000 blocks free. I created DUA2:[WASD_ROOT], and this post is written to reflect that. Adjust according to your needs.

Unzip the downloaded installation ZIP file into the new directory and run the install command file using @INSTALL. Follow the prompts and answer questions taking cues from a log the installation procedure I captured and saved here to build and install the initial working configuration of WASD.

When the install.com procedure completes, start up WASD using @DUA2:[WASD_ROOT.STARTUP]STARTUP.COM and point a web-browser on another computer on your subnet to your VAX. You should see the default WASD web-site with no further configuration needed for the out-of-the-box installation. Use CTRL-Y to exit as instructed.

Set up a different http server root


Create another new directory to hold your web-site and a top-level web server document root under that. I first created DUA2:[WEBROOT] and then a [.HTML] directory under it. Set global read and execute permissions on this directory using

$ SET FILE/PROT=(W:RE) DUA2:[000000]WEBROOT.DIR
$ SET FILE/PROT=(W:RE) DUA2:[000000.WEBROOT.HTML]

Add a simple test HTML file under DUA2:[WEBROOT.HTML]INDEX.HTML - this will be returned to your browser after configuration is complete. The following INDEX.HTML will do fine as your initial test page:

<html><head><title>WASD OpenVMS/VAX</title></head><body><p>TEST</p><p><a href="/falserver/">FAL AREA ON THIS VAX &raquo;</a></p></body></html>

Copy over the EXAMPLE configuration files to DUA2:[WASD_ROOT.LOCAL]:

$ COPY DUA2:[WASD_ROOT.EXAMPLE]*.CONF DUA2:[WASD_ROOT.LOCAL]

Then change to the .LOCAL directory.


Setup Local Configuration of WASD


In the .LOCAL directory, edit WASD_CONFIG_MAP.CONF  and delete all lines. Add the following few lines only.

# ------------------------------
# [WASD_ROOT.LOCAL]wasd_config_map.conf
# ------------------------------
# INSTALL AND CONFIGURE A BASIC WASD WEB SERVER
# ON OPENVMS VAX 7.3
#
# FULL INSTALLATION AND CONFIGURATION PROCEDURE:
# http://supratim-sanyal.blogspot.com/2016/11/install-wasd-openvms-web-server-simple.html
#
# SUPRATIM SANYAL
# SUPRATIM AT RISEUP DOT NET
# ------------------------------
fail /wasd_root/*
pass /falserver/* /falserver/* dir=access dir=wildcard
map /httpd-internal-icons/* /httpd/-/*
pass /*/-/* /wasd_root/runtime/*/* cache=perm
pass /wasd_root/runtime/* /wasd_root/runtime/*
pass /* /web_root/*




Edit WASD_CONFIG_GLOBAL.CONF and replace with the following contents. This is intended to bolster security by turning off scripting support, narrowing allowed default HTML files to index.html, enable reverse DNS lookup, add missing MIME types for directory displays etc. (DIFF with the .EXAMPLE version of WASD_CONFIG_GLOBAL.CONF to see the differences).

# ------------------------------
# [WASD_ROOT.LOCAL]wasd_config_global.conf
# ------------------------------
# INSTALL AND CONFIGURE A BASIC WASD WEB SERVER
# ON OPENVMS VAX 7.3
#
# FULL INSTALLATION AND CONFIGURATION PROCEDURE:
# http://supratim-sanyal.blogspot.com/2016/11/install-wasd-openvms-web-server-minimal.html
#
# SUPRATIM SANYAL
# SUPRATIM AT RISEUP DOT NET
# ------------------------------
# Configuration: klaatu.private:80
# HTTPd-WASD/11.0.0 OpenVMS/AXP SSL
# Last Modified: Monday, Nov 14, 2016
# SYSTEM.'QCOCAL'@sanyalnet-openvms-vax.freeddns.org
# -SERVICE-
[Service]
[ServiceNotFoundURL]
# -GENERAL-
[InstanceMax] 0
[InstancePassive] disabled
[ConnectMax] 100
[ProcessMax] 100
[ServiceListenBacklog] 5
[RequestHistory] 100
[ActivityDays] 28
[CharsetDefault] ISO-8859-1
[CharsetConvert]
[Monitor] enabled
[RegEx] enabled
[EntityTag] enabled
[PipelineRequests] enabled
[HttpTrace] disabled
[WwwImplied] enabled
[GzipAccept] 9
[GzipFlushSeconds] 5,3
[GzipResponse] 9
[Port] 80
[StreamLF] 250
[SearchScript]
[SearchScriptExclude]
[PutMaxKbytes] 5000
[PutBinaryRFM]
[PutVersionLimit] 3
[MapUserNameCacheEntries] 32
[PersonaCacheEntries] 32
# -DNS-
[DNSLookupClient] enabled
[DNSLookupLifeTime] 24:00:00
[DNSLookupRetry] 4
# -LOGGING-
[Logging] enabled
[LogFormat] combined
[LogNaming] host
[LogPeriod] monday
[LogPerInstance] disabled
[LogPerService] enabled
[LogPerServiceHostOnly] disabled
[LogWriteFail503] disabled
[LogFile] WASD_LOGS:
[LogFileExtend] 0
[LogExcludeHosts]
# -OPCOM-
[OpcomTarget] OPER12
[OpcomAdmin] enabled
[OpcomAuthorization] enabled
[OpcomControl] enabled
[OpcomHTTPd] enabled
[OpcomProxyMaint] enabled
# -CACHE-
[Cache] enabled
[CacheEntriesMax] 200
[CacheTotalKBytesMax] 5000
[CacheFileKBytesMax] 64
[CacheGuardPeriod] 00:00:10
[CacheValidatePeriod] 00:00:10
[CacheFrequentHits] 3
[CacheFrequentPeriod] 00:02:00
# -TIMEOUTS-
[TimeoutInput] 00:00:30
[TimeoutOutput] 02:30:00
[TimeoutNoProgress] 00:02:00
[TimeoutPersistent] 00:01:00
# -BUFFER SIZES-
[BufferSizeDclCommand] 8192
[BufferSizeDclOutput] 4492
[BufferSizeDclCgiPlusIn] 6142
[BufferSizeDclCgiHeader] 3172
[BufferSizeNetRead] 2048
[BufferSizeNetWrite] 7492
[BufferSizeNetFile] 7500
[BufferSizeNetMTU] 1500
[SocketSizeSndBuf] 0
[SocketSizeRcvBuf] 0
# -HTTP/2-
[Http2Protocol] enabled
[Http2StreamsMax] 0
[Http2FrameSizeMax] 0
[Http2HeaderListMax] 0
[Http2HeaderTableMax] 0
[Http2InitWindowSize] 0
[HTTP2PingSeconds] 00:00:00
# -SECURE SOCKET-
[SecureSocket] disabled
[SSLversion] TLSvall,-SSLv3
[SSLoptions] +OP_CIPHER_SERVER_PREFERENCE
[SSLcipherList] EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:-DSS:
[SSLcert]
[SSLkey]
[SSLverifyPeer] disabled
[SSLverifyPeerDepth] 0
[SSLverifyPeerCAFile]
[SSLstrictTransSec] 0
[SSLsessionCacheMax] 0
[SSLinstanceCacheMax] 0
[SSLinstanceCacheSize] 0
# -INDEX PAGES-
[Welcome]
INDEX.HTML
# -HOST ACCESS-
[Accept]
[Reject]
# -REPORTS-
[ServerAdmin]
[ServerSignature] enabled
[ServerReportBodyTag] <body link="#0000cc" vlink="#0000cc">
[ServerAdminBodyTag] <body link="#0000cc" vlink="#0000cc">
[ReportBasicOnly] enabled
[ReportMetaInfo] disabled
[ErrorReportPath]
[ErrorRecommend] disabled
# -AUTHORIZATION-
[AuthCacheEntriesMax] 0
[AuthCacheEntrySize] 0
[AuthCacheMinutes] 10
[AuthRevalidateUserMinutes] 0
[AuthFailureLimit] 20
[AuthFailurePeriod] 00:00:00
[AuthFailureTimeout] 00:00:00
[AuthTokenEntriesMax] 0
[AuthBasic] enabled
[AuthDigest] disabled
[AuthDigestGetLife] 0
[AuthDigestPutLife] 0
[AuthSYSUAFlogonType]
[AuthSYSUAFacceptExpPwd] disabled
[AuthSYSUAFpwdExpURL] /httpd/-/change/vms/
# -PROXY SERVING-
[ProxyServing] disabled
[ProxyCache] enabled
[ProxyUnknownRequestFields] enabled
[ProxyForwarded] disabled
[ProxyXForwardedFor] disabled
[ProxyReportLog] enabled
[ProxyReportCacheLog] disabled
[ProxyVerifyRecordMax] 20
[ProxyHostLookupRetryCount] 0
[ProxyConnectTimeoutSeconds] 00:00:00
[ProxyConnectPersistMax] 100
[ProxyConnectPersistSeconds] 00:00:30
[ProxyCacheFileKBytesMax] 0
[ProxyCacheNegativeSeconds] 00:05:00
[ProxyCacheNoReloadSeconds] 00:00:30
[ProxyCacheReloadList] 1,2,4,8,12,24,48,96,168
[ProxyCacheRoutineHourOfDay] 0
[ProxyCachePurgeList] 168,48,24,8,0
[ProxyCacheDeviceDirOrg] 64x64
[ProxyCacheDeviceCheckMinutes] 15
[ProxyCacheDeviceMaxPercent] 90
[ProxyCacheDevicePurgePercent] 1
# -SCRIPTING-
[Scripting] disabled
[DclDetachProcess] disabled
[DclDetachProcessPriority]
[CgiStrictOutput] enabled
[DclSpawnAuthPriv] disabled
[DclGatewayBg] enabled
[DclSoftLimit] 20
[DclHardLimit] 25
[DclBitBucketTimeout] 00:00:15
[DclZombieLifeTime] 00:05:00
[DclCgiPlusLifeTime] 00:10:00
[DECnetReuseLifeTime] 00:05:00
[DECnetConnectListMax] 50
[DclCleanupScratchMinutesMax] 10
[DclCleanupScratchMinutesOld] 10
[DclScriptRunTime]
.PL__ @cgi-bin:[000000]PERL.com
.PL perl
.DLL $CGI-BIN:[000000]CGISAPI.EXE
.CLASS @CGI-BIN:[000000]JAVA.COM
[DclScriptProctor]
# -SSI-
[SSI] disabled
[SSIexec] enabled
[SSIaccesses] enabled
[SSISizeMax] 0
# -WebDAV-
[WebDAV] disabled
[WebDAVlocking] enabled
[WebDAVlockTimeoutDefault] 00:00:00
[WebDAVlockTimeoutMax] 00:00:00
[WebDAVlockCollectionDepth] 1
[WebDAVquota] enabled
# -DIRECTORY-
[DirAccess] enabled
[DirLayout] I__L__R__S:b__D
[DirBodyTag] <body>
[DirDescriptionLines] 30
[DirMetaInfo] disabled
[DirOwner] disabled
[DirPreExpired] disabled
[DirWildcard] enabled
[DirNoImpliedWildcard] enabled
[DirNoPrivIgnore] enabled
[DirReadme] top
[DirReadmeFile]
README.HTML
README.HTM
README.TXT
README.
# -ICONS-
[AddIcon]
/httpd/-/text.gif [TXT] text/plain
/httpd/-/text.gif [CSS] text/css
/httpd/-/text.gif [XML] text/xml
/httpd/-/doc.gif [HTM] text/html
/httpd/-/doc.gif [HTM] text/x-menu
/httpd/-/image.gif [IMG] image/gif
/httpd/-/image.gif [IMG] image/bitmap
/httpd/-/image.gif [IMG] image/x-xbitmap
/httpd/-/image.gif [IMG] image/jpeg
/httpd/-/movie.gif [MOV] image/mpeg
/httpd/-/image.gif [IMG] image/png
/httpd/-/sound.gif [AUD] application/audio
/httpd/-/sound.gif [AUD] audio/x-wav
/httpd/-/sound.gif [AUD] audio/mpeg
/httpd/-/x-script.gif [htm] application/x-script
/httpd/-/text.gif [txt] text/x-ismap
/httpd/-/x-shtml.gif [htm] text/x-shtml
/httpd/-/binary.gif [BIN] application/octet-stream
/httpd/-/binary.gif [BIN] application/x-vms512
/httpd/-/binary.gif [BIN] application/x-compressed
/httpd/-/gzip.gif [ZIP] application/x-gzip
/httpd/-/compressed.gif [ZIP] application/x-compress
/httpd/-/uu.gif [UUE] application/x-uuencoded
/httpd/-/wp.gif [WPC] application/x-wp
/httpd/-/pdf.gif [PDF] application/pdf
/httpd/-/postscript.gif [PS_] application/postscript
/httpd/-/binary.gif [BIN] application/x-ns-proxy-autoconfig
/httpd/-/binary.gif [BIN] application/x-x509-ca-cert
/httpd/-/binary.gif [SWF] application/x-shockwave-flash
/httpd/-/blank.gif _____ x-internal/blank
/httpd/-/file.gif [FIL] x-internal/default-icon
/httpd/-/directory.gif [DIR] x-internal/directory
/httpd/-/back.gif [<--] x-internal/parent
/httpd/-/unknown.gif [???] x-internal/unknown
[AddBlankIcon]
[AddDefaultIcon]
[AddDirIcon]
[AddParentIcon]
[AddUnknownIcon]
# -CONTENT TYPES-
[AddType]
.HTML "text/html; charset=ISO-8859-1" HyperText Markup Language
.HTM text/html HyperText Markup Language
.MENU text/x-menu hypertext menu
.MNU text/x-menu hypertext menu
.TXT "text/plain; charset=ISO-8859-1" plain text
.GIF image/gif GIF image
.BMP image/bitmap Bitmap image
.XBM image/x-xbitmap X-bitmap
.DIR x-internal/directory binary
.SHTML text/x-shtml HyperText Markup Language (pre-processed)
.SHT text/x-shtml HyperText Markup Language (pre-processed)
.ISMAP text/x-ismap Clickable-image mapping
.ISM text/x-ismap Clickable-image mapping
. text/plain plain text
.ACF text/plain DCE Attribute Configuration File
.ADA text/plain Ada source
.ANNOUNCE text/plain plain text
.ASC text/plain plain text
.ASCII text/plain plain text
.AVI video/x-msvideo AVI video
.B32 text/plain BLISS-32 source
.BAS text/plain BASIC source
.BCK application/octet-stream backup saveset
.BKB application/x-script /HyperReader Bookreader book
.BKS application/x-script /HyperShelf Bookreader shelf
.C text/plain C source
.CLD text/plain VMS Command Line Definition
.CFG text/plain configuration file
.CGI text/plain Perl source
.CLASS application/octet-stream Java class
.CMS text/plain Code Management System rules
.COB text/plain COBOL source
.COM text/plain DCL procedure
.CONF text/plain configuration file
.CNF text/plain configuration
.CPP text/plain C++ source
.CRT application/x-x509-ca-cert DER certifcate (MSIE)
.CSS text/css W3C Cascading Style Sheet
.DAT application/octet-stream data file
.DBF application/x-script /dbiv dBASEIV database
.DBT application/octet-stream dBASEIV database memos
.DCL text/plain DCL procedure
.DIS text/plain distribution list
.DLL application/octet-stream ISAPI extension DLL
.DOC application/octet-stream DECwrite document
.DECW$BOOK application/x-script /HyperReader Bookreader book
.DECW$BOOKSHELF application/x-script /HyperShelf Bookreader shelf
.DVI application/octet-stream TeX Device Independent
.EPS text/plain Encapsulated PostScript
.EXE application/octet-stream executable
.FDL text/plain VMS File Definition Language
.FIRST text/plain plain text
.1ST text/plain plain text
.FOR text/plain Fortran source
.H text/plain C header
.HLP text/plain VMS help source
.HDR text/plain LSE template
.HLB application/x-script /Conan VMS help library
.HTMLX text/x-shtml OSU SSI HTML
.ICO image/x-icon MSWin icon
.IMAGEMAP application/x-script /htbin/mapimage OSU Image map
.IDL text/plain DCE Interface Definition Language
.IMG application/octet-stream DDIF image
.JAVA text/plain Java source
.JAR application/octet-stream Java JAR
.JPG image/jpeg JPEG image
.JPEG image/jpeg JPEG image
.JS text/JavaScript JavaScript source
.LIS text/plain plain text listing
.LIST text/plain plain text listing
.LUA text/plain Lua script
.LOG text/plain plain text log
.MAP text/plain map file
.MAR text/plain MACRO-32 source
.MAN text/plain U**x man page
.MLB application/octet-stream VMS MACRO library
.MMS text/plain Module Management System rules
.MP3 audio/mpeg MPEG audio
.MPG image/mpeg MPEG movie
.MPEG image/mpeg MPEG movie
.MSG text/plain VMS message source
.OBJ application/octet-stream VMS object module
.ODL application/x-script /HyperShelf BNU shelf
.OLB application/octet-stream VMS object library
.OPT text/plain VMS linker options
.PAC application/x-ns-proxy-autoconfig proxy autoconfig
.PAS text/plain Pascal source
.PCSI application/octet-stream product installer
.PCSI-DCX_VAXEXE executable product installer
.PDF application/pdf Adobe Portable Document Format
.PEM application/x-x509-ca-cert Privacy Enhanced Mail certificate
.PNG image/png Portable Network Graphic
.POD text/plain Perl documentation
.PL text/plain Perl source
.PERL text/plain Perl source
.PHP text/plain PHP source
.PHTML text/plain PHP source
.PHPS text/plain PHP source
.PM text/plain Perl package
.PRO text/plain IDL source
.PROPERTIES text/plain Java properties
.PS application/postscript PostScript
.PY text/plain Python source
.READ* text/plain plain text
.RELEASE_NOTES text/plain VMS software release notes
.SAV application/octet-stream backup saveset
.SDML text/plain Standard Digital Markup Language - VAX Document source
.STY text/plain TeX Style
.SWF application/x-shockwave-flash Adobe ShockWave Flash
.TEX text/plain TeX source
.TEXT text/plain plain text
.TPU text/plain Text Processing Utility source - VMS TPU
.TLB application/x-script /Conan VMS text library
.UIL text/plain User Interface Language - X Window System
.UID application/octet-stream User Interface Definition - X Window System
.UU application/x-uuencoded UU-encoded
.UUE application/x-uuencoded UU-encoded
.VMS text/plain plain text
.WAV audio/x-wav WAV audio
.WBMP image/vnd.wap.wbmp WAP bitmap
.WML text/vnd.wap.wml WAP ML
.WMLS text/vnd.wap.wmlscript WAP MLScript
.WP application/x-script /hwp WordPerfect document
.WPD application/x-script /hwp WordPerfect document
.WP5 application/x-script /hwp WordPerfect document
.WWW_* text/plain directory access control file
.XHTML application/xhtml+xml XHTML+XML document
.XML text/xml XML
.ZIP application/x-gzip ZIP-compressed
.Z application/x-compressed compressed
.HTL text/plain plain text
* x-internal/unknown
[AddMimeTypesFile]
# End!

Edit  WASD_CONFIG_SERVICE.CONF and enable only HTTP port 80 on the WAN address for our minimal installation.

# ------------------------------
# [WASD_ROOT.LOCAL]wasd_config_service.conf
# ------------------------------
# INSTALL AND CONFIGURE A BASIC WASD WEB SERVER
# ON OPENVMS VAX 7.3
#
# FULL INSTALLATION AND CONFIGURATION PROCEDURE:
# http://supratim-sanyal.blogspot.com/2016/11/install-wasd-openvms-web-server-simple.html
#
# SUPRATIM SANYAL
# SUPRATIM AT RISEUP DOT NET
# ------------------------------
[[http://*:80]]
#[[https://*:443]]
#[[http://localhost:80]]


No other configuration files need to be manipulated for our minimal WASD web server configuration.

Configure Logicals and Startup at Boot

Define the following two logicals manually for now:

$ DEFINE /SYSTEM /EXEC /TRANSLATION=CONCEALED WEB_ROOT DUA2:[WEBROOT.HTML.]
$ define /system/exec /TRANSLATION=CONCEALED falserver dua2:[fal$server.]

Also add them to system boot-time startup definitions. Edit your SYS$MANAGER:SYSTARTUP_VMS.COM and add the following where you define your site-specific startup scripts:

$! Start up the web server
$ DEFINE /SYSTEM /EXEC /TRANSLATION=CONCEALED WEB_ROOT DUA2:[WEBROOT.HTML.]
$ define /system/exec /TRANSLATION=CONCEALED falserver dua2:[fal$server.]
$ @DUA2:[WASD_ROOT.STARTUP]STARTUP.COM
$!

Note: Since you already installed the SSL and ZLIB applications at the beginning, you should already have the following startup commands executing before starting the WASD web server:

$ @sys$startup:ssl$startup.com
$ @sys$startup:gnv$zlib_startup.com

Also, my FAL directory is at DUA2:[FAL$SERVER] and that is what the falserver logical above reflects. Obviously you need to adjust for your FAL Server location.

Important: Do not miss the dot before the closing square brackets in the logicals. As a quick test, commands like DIR WEB_ROOT:[000000] and DIR FALSERVER:[000000] need to resolve to the directories correctly. Examples of what I get:

DUA2:[WASD_ROOT.LOCAL] DIR WEB_ROOT:[000000]  

Directory WEB_ROOT:[000000]

DIGITAL.PNG;1       FAVICON.ICO;1       HTML.TAR;1          INDEX.HTML;22      
STYLES.DIR;1        

Total of 5 files.
DUA2:[WASD_ROOT.LOCAL] DIR FALSERVER:[000000]

Directory FALSERVER:[000000]

INFO.TXT;1          INTRUSIONS.TXT;11   INTRUSIONS.TXT;10   INTRUSIONS.TXT;9   
KRB.DIR;1           NET$SERVER.LOG;48   NODENAMES.DAT;172   NODENAMES.DAT;171  
SOFTWARE-DOWNLOADS.DIR;1                

Total of 9 files.


Stop WASD and restart it:

$ @DUA2:[WASD_ROOT.STARTUP]SHUTDOWN.COM
$ @DUA2:[WASD_ROOT.STARTUP]STARTUP.COM

Again point a web-browser (remember to Shift+Reload on your browser to force a fresh non-cached request) on another computer on your subnet to your VAX. You should now see tiny test html page. Clicking on the FAL AREA link should show the files in your FAL$SERVER directory.

Troubleshooting


The only stumble I had was with file and directory permissions. If you get "ERROR 403  -  The requested action is not permitted." or "ERROR 404  -  The requested resource could not be found." errors, remember WASD needs to be able to reach and read the HTML files for your website in a different account, as well as FAL area files, and make sure they at least have READ privileges for the World:

$ SET FILE/PROT=(W:R) DUA2:[WEBROOT...]*.*
$ SET FILE/PROT=(W:R) DUA2:[FAL$SERVER...]*.*

WASD writes its httpd Access Log to the .LOG directory wasd_root:[log]. Example:

DUA2:[WASD_ROOT.LOCAL] dir wasd_root:[log]

Directory WASD_ROOT:[LOG]

.WWW_HIDDEN;1       LOCALHOST_80_20161031_ACCESS.LOG;1      README.HTML;1      
SANYALNET-VAX-SANYAL_80_20161031_ACCESS.LOG;1               

Total of 4 files.

The WASD install script created two accounts - one to run the WASD server process, and a "nobody" account to run scripts from. In addition, I created the WEBROOT account as the root html directory. I modified the account expiration and password lifetimes so that their passwords do not expire. I also made the WEBROOT account captive with no NETMBX privilege - the only purpose of this account is to be a holding place for HTML files served by WASD web-server. Here are the account characteristics I see:

DUA2:[WASD_ROOT.LOG] cd sys$system
SYS$SYSROOT:[SYSEXE] mc authorize
UAF> show http$server /full

Username: HTTP$SERVER                      Owner:  WASD Server
Account:                                   UIC:    [77,1] ([HTTP$SERVER])
CLI:      DCL                              Tables: DCLTABLES
Default:  DUA2:[HTTP$SERVER]
LGICMD:   LOGIN.COM
Flags:  DisNewMail DisMail
Primary days:   Mon Tue Wed Thu Fri        
Secondary days:                     Sat Sun
Primary   000000000011111111112222  Secondary 000000000011111111112222
Day Hours 012345678901234567890123  Day Hours 012345678901234567890123
Network:  ##### Full access ######            ##### Full access ######
Batch:    ##### Full access ######            ##### Full access ######
Local:    -----  No access  ------            -----  No access  ------
Dialup:   -----  No access  ------            -----  No access  ------
Remote:   -----  No access  ------            -----  No access  ------
Expiration:            (none)    Pwdminimum:  6   Login Fails:     0
Pwdlifetime:         90 00:00    Pwdchange:      (pre-expired) 
Last Login:            (none) (interactive),  6-NOV-2016 09:18 (non-interactive)
Maxjobs:         0  Fillm:       300  Bytlm:      5000000
Maxacctjobs:     0  Shrfillm:      0  Pbytlm:           0
Maxdetach:       0  BIOlm:      2000  JTquota:       4000
Prclm:         100  DIOlm:      1000  WSdef:         1000
Prio:            4  ASTlm:      2000  WSquo:         4000
Queprio:         0  TQElm:       100  WSextent:     20000
CPU:        (none)  Enqlm:       500  Pgflquo:     500000
Authorized Privileges: 
  NETMBX    TMPMBX
Default Privileges: 
  NETMBX    TMPMBX
Identifier                         Value           Attributes
  WASD_HTTP_SERVER                 %X80010003      
UAF> 
UAF> show http$nobody /full

Username: HTTP$NOBODY                      Owner:  WASD Scripting
Account:                                   UIC:    [76,1] ([HTTP$NOBODY])
CLI:      DCL                              Tables: DCLTABLES
Default:  DUA2:[HTTP$NOBODY]
LGICMD:   LOGIN.COM
Flags:  DisNewMail DisMail
Primary days:   Mon Tue Wed Thu Fri        
Secondary days:                     Sat Sun
Primary   000000000011111111112222  Secondary 000000000011111111112222
Day Hours 012345678901234567890123  Day Hours 012345678901234567890123
Network:  ##### Full access ######            ##### Full access ######
Batch:    -----  No access  ------            -----  No access  ------
Local:    -----  No access  ------            -----  No access  ------
Dialup:   -----  No access  ------            -----  No access  ------
Remote:   -----  No access  ------            -----  No access  ------
Expiration:            (none)    Pwdminimum:  6   Login Fails:     0
Pwdlifetime:         90 00:00    Pwdchange:      (pre-expired) 
Last Login:            (none) (interactive),  5-NOV-2016 01:33 (non-interactive)
Maxjobs:         0  Fillm:       300  Bytlm:       500000
Maxacctjobs:     0  Shrfillm:      0  Pbytlm:           0
Maxdetach:       0  BIOlm:      2000  JTquota:       4000
Prclm:         100  DIOlm:      1000  WSdef:         1000
Prio:            4  ASTlm:      2000  WSquo:         4000
Queprio:         0  TQElm:       100  WSextent:     20000
CPU:        (none)  Enqlm:       500  Pgflquo:     500000
Authorized Privileges: 
  NETMBX    TMPMBX
Default Privileges: 
  NETMBX    TMPMBX
Identifier                         Value           Attributes
  WASD_HTTP_NOBODY                 %X80010004      
UAF> 
UAF> 
UAF> show webroot /full    

Username: WEBROOT                          Owner:  WEB ROOT HTML FILES
Account:  WEBROOT                          UIC:    [200,236] ([WEBROOT])
CLI:      DCL                              Tables: DCLTABLES
Default:  DUA2:[WEBROOT]
LGICMD:   LOGIN
Flags:  Captive
Primary days:   Mon Tue Wed Thu Fri        
Secondary days:                     Sat Sun
No access restrictions
Expiration:            (none)    Pwdminimum:  6   Login Fails:     0
Pwdlifetime:           (none)    Pwdchange:      (pre-expired) 
Last Login:  5-NOV-2016 01:51 (interactive),            (none) (non-interactive)
Maxjobs:         0  Fillm:       300  Bytlm:        32768
Maxacctjobs:     0  Shrfillm:      0  Pbytlm:           0
Maxdetach:       0  BIOlm:        40  JTquota:       4096
Prclm:           2  DIOlm:        40  WSdef:          256
Prio:            4  ASTlm:        40  WSquo:          512
Queprio:         0  TQElm:        40  WSextent:      1024
CPU:        (none)  Enqlm:       200  Pgflquo:      32768
Authorized Privileges: 
Default Privileges: 
UAF> 
UAF> exit
%UAF-I-NOMODS, no modifications made to system authorization file
%UAF-I-NAFNOMODS, no modifications made to network proxy database
%UAF-I-RDBNOMODS, no modifications made to rights database
SYS$SYSROOT:[SYSEXE]

There are some fabulous folks at the comp.os.vms newsgroup that are always ready to help. For example, this post came in extremely useful for me when I was struggling with HTTP 403 errors.


Recommended Products from Amazon