This is G o o g l e's cache of http://www.lp.se/ftp/mailinglists/LP/FREE-BUGS.1999-04.
G o o g l e's cache is the snapshot that we took of the page as we crawled the web.
The page may have changed since that time. Click here for the current page without highlighting.


Google is not affiliated with the authors of this page nor responsible for its content.
These search terms have been highlighted: levitte programming 

Archive-Date: Fri, 9 Apr 1999 17:30:45 +0200
Date: Fri, 9 Apr 1999 11:30:34 -0400
From: SYSTEM@wolverine.acornsw.com
Reply-To: bugs@free.lp.se, SYSTEM@wolverine.acornsw.com
To: bugs@free.lp.se
Message-ID: <990409113034.21600131@wolverine.acornsw.com>
Subject: Fixed a few problems with ftp_mirror.com

$	VERIFY = 'F$VERIFY(F$TRNLNM("FTP_MIRROR_VERIFY"))'
$	SET = "SET"
$	SET SYMBOL/SCOPE=(noGLOBAL,noLOCAL)
$	GOTO _START_FTP_MIRROR

DESCRIPTION:

  Automates mirroring a remote FTP site.

PARAMETERS:

  P1 - configuration filename

REQUIREMENTS:

Due to the different commands used by FTP Clients, only a few FTP Clients are 
supported.  Due to the different output generated by different FTP Servers,
parsing routines have only been written for a few FTP Servers.

  o one of the following FTP Clients (on your system):
      - MultiNet 
      - MadGoat FTP
      - TCPware

  o mirrored against one of the following FTP Servers (on the remote system):
      - MultiNet
      - MadGoat FTP
      - TCPware
      - Unix

 =----------------------------------------------------------------------=

Copyright © 1994 by Dan Wing.
Copyright © 1997 by MadGoat Software, Inc.
Copyright © 1998 by Richard Levitte.
Copyright © 1999 by Dick Munroe

This code may be freely distributed and modified for no commercial gain
as long as this copyright notice is retained.  This program is supplied
'as-is', and with no warranty.

Created September 21, 1994, by Dan Wing, TGV <dwing@Cisco.com>
Hacked a lot by Richard Levitte <richard@levitte.org>
Features added by Hunter Goatley <goathunter@madgoat.com>

Please send bug reports to <bugs@free.lp.se>.

 =----------------------------------------------------------------------=

  REVERSE CHRONOLOGICAL MODIFICATION HISTORY
  ------------------------------------------

  T0.8-4  09-APR-1999  Dick Munroe <munroe@acornsw.com>
     Using a multinet FTP client requires that the VERBOSE mode of
     FTP transfer be used.  This, in turn, left stuff in the log files
     that, for some reason, the command procedure didn't know how to
     process.  There were similar issues for hooking up to aol.com, so
     now this procedure seems to work with all the ftp sites that I'm
     using regularly.

  T0.8-3  23-APR-1998  Richard Levitte <richard@levitte.org>
     A small bug corrected.  REMOTE_DIRECTORY wasn't set correctly
     under some circumstances.  Under others, it was set when it
     really shoulden't.

  T0.8-2  20-APR-1998  Richard Levitte <richard@levitte.org>
     Worked around the fact that the MadGoat client (and perhaps others)
     sputters lines like the following one right in the middle of the
     directory output:

	<226 File transfer Okay; Closing data connection.

  T0.8-1  07-APR-1998  Richard Levitte <richard@levitte.org>
     Corrected a small bug that caused a erroneous download to be made
     for a serie of Unix directories.  Of course, if `ls' could output
     the directory name for the first directory listed, we wouldn't
     have these problems...

  T0.8	   6-APR-1998	Hunter Goatley <goathunter@MadGoat.com>
     Explicitly enable or disable passive mode according to file setting.

  T0.7    06-APR-1998  Richard Levitte <richard@levitte.org>
     Merged in changes that Hunter Goatley <goathunter@madgoat.com>
     added in 27-MAY-1997.  His comment was:

	Updated for newer MGFTP releases and for TCPware.

  T0.6    05-APR-1998  Richard Levitte <richard@levitte.org>
     - Now understands the output from a Unix FTP server, and can
       download files from it.  ALL files are currently downloaded in
       Image mode.
     - An added feature is that "/..." at the end of a Unix directory
       specification means the same thing as the standard VMS
       ellipsis.
     - CAUTION:  Unix file specifications can ONLY be used as the
       first argument of the DIRECTORY configuratoin parameter.
     - Name conversion for Unix file specifications is done according
       to the following rules:
         1. An ending ".gz" is changed to "-gz" if there is another
            dot in the file name.
         2. And ending ".Z is changed to "_Z" if there is another dot
            in the file name.
         3. All remaining dots except the last are changed to
            underscores, except the last one in a file name.
         4. All other characters that are not legal in a VMS file name
            are changed to dollars.
     - A hack that saves the current time in a file has been added.
       If that file is found and there is a time specification in it,
       it is used to limit the download of file to those newer than
       that time.  The name of this file is configurable.
     - A mail address to send logs to is configurable.

  T0.5	  02-APR-1998  Richard Levitte <richard@levitte.org>
     Many hacks, among other supporting elipsis in directory specs,
     and support for the Process Software FTP server.  Unfortunatelly,
     I haven't made many notes of my changes.

  T0.0    25-OCT-1994  Dan Wing, wing@tgv.com
     Initial release.

$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$ _START_FTP_MIRROR: 
$
$	ON WARNING THEN GOTO _ERROR
$	ON CONTROL_Y THEN GOTO _ABORT
$
$	FTP_MIRROR_VERSION = "T0.8-3 BETA TEST Prerelease 4"								!DM
$	WRITE SYS$OUTPUT F$FAO("!/FTP_Mirror, version !AS.!/Started by !AS on node !AS on !AS, !AS !8AS.", -
			       FTP_MIRROR_VERSION, -
			       F$EDIT(F$GETJPI(0,"USERNAME"),"TRIM"), -
			       F$GETSYI("NODENAME"), -
			       F$CVTIME(,,"WEEKDAY"), -
			       F$CVTIME(,"ABSOLUTE","DATE"), -
			       F$CVTIME(,,"TIME"))
$
$	TRUE = 1
$	FALSE = 0
$	DEBUG = FALSE
$	IF F$TRNLNM("FTP_MIRROR_DEBUG") THEN DEBUG = TRUE
$	IF DEBUG THEN WRITE SYS$ERROR "FTP_Mirror debugging enabled."
$
$! setup defaults.  These can be overridden in the configuration file
$
$	CONFIG_FTP_CLIENT           = "MadGoat FTP"
$	CONFIG_COMMAND              = "FTP"
$	CONFIG_FTP_SERVER           = "MadGoat FTP"
$	CONFIG_SITE                 = ""
$	CONFIG_USERNAME             = "anonymous"
$	IF F$TRNLNM("UCX$INET_HOST") .NES. "" THEN CONFIG_PASSWORD = "mirror@" + F$TRNLNM("UCX$INET_HOST")
$	IF F$TRNLNM("MULTINET_HOST_NAME") .NES. "" THEN CONFIG_PASSWORD = "mirror@" + F$TRNLNM("MULTINET_HOST_NAME")
$	CONFIG_PASSIVE              = FALSE
$	CONFIG_SUBMIT_AFTER         = "+12:00:00"
$	CONFIG_QUEUE                = "SYS$BATCH"
$	CONFIG_FILE_TRANSFER        = "VMS"
$	CONFIG_LAST_TIME_FILE       = ""
$	CONFIG_MAILTO               = ""
$
$	VALID_CONFIGURATION = TRUE           ! assume the best
$
$	TEMPFILE_1 = "SYS$SCRATCH:FTP_MIRROR_1_" + F$GETJPI(0,"PID") + ".TMP"
$	TEMPFILE_2 = "SYS$SCRATCH:FTP_MIRROR_2_" + F$GETJPI(0,"PID") + ".TMP"
$	TEMPFILE_3 = "SYS$SCRATCH:FTP_MIRROR_3_" + F$GETJPI(0,"PID") + ".TMP"
$	TEMPFILE_4 = "SYS$SCRATCH:FTP_MIRROR_4_" + F$GETJPI(0,"PID") + ".TMP"
$
$	CONFIG_LAST_TIME = ""
$	CONFIG_DIR_TOTAL = 0
$
$	TYPE_MULTINET = 1
$	TYPE_MGFTP    = 2
$	TYPE_TCPWARE  = 3
$	TYPE_UNIX     = 128
$	TYPE_OTHER    = 255
$
$	IF P1 .EQS. "" THEN P1 = "FTP_MIRROR.DAT"
$! make sure CONFIGURATION_FILE contains a full path, but also make sure
$! you get the right directory.  Guess what F$PARSE does to non-concealed
$! multivalued logical names.  It's not a pretty sight.  --  Richard Levitte
$	CONFIGURATION_FILE = F$SEARCH(P1)
$	IF CONFIGURATION_FILE .EQS. "" THEN GOTO _NO_CONFIG_FILE
$	GOSUB _CLEANUP
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$	OPEN/READ/ERROR=_ERROR FILE 'CONFIGURATION_FILE'
$ _CONFIG_LOOP:	
$	READ/END_OF_FILE=_EXIT_CONFIG_LOOP/ERROR=_ERROR FILE RECORD
$	RECORD = F$EDIT(RECORD,"COMPRESS,UNCOMMENT")
$	IF RECORD .EQS. "" THEN GOTO _CONFIG_LOOP
$
$	PARA1 = F$EDIT(F$ELEMENT(0," ",RECORD),"UPCASE")
$	PARA2 = F$ELEMENT(1," ",RECORD)
$	PARA3 = F$ELEMENT(2," ",RECORD)
$  
$	VALID_RECORD = FALSE
$
$	IF PARA1 .EQS. "SITE"
$	THEN
$	    CONFIG_SITE = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "USERNAME"
$	THEN
$	    CONFIG_USERNAME = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "PASSWORD"
$	THEN
$	    CONFIG_PASSWORD = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "DIRECTORY"
$	THEN
$	    CONFIG_DIRECTORIES_'CONFIG_DIR_TOTAL' = PARA2 + "," + PARA3
$	    CONFIG_DIR_TOTAL = CONFIG_DIR_TOTAL + 1
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "COMMAND"
$	THEN
$	    CONFIG_COMMAND = F$EXTRACT(F$LOCATE(" ",RECORD)+1,-1,RECORD)
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "PASSIVE"
$	THEN
$	    CONFIG_PASSIVE = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "PRIV"
$	THEN
$	    ORIGINAL_PRIV = F$SETPRV(PARA2)
$	    IF .NOT. F$PRIVILEGE(PARA2) THEN WRITE SYS$OUTPUT "%%Warning - not all requested privileges are authorized."
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "SUBMIT_AFTER"
$	THEN
$	    CONFIG_SUBMIT_AFTER = F$EDIT("''PARA2' ''PARA3'","TRIM")
$	    IF F$EDIT(PARA2,"UPCASE") .EQS. "NONE" -
	       .OR. F$EDIT(PARA3,"UPCASE") .EQS. "ONE" THEN -
	       CONFIG_SUBMIT_AFTER = "NONE"
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "BATCH_QUEUE"
$	THEN
$	    CONFIG_QUEUE = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "FTP_CLIENT"
$	THEN
$	    CONFIG_FTP_CLIENT = F$EDIT(PARA2,"UPCASE")
$	    IF CONFIG_FTP_CLIENT .EQS. "MULTINET" 
$	    THEN 
$		CONFIG_FTP_CLIENT = "MultiNet"
$		CONFIG_COMMAND = "MULTINET FTP"
$		VALID_RECORD = TRUE
$	    ENDIF
$	    IF CONFIG_FTP_CLIENT .EQS. "MADGOAT" -
	       .OR. CONFIG_FTP_CLIENT .EQS. "MADGOAT_FTP"
$	    THEN 
$		CONFIG_FTP_CLIENT = "MadGoat FTP"
$		CONFIG_COMMAND = "FTP"
$		VALID_RECORD = TRUE
$	    ENDIF
$	    IF CONFIG_FTP_CLIENT .EQS. "TCPWARE"
$	    THEN
$		CONFIG_FTP_CLIENT = "TCPware"
$		CONFIG_COMMAND = "FTP"
$		VALID_RECORD = TRUE
$	    ENDIF
$	ENDIF
$
$	IF PARA1 .EQS. "FTP_SERVER"
$	THEN
$	    CONFIG_FTP_SERVER = F$EDIT(PARA2,"UPCASE")
$	    IF CONFIG_FTP_SERVER .EQS. "MULTINET" THEN -
	       CONFIG_FTP_SERVER = "MultiNet"
$	    IF CONFIG_FTP_SERVER .EQS. "MADGOAT" -
	       .OR. CONFIG_FTP_SERVER .EQS. "MADGOAT_FTP" -
	       THEN CONFIG_FTP_SERVER = "MadGoat FTP"
$	    IF CONFIG_FTP_SERVER .EQS. "TCPWARE" THEN -
	       CONFIG_FTP_SERVER = "TCPware"
$	    IF CONFIG_FTP_SERVER .EQS. "UNIX" THEN -
	       CONFIG_FTP_SERVER = "Unix"
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "FILE_TRANSFER"
$	THEN
$	    CONFIG_FILE_TRANSFER = F$EDIT(PARA2,"UPCASE")
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "LAST_TIME_FILE"
$	THEN
$	    CONFIG_LAST_TIME_FILE = F$EDIT(PARA2,"UPCASE")
$	    IF F$SEARCH(CONFIG_LAST_TIME_FILE) .NES. ""
$	    THEN
$		OPEN/READ FOO 'CONFIG_LAST_TIME_FILE'
$		READ FOO CONFIG_LAST_TIME
$		CONFIG_LAST_TIME = F$CVTIME(CONFIG_LAST_TIME,"COMPARISON")
$		CLOSE FOO
$	    ELSE
$		CONFIG_LAST_TIME = "1-JAN-1900"
$	    ENDIF
$	    ! We remove oen day just to make sure we get all files in
$	    ! spite of all kinds of timezone junk.  So we might get
$	    ! duplicates at times...  So what?
$	    CONFIG_NEXT_TIME = F$CVTIME("-1-","ABSOLUTE")
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "MAILTO"
$	THEN
$	    CONFIG_MAILTO = F$EDIT(PARA2,"UPCASE")
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF .NOT. VALID_RECORD
$	THEN
$	    WRITE SYS$OUTPUT "%%Warning - invalid configuration file record \", RECORD, "\"
$	    VALID_CONFIGURATION = FALSE
$	ENDIF
$
$	GOTO _CONFIG_LOOP
$  
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$ _EXIT_CONFIG_LOOP: 
$	CLOSE FILE
$
$	IF .NOT. VALID_CONFIGURATION
$	THEN
$	    WRITE SYS$OUTPUT "Error in configuration file."
$	    GOTO _EXIT
$	ENDIF
$
$	FTP_CLIENT_TYPE = TYPE_OTHER
$	IF CONFIG_FTP_CLIENT .EQS. "MultiNet" THEN -
	   FTP_CLIENT_TYPE = TYPE_MULTINET
$	IF CONFIG_FTP_CLIENT .EQS. "MadGoat FTP" THEN -
	   FTP_CLIENT_TYPE = TYPE_MGFTP
$	IF CONFIG_FTP_CLIENT .EQS. "TCPware" THEN -
	   FTP_CLIENT_TYPE = TYPE_TCPWARE
$
$	FTP_SERVER_TYPE = TYPE_OTHER
$	IF CONFIG_FTP_SERVER .EQS. "MultiNet" THEN -
	   FTP_SERVER_TYPE = TYPE_MULTINET
$	IF CONFIG_FTP_SERVER .EQS. "MadGoat FTP" THEN -
	   FTP_SERVER_TYPE = TYPE_MGFTP
$	IF CONFIG_FTP_SERVER .EQS. "TCPware" THEN -
	   FTP_SERVER_TYPE = TYPE_TCPWARE
$	IF CONFIG_FTP_SERVER .EQS. "Unix" THEN -
	   FTP_SERVER_TYPE = TYPE_UNIX
$
$	WRITE SYS$OUTPUT ""
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Remote site:",CONFIG_SITE)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Remote username:",CONFIG_USERNAME)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Remote password:",CONFIG_PASSWORD)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","FTP server:",CONFIG_FTP_SERVER)
$	WRITE SYS$OUTPUT ""
$	WRITE SYS$OUTPUT "  Directories:  (remote)                (local)"
$
$	COUNT = 0
$ _DISPLAY_LOOP_1: 
$	IF COUNT .GE. CONFIG_DIR_TOTAL THEN GOTO _EXIT_DISPLAY_LOOP_1
$	WRITE SYS$OUTPUT F$FAO("    !33AS !35AS", -
			       F$ELEMENT(0,",",CONFIG_DIRECTORIES_'COUNT'), -
			       F$ELEMENT(1,",",CONFIG_DIRECTORIES_'COUNT'))
$	IF F$PARSE(F$ELEMENT(1,",",CONFIG_DIRECTORIES_'COUNT'),,,,"SYNTAX_ONLY") .EQS. ""
$	THEN
$	    WRITE SYS$ERROR F$FAO("!5** Local directory specification (above) is invalid VMS syntax.")
$	    VALID_CONFIGURATION = FALSE
$	ENDIF
$	COUNT = COUNT + 1
$	GOTO _DISPLAY_LOOP_1
$ _EXIT_DISPLAY_LOOP_1: 
$
$	WRITE SYS$OUTPUT ""
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","FTP client:",CONFIG_FTP_CLIENT)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","DCL command:",CONFIG_COMMAND)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","File transfer mode:",CONFIG_FILE_TRANSFER)
$	IF CONFIG_PASSIVE
$	THEN
$	    CONFIG_PASSIVE = TRUE
$	    WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Passive mode:","Yes")
$	ELSE
$	    CONFIG_PASSIVE = FALSE
$	    WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Passive mode:","No")
$	ENDIF
$	IF CONFIG_LAST_TIME .NES. "" THEN -
	   WRITE SYS$OUTPUT F$FAO("  !40AS !AS",-
				  "Only get files created after:",-
				  CONFIG_LAST_TIME)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Resubmit after:",-
			       CONFIG_SUBMIT_AFTER)
$	IF CONFIG_SUBMIT_AFTER .NES. "NONE" THEN -
	   WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Batch queue:",CONFIG_QUEUE)
$	IF CONFIG_MAILTO .NES. "" THEN -
	   WRITE SYS$OUTPUT F$FAO("  !40AS !AS",-
				  "Mail reports to:",-
				  CONFIG_MAILTO)
$	WRITE SYS$OUTPUT ""
$
$	IF CONFIG_SITE .EQS. "" .OR. CONFIG_USERNAME .EQS. "" .OR. -
	   CONFIG_PASSWORD .EQS. "" .OR. CONFIG_DIRECTORIES_0 .EQS. "" .OR. -
	   CONFIG_SUBMIT_AFTER .EQS. ""
$	THEN
$	    WRITE SYS$ERROR "Missing required configuration setting; exiting."
$	    WRITE SYS$ERROR "Check for missing username, directory, password, or submit-after."
$	    GOTO _EXIT
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .NE. TYPE_MULTINET -
	   .AND. FTP_CLIENT_TYPE .NE. TYPE_MGFTP -
	   .AND. FTP_CLIENT_TYPE .NE. TYPE_TCPWARE
$	THEN
$	    WRITE SYS$ERROR "Invalid FTP Client -- only \MULTINET\, \TCPWARE\, or \MADGOAT FTP\ are allowed."
$	    GOTO _EXIT
$	ENDIF
$
$!$	IF CONFIG_PASSIVE .AND. (FTP_CLIENT_TYPE .EQ. TYPE_MGFTP .OR. -
$!				 FTP_SERVER_TYPE .EQ. TYPE_MGFTP)
$!$	THEN
$!$	    WRITE SYS$ERROR "PASSIVE isn't supported by MadGoat FTP client or server."
$!$	    GOTO _EXIT
$!$	ENDIF
$
$	IF FTP_SERVER_TYPE .NE. TYPE_MULTINET -
	   .AND. FTP_SERVER_TYPE .NE. TYPE_MGFTP -
	   .AND. FTP_SERVER_TYPE .NE. TYPE_TCPWARE -
	   .AND. FTP_SERVER_TYPE .NE. TYPE_UNIX
$	THEN
$	    WRITE SYS$ERROR "Invalid FTP Server.  Only MultiNet, MadGoat FTP, TCPware, and UNIX are supported."
$	    GOTO _EXIT
$	ENDIF
$
$	IF .NOT. VALID_CONFIGURATION
$	THEN
$	    WRITE SYS$ERROR "Invalid configuration -- see above reason"
$	    GOTO _EXIT
$	ENDIF
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$	IF F$MODE() .EQS. "INTERACTIVE"
$	THEN
$	    READ SYS$COMMAND CHECK/PROMPT="Ready [Y]? "/END_OF_FILE=_ABORT
$	ELSE
$	    CHECK := Y
$	ENDIF
$
$	IF .NOT. CHECK .AND. CHECK .NES. "" THEN GOTO _ABORT
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$	IF CONFIG_SUBMIT_AFTER .NES. "NONE" .AND. F$MODE() .NES. "BATCH"
$	THEN
$	    GOTO _SUBMIT
$	ENDIF
$          
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!  Obtain the list of files on the remote system
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$	OPEN/WRITE FILE 'TEMPFILE_1'
$	COUNT = 0
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MULTINET
$	THEN
$	    IF CONFIG_PASSIVE
$	    THEN WRITE FILE "PASSIVE ON"
$	    ELSE WRITE FILE "PASSIVE OFF"
$	    ENDIF
$	    WRITE FILE "EXIT-ON-ERROR ON"
$	    WRITE FILE "PROMPT-FOR-MISSING-ARGUMENTS OFF"
$	    WRITE FILE "VERBOSE"											!DM
$	    IF DEBUG THEN WRITE FILE "STATISTICS"
$	    WRITE FILE "CONNECT ", CONFIG_SITE
$	    WRITE FILE "USER ", CONFIG_USERNAME
$	    WRITE FILE "PASS ", CONFIG_PASSWORD
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE FILE "STRUCTURE VMS"
$	    ELSE
$		WRITE FILE "TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE FILE "PWD"
$	ENDIF  ! multinet
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MGFTP
$	THEN
$	    WRITE FILE "SET BATCH"
$	    IF CONFIG_PASSIVE
$	    THEN WRITE FILE "SET PASSIVE"
$	    ELSE WRITE FILE "SET NOPASSIVE"
$	    ENDIF
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE FILE "SET STRUCTURE VMS"
$	    ELSE
$		WRITE FILE "SET TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE FILE "PWD"
$	ENDIF  ! madgoat
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_TCPWARE
$	THEN
$	    IF CONFIG_PASSIVE
$	    THEN WRITE FILE "SET PASSIVE"
$	    ELSE WRITE FILE "SET NOPASSIVE"
$	    ENDIF
$	    IF DEBUG THEN WRITE FILE "SET DEBUG/CLASS=REPLIES"
$	    WRITE FILE "CONNECT ", CONFIG_SITE, " ", -
		  CONFIG_USERNAME, " ", CONFIG_PASSWORD
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE FILE "STRUCTURE VMS"
$	    ELSE
$		WRITE FILE "TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE FILE "PWD"
$	ENDIF  ! tcpware
$
$	COUNT = 0
$ _GEN_FILE_LOOP: 
$	IF COUNT .GE. CONFIG_DIR_TOTAL THEN GOTO _EXIT_GEN_FILE_LOOP
$	DIRECTORY_NAME = F$ELEMENT(0,",",CONFIG_DIRECTORIES_'COUNT')
$	DIRECTORY_NAME2 = DIRECTORY_NAME - "/..." - "..."
$	WRITE FILE "SPAWN WRITE SYS$OUTPUT ""<<<REMOTE_DIRECTORY ''DIRECTORY_NAME2'>>>"""
$	IF FTP_SERVER_TYPE .EQ. TYPE_UNIX .AND. -
	   F$EXTRACT(F$LENGTH(DIRECTORY_NAME)-4, 4, DIRECTORY_NAME) .EQS. "/..." -
	   THEN DIRECTORY_NAME = "-RlL " + F$EXTRACT(0, F$LENGTH(DIRECTORY_NAME)-4, DIRECTORY_NAME)
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MULTINET THEN -
	   WRITE FILE "DIR """, DIRECTORY_NAME, """"
$!RL	   WRITE FILE "DIR """, DIRECTORY_NAME, """ FTP_DIR:"
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MGFTP -
	   .OR. FTP_CLIENT_TYPE .EQ. TYPE_TCPWARE THEN -
	   WRITE FILE "DIR """, DIRECTORY_NAME, """"
$!RL	   WRITE FILE "DIR """, DIRECTORY_NAME, """/OUTPUT=FTP_DIR:"
$	COUNT = COUNT + 1
$	GOTO _GEN_FILE_LOOP
$
$ _EXIT_GEN_FILE_LOOP: 
$	WRITE FILE "EXIT"
$	CLOSE FILE
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Contents of input file:"
$	IF DEBUG THEN TYPE/OUTPUT=SYS$ERROR 'TEMPFILE_1'
$
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Connecting to remote system..."
$!RL$	IF F$SEARCH(TEMPFILE_2) .NES. "" THEN DELETE 'TEMPFILE_2';*
$!RL$	TYPE NLA0: /OUTPUT='TEMPFILE_2'
$!RL$	SET FILE/VERSION_LIMIT=0 'TEMPFILE_2'
$!RL$	IF F$SEARCH(TEMPFILE_4) .NES. "" THEN DELETE 'TEMPFILE_4';*
$!RL$	TYPE NLA0: /OUTPUT='TEMPFILE_4'
$!RL$	SET FILE/VERSION_LIMIT=0 'TEMPFILE_4'
$	IF F$SEARCH(TEMPFILE_3) .NES. "" THEN DELETE 'TEMPFILE_3';*
$
$	OLD_SYMBOL_SCOPE = F$ENVIRONMENT("SYMBOL_SCOPE")
$	SET SYMBOL/SCOPE=(GLOBAL,LOCAL)
$
$!RL$	IF DEBUG THEN SHOW LOG SYS$OUTPUT/FULL
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MULTINET
$	THEN
$	    SET noON
$!RL$	    OPEN/WRITE FTP_DIR 'TEMPFILE_2'
$!RL$	    DEFINE SYS$OUTPUT 'TEMPFILE_4'
$	    DEFINE SYS$OUTPUT 'TEMPFILE_3'
$	    'CONFIG_COMMAND' -
		  /NOINITIALIZATION -
		  /TAKE_FILE='TEMPFILE_1'
$	    STATUS = $STATUS
$	    DEASSIGN SYS$OUTPUT
$!RL$	    CLOSE FTP_DIR
$	    SET ON
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MGFTP
$	THEN
$	    SET noON
$!RL$	    OPEN/WRITE FTP_DIR 'TEMPFILE_2'
$!RL$	    DEFINE SYS$OUTPUT 'TEMPFILE_4'
$	    DEFINE SYS$OUTPUT 'TEMPFILE_3'
$	    'CONFIG_COMMAND' -
		  'CONFIG_SITE' -
		  /USERNAME="''CONFIG_USERNAME'" -
		  /PASSWORD="''CONFIG_PASSWORD'" -
		  /INITIALIZATION='TEMPFILE_1'
$	    STATUS = $STATUS
$	    DEASSIGN SYS$OUTPUT
$!RL$	    CLOSE FTP_DIR
$	    SET noON
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_TCPWARE
$	THEN
$	    SET noON
$!RL$	    OPEN/WRITE FTP_DIR 'TEMPFILE_2'
$!RL$	    DEFINE SYS$OUTPUT 'TEMPFILE_4'
$	    DEFINE SYS$OUTPUT 'TEMPFILE_3'
$	    DEFINE/USER FTP_STARTUP 'tempfile_1'
$	    'CONFIG_COMMAND'
$	    STATUS = $STATUS
$	    DEASSIGN SYS$OUTPUT
$!RL$	    CLOSE FTP_DIR
$	    SET noON
$	ENDIF
$
$	SET SYMBOL/SCOPE=('OLD_SYMBOL_SCOPE')
$
$!RL$	IF F$SEARCH(TEMPFILE_3) .NES. "" THEN DELETE 'TEMPFILE_3';*
$!RL$	COPY/CONCATENATE 'TEMPFILE_4','TEMPFILE_2' 'TEMPFILE_3'
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Output from FTP session:"
$	IF DEBUG THEN TYPE/OUTPUT=SYS$ERROR 'TEMPFILE_3'
$
$	IF .NOT. STATUS THEN GOTO _ERROR
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$! Determine which files we will need to get from the remote system
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$	OPEN/READ FILE 'TEMPFILE_3'
$	IF F$SEARCH(TEMPFILE_1) .NES. "" THEN DELETE 'TEMPFILE_1';
$	OPEN/WRITE OUTFILE 'TEMPFILE_1'
$	TYPE NLA0: /OUTPUT='TEMPFILE_4'
$	OPEN/APPEND REPORT_FILE 'TEMPFILE_4'
$	WRITE REPORT_FILE "(This message generated by FTP_MIRROR.COM)"
$	WRITE REPORT_FILE ""
$	WRITE REPORT_FILE "New files at site: ", CONFIG_SITE
$	WRITE REPORT_FILE ""
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MULTINET
$	THEN
$	    IF CONFIG_PASSIVE THEN WRITE OUTFILE "PASSIVE ON"
$	    WRITE OUTFILE "EXIT-ON-ERROR ON"
$	    WRITE OUTFILE "PROMPT-FOR-MISSING-ARGUMENTS OFF"
$	    WRITE OUTFILE "VERBOSE"											!DM
$	    IF DEBUG THEN WRITE OUTFILE "STATISTICS"
$	    WRITE OUTFILE "CONNECT ", CONFIG_SITE
$	    WRITE OUTFILE "USER ", CONFIG_USERNAME
$	    WRITE OUTFILE "PASS ", CONFIG_PASSWORD
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE OUTFILE "STRUCTURE VMS"
$	    ELSE
$		WRITE OUTFILE "TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE OUTFILE "PWD"
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MGFTP
$	THEN
$	    WRITE OUTFILE "SET BATCH"
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE OUTFILE "SET STRUCTURE VMS"
$	    ELSE
$		WRITE OUTFILE "SET TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE OUTFILE "PWD"
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_TCPWARE
$	THEN
$	    IF CONFIG_PASSIVE THEN WRITE OUTFILE "SET PASSIVE"
$	    IF DEBUG THEN WRITE OUTFILE "SET DEBUG/CLASS=REPLIES"
$	    WRITE OUTFILE "CONNECT ", CONFIG_SITE, " ", -
		  CONFIG_USERNAME, " ", CONFIG_PASSWORD
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE OUTFILE "STRUCTURE VMS"
$	    ELSE
$		WRITE OUTFILE "TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE OUTFILE "PWD"
$	ENDIF  ! tcpware
$
$	GET_FILE_COUNT = 0
$
$	LOCAL_DIRECTORY = ""
$	LOCAL_FILENAME = ""
$ _READ_FILE_LOOP:
$	READ/END_OF_FILE=_EXIT_READ_FILE_LOOP FILE RECORD
$	IF F$EDIT(RECORD,"COLLAPSE") .EQS. "" THEN GOTO _READ_FILE_LOOP
$	IF DEBUG THEN WRITE SYS$ERROR F$FAO("-Debug- Record is: \!AS\", RECORD)
$	RECORD = F$EDIT(RECORD,"COMPRESS")
$	XXX = F$EDIT(F$ELEMENT(0," ",RECORD),"UPCASE")									!DM
$	IF XXX .EQS. "LIST" THEN GOTO _READ_FILE_LOOP									!DM
$	IF XXX .EQS. "PORT" THEN GOTO _READ_FILE_LOOP									!DM
$	IF XXX .EQS. "QUIT" THEN GOTO _READ_FILE_LOOP									!DM
$	IF XXX .EQS. "RUN" THEN GOTO _READ_FILE_LOOP									!DM
$	IF XXX .EQS. "TYPE:" THEN GOTO _READ_FILE_LOOP									!DM
$	IF XXX .EQS. "TYPE" THEN GOTO _READ_FILE_LOOP									!DM
$	IF F$EXTRACT(0,5,RECORD) .EQS. "<257 " -
	   .OR. F$EXTRACT(0,4,RECORD) .EQS. "257 "
$	THEN
$	    REMOTE_ROOT = F$ELEMENT(1," ",RECORD)
$	    IF F$EXTRACT(0,1,REMOTE_ROOT) .EQS. """" THEN REMOTE_ROOT = F$ELEMENT(1,"""",REMOTE_ROOT)
$	    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Remote root now: ", REMOTE_ROOT
$	    GOTO _READ_FILE_LOOP
$	ENDIF
$
$	IF F$EXTRACT(0,10,RECORD) .EQS. "Directory "
$	THEN 
$	    RECORD = F$EXTRACT(10,F$LENGTH(RECORD)-10,RECORD)
$	    IF DEBUG THEN WRITE SYS$ERROR F$FAO("-Debug- Record changed: \!AS\", RECORD)
$	ENDIF
$	IF F$EDIT(F$ELEMENT(0," ",RECORD),"UPCASE") .EQS. "<<<REMOTE_DIRECTORY"
$!RL	   .AND. LOCAL_DIRECTORY .EQS. ""
$	THEN
$	    LOCAL_DIRECTORY = ""
$	    RECORD = F$ELEMENT(0,">",F$ELEMENT(1," ",RECORD))
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$	    THEN
$		RECORD = RECORD + ":"
$	    ELSE
$!RL$		IF RECORD - ":" .EQS. RECORD THEN -
$!RL		   RECORD = REMOTE_ROOT - "]" + (RECORD - "[")
$		GOTO _READ_FILE_LOOP
$	    ENDIF
$	    IF DEBUG THEN WRITE SYS$ERROR F$FAO("-Debug- Record changed: \!AS\", RECORD)
$	ENDIF
$
$	IF RECORD .EQS. "" .OR. -
	   (FTP_SERVER_TYPE .NE. TYPE_UNIX .AND. -
	    RECORD .NES. F$EDIT(RECORD,"UPCASE")) THEN -
	   GOTO _READ_FILE_LOOP      ! no lowercase in files/directories
$	C = F$EXTRACT(0,1,RECORD)
$	IF C .EQS. "<" .OR. C .EQS. "%" .OR. C .EQS. "[" THEN GOTO _READ_FILE_LOOP					!DM
$	IF FTP_SERVER_TYPE .EQ. TYPE_UNIX .AND. -
	   F$TYPE(C) .EQS. "INTEGER" THEN GOTO _READ_FILE_LOOP
$	IF FTP_SERVER_TYPE .EQ. TYPE_UNIX .AND. -
	   F$ELEMENT(0," ",RECORD) .EQS. "total"
$	THEN
$	    TMP3 = F$EDIT(RECORD - F$ELEMENT(0," ",RECORD),"TRIM")
$	    IF F$TYPE(TMP3) .EQS. "INTEGER" THEN GOTO _READ_FILE_LOOP
$	ENDIF
$
$	IF F$LOCATE(":",F$ELEMENT(0," ",RECORD)) .NE. F$LENGTH(F$ELEMENT(0," ",RECORD))
$	THEN
$	    ! we have a directory
$	    LOCAL_DIRECTORY = ""
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$	    THEN
$		REMOTE_DIRECTORY = F$ELEMENT(0,":",RECORD)
$		IF F$EXTRACT(0,1,REMOTE_DIRECTORY) .NES. "/"
$		THEN
$		    IF F$EXTRACT(F$LENGTH(REMOTE_ROOT)-1,1,REMOTE_ROOT) .NES. "/" THEN -
		       REMOTE_DIRECTORY = "/" + REMOTE_DIRECTORY
$		    REMOTE_DIRECTORY = REMOTE_ROOT + REMOTE_DIRECTORY
$		ENDIF
$		IF F$EXTRACT(F$LENGTH(REMOTE_DIRECTORY)-1,1,REMOTE_DIRECTORY) -
		   .NES. "/" THEN -
		   REMOTE_DIRECTORY = REMOTE_DIRECTORY + "/"
$	    ELSE
$		REMOTE_DIRECTORY = F$ELEMENT(0," ",RECORD)
$	    ENDIF
$	    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Remote directory now: ", REMOTE_DIRECTORY
$	    ! now we have to find it in our mappings
$	    COUNT = 0
$ _FIND_LOOP: 
$	    IF COUNT .GE. CONFIG_DIR_TOTAL THEN GOTO _EXIT_FIND_LOOP
$	    TMP = F$ELEMENT(0,",",CONFIG_DIRECTORIES_'COUNT')
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$	    THEN
$		IF F$EXTRACT(0,1,TMP) .NES. "/"
$		THEN
$		    IF F$EXTRACT(F$LENGTH(REMOTE_ROOT)-1,1,REMOTE_ROOT) .NES. "/" THEN -
		       TMP = "/" + TMP
$		    TMP = REMOTE_ROOT + TMP
$		ENDIF
$	    ELSE
$		IF F$EXTRACT(0,2,TMP) .EQS. "[." THEN -
		   TMP = F$EXTRACT(0,F$LENGTH(REMOTE_ROOT)-1,REMOTE_ROOT) + -
		   F$EXTRACT(1,999,TMP)
$		IF F$EXTRACT(0,1,TMP) .EQS. "[" THEN -
		   TMP = F$ELEMENT(0,"[",REMOTE_ROOT) + TMP
$	    ENDIF
$	    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Remote directory to check for: ", TMP
$	    ENDING = "...]"
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX THEN ENDING = "..."
$	    LE = F$LENGTH(ENDING)
$	    IF F$EXTRACT(F$LENGTH(TMP)-LE,LE,TMP) -
	       .EQS. ENDING
$	    THEN
$		TMP = F$EXTRACT(0,F$LENGTH(TMP)-F$LENGTH(ENDING),TMP)
$		IF TMP .EQS. F$EXTRACT(0,F$LENGTH(TMP),REMOTE_DIRECTORY)
$		THEN
$		    ! we have a mapping
$		    LOCAL_DIRECTORY = F$ELEMENT(1,",",CONFIG_DIRECTORIES_'COUNT')
$		    IF F$EXTRACT(F$LENGTH(LOCAL_DIRECTORY)-4,4,LOCAL_DIRECTORY) .EQS. "...]"
$		    THEN
$			TMP2 = REMOTE_DIRECTORY
$			IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$			THEN
$			    ALLOWED_CHARACTERS = "ABCDEFGHIKJLMNOPQRSTUVWXYZabcdefghikjlmnopqrstuvwxyz0123456789-_$/."
$			    I = 0
$ LOOP_CHARACTERS1:	    
$			    C = F$EXTRACT(I,1,TMP2)
$			    IF C .EQS. "." THEN -
			       TMP2 = F$EXTRACT(0,I,TMP2) + "_" + F$EXTRACT(I+1,F$LENGTH(TMP2)-I-1,TMP2)
$			    IF C .EQS. "/"
$			    THEN
$				IF I .LT. F$LENGTH(TMP2)-1
$				THEN
$				    TMP2 = F$EXTRACT(0,I,TMP2) + "." + F$EXTRACT(I+1,F$LENGTH(TMP2)-I-1,TMP2)
$				ELSE
$				    TMP2 = F$EXTRACT(0,I,TMP2) + "]"
$				ENDIF
$			    ENDIF
$			    IF ALLOWED_CHARACTERS - C .EQS. ALLOWED_CHARACTERS THEN -
			       TMP2 = F$EXTRACT(0,I,TMP2) + "$" + F$EXTRACT(I+1,F$LENGTH(TMP2)-I-1,TMP2)
$			    I = I + 1
$			    IF I .LT. F$LENGTH(TMP2) THEN GOTO LOOP_CHARACTERS1
$			    TMP2 = TMP2
$			ENDIF
$			IF DEBUG THEN -
			   WRITE SYS$ERROR "-Debug- TMP = """,TMP,""""
$			IF DEBUG THEN -
			   WRITE SYS$ERROR "-Debug- TMP2 = """,TMP2,""""
$			IF DEBUG THEN -
			   WRITE SYS$ERROR "-Debug- LOCAL_DIRECTORY = """,-
			   LOCAL_DIRECTORY,""""
$			LOCAL_DIRECTORY = F$EXTRACT(0,F$LENGTH(LOCAL_DIRECTORY)-4,LOCAL_DIRECTORY) + F$EXTRACT(F$LENGTH(TMP)-(FTP_SERVER_TYPE .EQ. TYPE_UNIX),999,TMP2)
$
$		    ENDIF
$		    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Local directory now: ", LOCAL_DIRECTORY
$		ENDIF
$	    ELSE
$		IF FTP_SERVER_TYPE .EQ. TYPE_UNIX -
		   .AND. F$EXTRACT(F$LENGTH(TMP)-1,1,TMP) .NES. "/" THEN -
		   TMP = TMP + "/"
$		IF TMP .EQS. REMOTE_DIRECTORY
$		THEN
$		    ! we have a mapping
$		    LOCAL_DIRECTORY = F$ELEMENT(1,",",CONFIG_DIRECTORIES_'COUNT') - "..."
$		    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Local directory now: ", LOCAL_DIRECTORY
$		ENDIF
$	    ENDIF
$	    COUNT = COUNT + 1
$	    GOTO _FIND_LOOP
$ _EXIT_FIND_LOOP: 
$	    IF LOCAL_DIRECTORY .EQS. "" 
$	    THEN 
$		WRITE SYS$ERROR "Error - no mapping for remote directory ", REMOTE_DIRECTORY
$		WRITE SYS$ERROR "Error - skipping directory ", REMOTE_DIRECTORY
$	    ELSE
$		IF F$PARSE(LOCAL_DIRECTORY) .EQS. "" THEN CREATE/DIRECTORY/LOG 'LOCAL_DIRECTORY'
$	    ENDIF
$	    GOTO _READ_FILE_LOOP
$	ENDIF ! f$locate
$
$	IF LOCAL_DIRECTORY .EQS. "" THEN GOTO _READ_FILE_LOOP
$
$!
$!!!  Determine if we need to get a file
$!
$
$	IF F$EDIT(F$ELEMENT(0," ",RECORD),"COLLAPSE") .NES. ""
$	THEN
$	    GET_FILE = FALSE
$	    ! assume we have a remote filename
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$	    THEN
$		RECORD_C = F$EDIT(RECORD,"COMPRESS,TRIM")
$		REMOTE_PROTECTION = F$ELEMENT(0," ",RECORD_C)
$		REMOTE_LINKS = F$ELEMENT(1," ",RECORD_C)
$		REMOTE_USER = F$ELEMENT(2," ",RECORD_C)
$		REMOTE_GROUP = F$ELEMENT(3," ",RECORD_C)
$		REMOTE_SIZE = F$ELEMENT(4," ",RECORD_C)
$		REMOTE_MONTH = F$ELEMENT(5," ",RECORD_C)
$		REMOTE_DAY = F$ELEMENT(6," ",RECORD_C)
$		REMOTE_YEARORTIME = F$ELEMENT(7," ",RECORD_C)
$		IF REMOTE_YEARORTIME - ":" .EQS. REMOTE_YEARORTIME
$		THEN ! Mon day year
$		    REMOTE_TIMESTAMP = F$CVTIME(REMOTE_DAY+"-"+REMOTE_MONTH+"-"+REMOTE_YEARORTIME+":0:0:0","COMPARISON")
$		ELSE
$		    REMOTE_TIMESTAMP = F$CVTIME(REMOTE_DAY+"-"+REMOTE_MONTH+"-"+F$CVTIME("",,"YEAR")+":"+REMOTE_YEARORTIME,"COMPARISON")
$		    IF REMOTE_TIMESTAMP .GTS. F$CVTIME("+1-","COMPARISON") THEN -
		       REMOTE_TIMESTAMP = F$CVTIME(REMOTE_DAY+"-"+REMOTE_MONTH+"-"+F$CVTIME("-365-",,"YEAR")+":"+REMOTE_YEARORTIME,"COMPARISON")
$		ENDIF
$		FILENAME = RECORD_C - REMOTE_PROTECTION - REMOTE_LINKS -
			   - REMOTE_USER - REMOTE_GROUP - REMOTE_SIZE -
			   - REMOTE_MONTH - REMOTE_DAY - REMOTE_YEARORTIME
$		FILENAME = F$EDIT(FILENAME,"TRIM")
$	    ELSE
$		FILENAME = F$ELEMENT(0," ",RECORD)
$		REMOTE_TIMESTAMP = F$ELEMENT(2," ",RECORD) + " " + F$ELEMENT(3," ",RECORD)
$		IF F$EDIT(REMOTE_TIMESTAMP,"COLLAPSE") .EQS. "" 
$		THEN
$		    ! date is on the next line...
$ _READ_DATE_LINE:  
$		    READ/END_OF_FILE=_EXIT_READ_FILE_LOOP FILE RECORD
$! Watch out.  Some client, like the MadGoat FTP client, will sputter lines
$! like this right in the middle of the directory output:
$!	<226 File transfer Okay; Closing data connection.
$! Fortunately, it is very easy to check, since we expect this line to start
$! with a space
$		    IF F$EXTRACT(0,1,RECORD) .NES. " " THEN -
		       GOTO _READ_DATE_LINE
$		    RECORD = F$EDIT(RECORD,"COMPRESS")
$		    REMOTE_TIMESTAMP = F$ELEMENT(2," ",RECORD) + " " + F$ELEMENT(3," ",RECORD)
$		ENDIF
$		REMOTE_TIMESTAMP = F$CVTIME(REMOTE_TIMESTAMP,"COMPARISON")
$	    ENDIF
$	    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Remote file is: ", FILENAME
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$	    THEN
$		IF F$EXTRACT(0,1,REMOTE_PROTECTION) .NES. "-" THEN -
		   GOTO _READ_FILE_LOOP
$	    ELSE
$		IF F$PARSE(FILENAME,,,"TYPE") .EQS. ".DIR" THEN -
		   GOTO _READ_FILE_LOOP
$	    ENDIF
$
$	    OLD_LOCAL_FILENAME = LOCAL_FILENAME
$	    IF FTP_SERVER_TYPE .EQS. TYPE_UNIX
$	    THEN
$		LOCAL_FILENAME = FILENAME
$		IF F$EXTRACT(F$LENGTH(LOCAL_FILENAME)-3,3,LOCAL_FILENAME) .EQS. ".gz"
$		THEN
$		    LOCAL_FILENAME = F$EXTRACT(0,F$LENGTH(LOCAL_FILENAME)-3,LOCAL_FILENAME)
$		    IF LOCAL_FILENAME - "." .EQS. LOCAL_FILENAME
$		    THEN
$			LOCAL_FILENAME = LOCAL_FILENAME + ".gz"
$		    ELSE
$			LOCAL_FILENAME = LOCAL_FILENAME + "-gz"
$		    ENDIF
$		ENDIF
$		IF F$EXTRACT(F$LENGTH(LOCAL_FILENAME)-2,2,LOCAL_FILENAME) .EQS. ".Z"
$		THEN
$		    LOCAL_FILENAME = F$EXTRACT(0,F$LENGTH(LOCAL_FILENAME)-2,LOCAL_FILENAME)
$		    IF LOCAL_FILENAME - "." .EQS. LOCAL_FILENAME
$		    THEN
$			LOCAL_FILENAME = LOCAL_FILENAME + ".Z"
$		    ELSE
$			LOCAL_FILENAME = LOCAL_FILENAME + "_Z"
$		    ENDIF
$		ENDIF
$		ALLOWED_CHARACTERS = "ABCDEFGHIKJLMNOPQRSTUVWXYZabcdefghikjlmnopqrstuvwxyz0123456789-_$."
$		IF DEBUG THEN WRITE SYS$ERROR "-Debug- (1) LOCAL_FILENAME=""",-
		   LOCAL_FILENAME,""""
$		I = 0
$ LOOP_CHARACTERS2: 
$		C = F$EXTRACT(I,1,LOCAL_FILENAME)
$		IF C .EQS. "." -
		   .AND. LOCAL_FILENAME - "." - "." .NES. LOCAL_FILENAME - "." THEN -
		   LOCAL_FILENAME = F$EXTRACT(0,I,LOCAL_FILENAME) + "_" + F$EXTRACT(I+1,F$LENGTH(LOCAL_FILENAME)-I-1,LOCAL_FILENAME)
$		IF ALLOWED_CHARACTERS - C .EQS. ALLOWED_CHARACTERS THEN -
		   LOCAL_FILENAME = F$EXTRACT(0,I,LOCAL_FILENAME) + "$" + F$EXTRACT(I+1,F$LENGTH(LOCAL_FILENAME)-I-1,LOCAL_FILENAME)
$		I = I + 1
$		IF I .LT. F$LENGTH(LOCAL_FILENAME) THEN GOTO LOOP_CHARACTERS2
$		IF DEBUG THEN WRITE SYS$ERROR "-Debug- (2) LOCAL_FILENAME=""",-
		   LOCAL_FILENAME,""""
$		LOCAL_FILENAME = F$PARSE(";",LOCAL_FILENAME,LOCAL_DIRECTORY)
$		IF DEBUG THEN WRITE SYS$ERROR "-Debug- (3) LOCAL_FILENAME=""",-
		   LOCAL_FILENAME,""""
$	    ELSE
$		LOCAL_FILENAME = F$PARSE(";",FILENAME,LOCAL_DIRECTORY)
$	    ENDIF
$	    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Local file is: ", LOCAL_FILENAME
$	    IF OLD_LOCAL_FILENAME .EQS. LOCAL_FILENAME
$	    THEN
$		IF DEBUG THEN WRITE SYS$ERROR "-Debug- Skipping file ", FILENAME, " (it's an older version)"
$		GOTO _READ_FILE_LOOP
$	    ENDIF
$	    IF F$SEARCH(LOCAL_FILENAME) .EQS. ""
$	    THEN
$		! no such file exists, so we need to create directory (if
$		! necessary) and pull the file over
$		IF CONFIG_LAST_TIME_FILE .EQS. "" -
		   .OR. CONFIG_LAST_TIME .LTS. REMOTE_TIMESTAMP THEN GET_FILE = TRUE
$		IF GET_FILE .AND. DEBUG THEN -
		   WRITE SYS$ERROR "-Debug- Copying file ", REMOTE_DIRECTORY, FILENAME, " to ", LOCAL_FILENAME, " (we don't have a copy)."
$	    ELSE
$		! check dates to see if we should get a new copy
$		LOCAL_TIMESTAMP = F$CVTIME(F$FILE(LOCAL_FILENAME,"RDT"),"COMPARISON")
$		IF DEBUG THEN WRITE SYS$ERROR "-Debug- Local file date: ", LOCAL_TIMESTAMP, ", remote file date: ", REMOTE_TIMESTAMP
$		IF LOCAL_TIMESTAMP .LES. REMOTE_TIMESTAMP
$		THEN 
$		    IF CONFIG_LAST_TIME_FILE .EQS. "" -
		       .OR. CONFIG_LAST_TIME .LTS. REMOTE_TIMESTAMP THEN GET_FILE = TRUE
$		    IF GET_FILE .AND. DEBUG THEN -
		       WRITE SYS$ERROR "-Debug- Getting file ", REMOTE_DIRECTORY, FILENAME, " to ", LOCAL_FILENAME," (we have an old copy)."
$		ENDIF
$	    ENDIF
$	    IF GET_FILE 
$	    THEN 
$		GET_FILE_COUNT = GET_FILE_COUNT + 1
$		WRITE OUTFILE "GET """, REMOTE_DIRECTORY, FILENAME, """ ", -
		      LOCAL_FILENAME
$		WRITE REPORT_FILE F$FAO("  !3UL.  !AS!AS -> !AS", -
					GET_FILE_COUNT, -
					REMOTE_DIRECTORY, FILENAME, -
					LOCAL_FILENAME)
$	    ENDIF
$	ENDIF
$
$	GOTO _READ_FILE_LOOP
$ _EXIT_READ_FILE_LOOP:	
$	CLOSE FILE
$	WRITE OUTFILE "EXIT"
$	CLOSE OUTFILE
$	CLOSE REPORT_FILE
$
$	IF F$SEARCH(TEMPFILE_2) .NES. "" THEN DELETE 'TEMPFILE_2';
$
$	IF GET_FILE_COUNT .EQ. 0
$	THEN
$	    WRITE SYS$OUTPUT "No files to get.  Exiting."
$	    GOTO _SUBMIT
$	ENDIF
$	WRITE SYS$OUTPUT F$FAO("!/Getting !UL file!%S!/", GET_FILE_COUNT)
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!  Get the new files from the remote system
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Contents of input file:"
$	IF DEBUG THEN TYPE/OUTPUT=SYS$ERROR 'TEMPFILE_1'
$
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Connecting to remote system..."
$	OLD_SYMBOL_SCOPE = F$ENVIRONMENT("SYMBOL_SCOPE")
$	SET SYMBOL/SCOPE=(GLOBAL,LOCAL)
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MULTINET 
$	THEN
$	    SET noON
$	    DEFINE/USER_MODE SYS$OUTPUT 'TEMPFILE_2'
$	    'CONFIG_COMMAND' -
		  /NOINITIALIZATION -
		  /TAKE_FILE='TEMPFILE_1'
$	    STATUS = $STATUS
$	    SET ON
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MGFTP
$	THEN
$	    SET noON
$	    DEFINE/USER_MODE SYS$OUTPUT 'TEMPFILE_2'
$	    'CONFIG_COMMAND' -
		  'CONFIG_SITE' -
		  /USERNAME="''CONFIG_USERNAME'" -
		  /PASSWORD="''CONFIG_PASSWORD'" -
		  /INITIALIZATION='TEMPFILE_1'
$	    STATUS = $STATUS
$	    SET ON
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_TCPWARE
$	THEN
$	    SET noON
$	    DEFINE/USER_MODE SYS$OUTPUT 'TEMPFILE_2'
$	    DEFINE/USER FTP_STARTUP 'tempfile_1'
$	    'CONFIG_COMMAND'
$	    STATUS = $STATUS
$	    SET noON
$	ENDIF
$
$	SET SYMBOL/SCOPE=('OLD_SYMBOL_SCOPE')
$
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Output from FTP session:"
$	IF DEBUG THEN TYPE/OUTPUT=SYS$ERROR 'TEMPFILE_2'
$
$	IF CONFIG_LAST_TIME_FILE .NES. "" .AND. .NOT. STATUS
$	THEN
$	    OPEN/WRITE FOO 'CONFIG_LAST_TIME_FILE'
$	    WRITE FOO CONFIG_NEXT_TIME
$	    CLOSE FOO
$	ENDIF
$
$	IF CONFIG_MAILTO .NES. ""
$	THEN
$	    IF STATUS
$	    THEN
$		MAIL_SUBJECT = F$FAO("!AS: !UL file!%S transferred to local system", -
				     CONFIG_SITE, GET_FILE_COUNT)
$		MAIL_PN = F$FAO("!AS: !UL file!%S", -
				CONFIG_SITE, GET_FILE_COUNT)
$	    ELSE
$		SHOW SYMBOL STATUS
$		MAIL_SUBJECT = F$FAO("!AS: Following files were not transferred - check logs", -
				     CONFIG_SITE)
$		MAIL_PN = F$FAO("!AS: Failure!!", CONFIG_SITE)
$	    ENDIF
$	    SET noON
$	    MAIL 'TEMPFILE_4' 'CONFIG_MAILTO' -
		 /SUBJECT="''MAIL_SUBJECT'" -
		 /PERSONAL_NAME="''MAIL_PN'"
$	    SET ON
$	ENDIF
$
$!
$!!!  Purge local directories
$!
$
$	COUNT = 0
$ _PURGE_LOOP: 
$	IF COUNT .GE. CONFIG_DIR_TOTAL THEN GOTO _EXIT_PURGE_LOOP
$	FOO = CONFIG_DIRECTORIES_'COUNT'
$	PURGE/LOG 'F$ELEMENT(1,",",FOO)'*.*
$	COUNT = COUNT + 1
$	GOTO _PURGE_LOOP
$_EXIT_PURGE_LOOP:
$
$_SUBMIT:
$	IF CONFIG_SUBMIT_AFTER .NES. "NONE"
$	THEN
$	    SET VERIFY
$	    SUBMIT -
		   /NOTIFY -
		   /LOG_FILE=FTP_MIRROR.LOG -
		   /PARAMETERS='F$ELEMENT(0,";",CONFIGURATION_FILE)' -
		   /noPRINTER -
		   /QUEUE='CONFIG_QUEUE' -
		   /NAME="FTP_Mirror" -
		   /AFTER="''CONFIG_SUBMIT_AFTER'" -
		   /KEEP -
		   'F$ELEMENT(0,";",F$ENVIRONMENT("PROCEDURE"))' 
$	    SET NOVERIFY
$	ENDIF
$	GOTO _EXIT
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$ _EXIT: 
$	GOSUB _CLEANUP
$	WRITE SYS$OUTPUT "Leaving FTP_Mirror ..."
$	IF F$TYPE(ORIGINAL_PRIV) THEN JUNK = F$SETPRV(ORIGINAL_PRIV)
$	VERIFY = F$VERIFY(VERIFY)
$	EXIT 1
$
$ _NO_CONFIG_FILE: 
$	WRITE SYS$ERROR "Could not find configuration file ",P1
$	WRITE SYS$ERROR "Aborting..."
$	GOTO _EXIT
$ 
$ _ERROR: 
$	ERROR_STATUS = $STATUS
$	WRITE SYS$ERROR "Unexpected error (%X''F$FAO("!XL",ERROR_STATUS)') in FTP_MIRROR.COM"
$	GOSUB _CLEANUP
$	IF F$TYPE(ORIGINAL_PRIV) THEN JUNK = F$SETPRV(ORIGINAL_PRIV)
$	VERIFY = F$VERIFY(VERIFY)
$	EXIT ERROR_STATUS
$
$ _ABORT: 
$	WRITE SYS$ERROR "User aborted FTP_MIRROR.COM"
$	GOTO _EXIT
$
$ _CLEANUP: 
$	CLOSE/NOLOG FILE
$	CLOSE/NOLOG OUTFILE
$	CLOSE/NOLOG REPORT_FILE
$	IF .NOT. DEBUG .AND. F$SEARCH(TEMPFILE_1) .NES. "" THEN -
	   DELETE 'TEMPFILE_1';*
$	IF .NOT. DEBUG .AND. F$SEARCH(TEMPFILE_2) .NES. "" THEN -
	   DELETE 'TEMPFILE_2';*
$	IF .NOT. DEBUG .AND. F$SEARCH(TEMPFILE_3) .NES. "" THEN -
	   DELETE 'TEMPFILE_3';*
$	IF .NOT. DEBUG .AND. F$SEARCH(TEMPFILE_4) .NES. "" THEN -
	   DELETE 'TEMPFILE_4';*
$	RETURN
================================================================================
Archive-Date: Sat, 10 Apr 1999 10:24:18 +0200
Date: Sat, 10 Apr 1999 10:24:12 +0200
Message-ID: <1855-Sat10Apr1999102412+0200-levitte@lp.se>
From: Richard Levitte - VMS Whacker <levitte@lp.se>
Reply-To: bugs@free.lp.se, levitte@lp.se
To: bugs@free.lp.se, SYSTEM@wolverine.acornsw.com
In-Reply-To: <990409113034.21600131@wolverine.acornsw.com> (SYSTEM@wolverine.acornsw.com)
Subject: Re: Fixed a few problems with ftp_mirror.com
MIME-Version: 1.0
Content-Type: Text/Plain; Charset=ISO-8859-1
Content-Transfer-Encoding: 8bit

Thank you for the fix.  I'll test it a couple of days on my systems and
then release it.

-- 
R Levitte, Levitte Programming;  Spannv. 38, I;  S-168 35  Bromma;  SWEDEN
    Tel: +46-8-26 52 47; Cell: +46-708-26 53 44; Fax: +46-708-26 53 88
  PGP key fingerprint = 35 3E 6C 9E 8C 97 85 24  BD 9F D1 9E 8F 75 23 6B
 http://richard.levitte.org/pubkey2.asc for my public key.  levitte@lp.se

          "price, performance, quality.  Choose any two you like"
================================================================================
Archive-Date: Tue, 13 Apr 1999 17:45:17 +0200
Date: Tue, 13 Apr 1999 11:45:08 -0400
From: SYSTEM@wolverine.acornsw.com
Reply-To: bugs@free.lp.se, SYSTEM@wolverine.acornsw.com
To: bugs@free.lp.se
Message-ID: <990413114508.21a00185@wolverine.acornsw.com>
Subject: Fixed a couple more things in FTP_MIRROR.COM (added a new feature as well).

$	VERIFY = 'F$VERIFY(F$TRNLNM("FTP_MIRROR_VERIFY"))'
$	SET = "SET"
$	SET SYMBOL/SCOPE=(noGLOBAL,noLOCAL)
$	GOTO _START_FTP_MIRROR

DESCRIPTION:

  Automates mirroring a remote FTP site.

PARAMETERS:

  P1 - configuration filename

REQUIREMENTS:

Due to the different commands used by FTP Clients, only a few FTP Clients are 
supported.  Due to the different output generated by different FTP Servers,
parsing routines have only been written for a few FTP Servers.

  o one of the following FTP Clients (on your system):
      - MultiNet 
      - MadGoat FTP
      - TCPware

  o mirrored against one of the following FTP Servers (on the remote system):
      - MultiNet
      - MadGoat FTP
      - TCPware
      - Unix

 =----------------------------------------------------------------------=

Copyright © 1994 by Dan Wing.
Copyright © 1997 by MadGoat Software, Inc.
Copyright © 1998 by Richard Levitte.
Copyright © 1999 by Dick Munroe

This code may be freely distributed and modified for no commercial gain
as long as this copyright notice is retained.  This program is supplied
'as-is', and with no warranty.

Created September 21, 1994, by Dan Wing, TGV <dwing@Cisco.com>
Hacked a lot by Richard Levitte <richard@levitte.org>
Features added by Hunter Goatley <goathunter@madgoat.com>

Please send bug reports to <bugs@free.lp.se>.

 =----------------------------------------------------------------------=

  REVERSE CHRONOLOGICAL MODIFICATION HISTORY
  ------------------------------------------

  T0.8-5  13-APR-1999  Dick Munroe <munroe@acornsw.com>
     Some FTP servers have a time limit on them.  I'm adding a
     MAXIMUM_FILES parameter to the configuration that allows some
     control over the load placed on the server.  Once the maximum
     number of files have been transferred, then the job is rescheduled.
     Frequently FTP servers are busy and you can't get logged in, so
     check for the 530 status and reschedule the job if that happens.
     To avoid spurious errors, check to see if directories contain
     files during the purge processing.

  T0.8-4  09-APR-1999  Dick Munroe <munroe@acornsw.com>
     Using a multinet FTP client requires that the VERBOSE mode of
     FTP transfer be used.  This, in turn, left stuff in the log files
     that, for some reason, the command procedure didn't know how to
     process.  There were similar issues for hooking up to aol.com, so
     now this procedure seems to work with all the ftp sites that I'm
     using regularly.

  T0.8-3  23-APR-1998  Richard Levitte <richard@levitte.org>
     A small bug corrected.  REMOTE_DIRECTORY wasn't set correctly
     under some circumstances.  Under others, it was set when it
     really shoulden't.

  T0.8-2  20-APR-1998  Richard Levitte <richard@levitte.org>
     Worked around the fact that the MadGoat client (and perhaps others)
     sputters lines like the following one right in the middle of the
     directory output:

	<226 File transfer Okay; Closing data connection.

  T0.8-1  07-APR-1998  Richard Levitte <richard@levitte.org>
     Corrected a small bug that caused a erroneous download to be made
     for a serie of Unix directories.  Of course, if `ls' could output
     the directory name for the first directory listed, we wouldn't
     have these problems...

  T0.8	   6-APR-1998	Hunter Goatley <goathunter@MadGoat.com>
     Explicitly enable or disable passive mode according to file setting.

  T0.7    06-APR-1998  Richard Levitte <richard@levitte.org>
     Merged in changes that Hunter Goatley <goathunter@madgoat.com>
     added in 27-MAY-1997.  His comment was:

	Updated for newer MGFTP releases and for TCPware.

  T0.6    05-APR-1998  Richard Levitte <richard@levitte.org>
     - Now understands the output from a Unix FTP server, and can
       download files from it.  ALL files are currently downloaded in
       Image mode.
     - An added feature is that "/..." at the end of a Unix directory
       specification means the same thing as the standard VMS
       ellipsis.
     - CAUTION:  Unix file specifications can ONLY be used as the
       first argument of the DIRECTORY configuratoin parameter.
     - Name conversion for Unix file specifications is done according
       to the following rules:
         1. An ending ".gz" is changed to "-gz" if there is another
            dot in the file name.
         2. And ending ".Z is changed to "_Z" if there is another dot
            in the file name.
         3. All remaining dots except the last are changed to
            underscores, except the last one in a file name.
         4. All other characters that are not legal in a VMS file name
            are changed to dollars.
     - A hack that saves the current time in a file has been added.
       If that file is found and there is a time specification in it,
       it is used to limit the download of file to those newer than
       that time.  The name of this file is configurable.
     - A mail address to send logs to is configurable.

  T0.5	  02-APR-1998  Richard Levitte <richard@levitte.org>
     Many hacks, among other supporting elipsis in directory specs,
     and support for the Process Software FTP server.  Unfortunatelly,
     I haven't made many notes of my changes.

  T0.0    25-OCT-1994  Dan Wing, wing@tgv.com
     Initial release.

$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$ _START_FTP_MIRROR: 
$
$	ON WARNING THEN GOTO _ERROR
$	ON CONTROL_Y THEN GOTO _ABORT
$
$	FTP_MIRROR_VERSION = "T0.8-3 BETA TEST Prerelease 5"								!DM
$	WRITE SYS$OUTPUT F$FAO("!/FTP_Mirror, version !AS.!/Started by !AS on node !AS on !AS, !AS !8AS.", -
			       FTP_MIRROR_VERSION, -
			       F$EDIT(F$GETJPI(0,"USERNAME"),"TRIM"), -
			       F$GETSYI("NODENAME"), -
			       F$CVTIME(,,"WEEKDAY"), -
			       F$CVTIME(,"ABSOLUTE","DATE"), -
			       F$CVTIME(,,"TIME"))
$
$	TRUE = 1
$	FALSE = 0
$	DEBUG = FALSE
$	IF F$TRNLNM("FTP_MIRROR_DEBUG") THEN DEBUG = TRUE
$	IF DEBUG THEN WRITE SYS$ERROR "FTP_Mirror debugging enabled."
$
$! setup defaults.  These can be overridden in the configuration file
$
$	CONFIG_FTP_CLIENT           = "MadGoat FTP"
$	CONFIG_COMMAND              = "FTP"
$	CONFIG_FTP_SERVER           = "MadGoat FTP"
$	CONFIG_SITE                 = ""
$	CONFIG_USERNAME             = "anonymous"
$	IF F$TRNLNM("UCX$INET_HOST") .NES. "" THEN CONFIG_PASSWORD = "mirror@" + F$TRNLNM("UCX$INET_HOST")
$	IF F$TRNLNM("MULTINET_HOST_NAME") .NES. "" THEN CONFIG_PASSWORD = "mirror@" + F$TRNLNM("MULTINET_HOST_NAME")
$	CONFIG_PASSIVE              = FALSE
$	CONFIG_SUBMIT_AFTER         = "+12:00:00"
$	CONFIG_QUEUE                = "SYS$BATCH"
$	CONFIG_FILE_TRANSFER        = "VMS"
$	CONFIG_LAST_TIME_FILE       = ""
$	CONFIG_MAILTO               = ""
$	CONFIG_MAXIMUM_FILES	    = %X7FFFFFFF									!DM
$
$	VALID_CONFIGURATION = TRUE           ! assume the best
$
$	TEMPFILE_1 = "SYS$SCRATCH:FTP_MIRROR_1_" + F$GETJPI(0,"PID") + ".TMP"
$	TEMPFILE_2 = "SYS$SCRATCH:FTP_MIRROR_2_" + F$GETJPI(0,"PID") + ".TMP"
$	TEMPFILE_3 = "SYS$SCRATCH:FTP_MIRROR_3_" + F$GETJPI(0,"PID") + ".TMP"
$	TEMPFILE_4 = "SYS$SCRATCH:FTP_MIRROR_4_" + F$GETJPI(0,"PID") + ".TMP"
$
$	CONFIG_LAST_TIME = ""
$	CONFIG_DIR_TOTAL = 0
$
$	TYPE_MULTINET = 1
$	TYPE_MGFTP    = 2
$	TYPE_TCPWARE  = 3
$	TYPE_UNIX     = 128
$	TYPE_OTHER    = 255
$
$	IF P1 .EQS. "" THEN P1 = "FTP_MIRROR.DAT"
$! make sure CONFIGURATION_FILE contains a full path, but also make sure
$! you get the right directory.  Guess what F$PARSE does to non-concealed
$! multivalued logical names.  It's not a pretty sight.  --  Richard Levitte
$	CONFIGURATION_FILE = F$SEARCH(P1)
$	IF CONFIGURATION_FILE .EQS. "" THEN GOTO _NO_CONFIG_FILE
$	GOSUB _CLEANUP
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$	OPEN/READ/ERROR=_ERROR FILE 'CONFIGURATION_FILE'
$ _CONFIG_LOOP:	
$	READ/END_OF_FILE=_EXIT_CONFIG_LOOP/ERROR=_ERROR FILE RECORD
$	RECORD = F$EDIT(RECORD,"COMPRESS,UNCOMMENT")
$	IF RECORD .EQS. "" THEN GOTO _CONFIG_LOOP
$
$	PARA1 = F$EDIT(F$ELEMENT(0," ",RECORD),"UPCASE")
$	PARA2 = F$ELEMENT(1," ",RECORD)
$	PARA3 = F$ELEMENT(2," ",RECORD)
$  
$	VALID_RECORD = FALSE
$
$	IF PARA1 .EQS. "SITE"
$	THEN
$	    CONFIG_SITE = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "USERNAME"
$	THEN
$	    CONFIG_USERNAME = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "PASSWORD"
$	THEN
$	    CONFIG_PASSWORD = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "DIRECTORY"
$	THEN
$	    CONFIG_DIRECTORIES_'CONFIG_DIR_TOTAL' = PARA2 + "," + PARA3
$	    CONFIG_DIR_TOTAL = CONFIG_DIR_TOTAL + 1
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "COMMAND"
$	THEN
$	    CONFIG_COMMAND = F$EXTRACT(F$LOCATE(" ",RECORD)+1,-1,RECORD)
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "PASSIVE"
$	THEN
$	    CONFIG_PASSIVE = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "PRIV"
$	THEN
$	    ORIGINAL_PRIV = F$SETPRV(PARA2)
$	    IF .NOT. F$PRIVILEGE(PARA2) THEN WRITE SYS$OUTPUT "%%Warning - not all requested privileges are authorized."
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "SUBMIT_AFTER"
$	THEN
$	    CONFIG_SUBMIT_AFTER = F$EDIT("''PARA2' ''PARA3'","TRIM")
$	    IF F$EDIT(PARA2,"UPCASE") .EQS. "NONE" -
	       .OR. F$EDIT(PARA3,"UPCASE") .EQS. "ONE" THEN -
	       CONFIG_SUBMIT_AFTER = "NONE"
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "BATCH_QUEUE"
$	THEN
$	    CONFIG_QUEUE = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "FTP_CLIENT"
$	THEN
$	    CONFIG_FTP_CLIENT = F$EDIT(PARA2,"UPCASE")
$	    IF CONFIG_FTP_CLIENT .EQS. "MULTINET" 
$	    THEN 
$		CONFIG_FTP_CLIENT = "MultiNet"
$		CONFIG_COMMAND = "MULTINET FTP"
$		VALID_RECORD = TRUE
$	    ENDIF
$	    IF CONFIG_FTP_CLIENT .EQS. "MADGOAT" -
	       .OR. CONFIG_FTP_CLIENT .EQS. "MADGOAT_FTP"
$	    THEN 
$		CONFIG_FTP_CLIENT = "MadGoat FTP"
$		CONFIG_COMMAND = "FTP"
$		VALID_RECORD = TRUE
$	    ENDIF
$	    IF CONFIG_FTP_CLIENT .EQS. "TCPWARE"
$	    THEN
$		CONFIG_FTP_CLIENT = "TCPware"
$		CONFIG_COMMAND = "FTP"
$		VALID_RECORD = TRUE
$	    ENDIF
$	ENDIF
$
$	IF PARA1 .EQS. "FTP_SERVER"
$	THEN
$	    CONFIG_FTP_SERVER = F$EDIT(PARA2,"UPCASE")
$	    IF CONFIG_FTP_SERVER .EQS. "MULTINET" THEN -
	       CONFIG_FTP_SERVER = "MultiNet"
$	    IF CONFIG_FTP_SERVER .EQS. "MADGOAT" -
	       .OR. CONFIG_FTP_SERVER .EQS. "MADGOAT_FTP" -
	       THEN CONFIG_FTP_SERVER = "MadGoat FTP"
$	    IF CONFIG_FTP_SERVER .EQS. "TCPWARE" THEN -
	       CONFIG_FTP_SERVER = "TCPware"
$	    IF CONFIG_FTP_SERVER .EQS. "UNIX" THEN -
	       CONFIG_FTP_SERVER = "Unix"
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "FILE_TRANSFER"
$	THEN
$	    CONFIG_FILE_TRANSFER = F$EDIT(PARA2,"UPCASE")
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "LAST_TIME_FILE"
$	THEN
$	    CONFIG_LAST_TIME_FILE = F$EDIT(PARA2,"UPCASE")
$	    IF F$SEARCH(CONFIG_LAST_TIME_FILE) .NES. ""
$	    THEN
$		OPEN/READ FOO 'CONFIG_LAST_TIME_FILE'
$		READ FOO CONFIG_LAST_TIME
$		CONFIG_LAST_TIME = F$CVTIME(CONFIG_LAST_TIME,"COMPARISON")
$		CLOSE FOO
$	    ELSE
$		CONFIG_LAST_TIME = "1-JAN-1900"
$	    ENDIF
$	    ! We remove oen day just to make sure we get all files in
$	    ! spite of all kinds of timezone junk.  So we might get
$	    ! duplicates at times...  So what?
$	    CONFIG_NEXT_TIME = F$CVTIME("-1-","ABSOLUTE")
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "MAILTO"
$	THEN
$	    CONFIG_MAILTO = F$EDIT(PARA2,"UPCASE")
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "MAXIMUM_FILES"											!DM
$	THEN														!DM
$	    CONFIG_MAXIMUM_FILES = F$INTEGER(F$EDIT(PARA2,"UPCASE"))							!DM
$	    VALID_RECORD = TRUE												!DM
$	ENDIF														!DM
$															!DM
$	IF .NOT. VALID_RECORD
$	THEN
$	    WRITE SYS$OUTPUT "%%Warning - invalid configuration file record \", RECORD, "\"
$	    VALID_CONFIGURATION = FALSE
$	ENDIF
$
$	GOTO _CONFIG_LOOP
$  
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$ _EXIT_CONFIG_LOOP: 
$	CLOSE FILE
$
$	IF .NOT. VALID_CONFIGURATION
$	THEN
$	    WRITE SYS$OUTPUT "Error in configuration file."
$	    GOTO _EXIT
$	ENDIF
$
$	FTP_CLIENT_TYPE = TYPE_OTHER
$	IF CONFIG_FTP_CLIENT .EQS. "MultiNet" THEN -
	   FTP_CLIENT_TYPE = TYPE_MULTINET
$	IF CONFIG_FTP_CLIENT .EQS. "MadGoat FTP" THEN -
	   FTP_CLIENT_TYPE = TYPE_MGFTP
$	IF CONFIG_FTP_CLIENT .EQS. "TCPware" THEN -
	   FTP_CLIENT_TYPE = TYPE_TCPWARE
$
$	FTP_SERVER_TYPE = TYPE_OTHER
$	IF CONFIG_FTP_SERVER .EQS. "MultiNet" THEN -
	   FTP_SERVER_TYPE = TYPE_MULTINET
$	IF CONFIG_FTP_SERVER .EQS. "MadGoat FTP" THEN -
	   FTP_SERVER_TYPE = TYPE_MGFTP
$	IF CONFIG_FTP_SERVER .EQS. "TCPware" THEN -
	   FTP_SERVER_TYPE = TYPE_TCPWARE
$	IF CONFIG_FTP_SERVER .EQS. "Unix" THEN -
	   FTP_SERVER_TYPE = TYPE_UNIX
$
$	WRITE SYS$OUTPUT ""
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Remote site:",CONFIG_SITE)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Remote username:",CONFIG_USERNAME)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Remote password:",CONFIG_PASSWORD)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","FTP server:",CONFIG_FTP_SERVER)
$	WRITE SYS$OUTPUT ""
$	WRITE SYS$OUTPUT "  Directories:  (remote)                (local)"
$
$	COUNT = 0
$ _DISPLAY_LOOP_1: 
$	IF COUNT .GE. CONFIG_DIR_TOTAL THEN GOTO _EXIT_DISPLAY_LOOP_1
$	WRITE SYS$OUTPUT F$FAO("    !33AS !35AS", -
			       F$ELEMENT(0,",",CONFIG_DIRECTORIES_'COUNT'), -
			       F$ELEMENT(1,",",CONFIG_DIRECTORIES_'COUNT'))
$	IF F$PARSE(F$ELEMENT(1,",",CONFIG_DIRECTORIES_'COUNT'),,,,"SYNTAX_ONLY") .EQS. ""
$	THEN
$	    WRITE SYS$ERROR F$FAO("!5** Local directory specification (above) is invalid VMS syntax.")
$	    VALID_CONFIGURATION = FALSE
$	ENDIF
$	COUNT = COUNT + 1
$	GOTO _DISPLAY_LOOP_1
$ _EXIT_DISPLAY_LOOP_1: 
$
$	WRITE SYS$OUTPUT ""
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","FTP client:",CONFIG_FTP_CLIENT)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","DCL command:",CONFIG_COMMAND)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","File transfer mode:",CONFIG_FILE_TRANSFER)
$	IF CONFIG_PASSIVE
$	THEN
$	    CONFIG_PASSIVE = TRUE
$	    WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Passive mode:","Yes")
$	ELSE
$	    CONFIG_PASSIVE = FALSE
$	    WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Passive mode:","No")
$	ENDIF
$	IF CONFIG_LAST_TIME .NES. "" THEN -
	   WRITE SYS$OUTPUT F$FAO("  !40AS !AS",-
				  "Only get files created after:",-
				  CONFIG_LAST_TIME)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Resubmit after:",-
			       CONFIG_SUBMIT_AFTER)
$	IF CONFIG_SUBMIT_AFTER .NES. "NONE" THEN -
	   WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Batch queue:",CONFIG_QUEUE)
$	IF CONFIG_MAILTO .NES. "" THEN -
	   WRITE SYS$OUTPUT F$FAO("  !40AS !AS",-
				  "Mail reports to:",-
				  CONFIG_MAILTO)
$	IF CONFIG_MAXIMUM_FILES .NE. %X7FFFFFFF THEN -									!DM
	   WRITE SYS$OUTPUT F$FAO("  !40AS !UL",-									!DM
				  "Maximum number of files to transfer:",-						!DM
				  CONFIG_MAXIMUM_FILES)									!DM
$	WRITE SYS$OUTPUT ""
$
$	IF CONFIG_SITE .EQS. "" .OR. CONFIG_USERNAME .EQS. "" .OR. -
	   CONFIG_PASSWORD .EQS. "" .OR. CONFIG_DIRECTORIES_0 .EQS. "" .OR. -
	   CONFIG_SUBMIT_AFTER .EQS. ""
$	THEN
$	    WRITE SYS$ERROR "Missing required configuration setting; exiting."
$	    WRITE SYS$ERROR "Check for missing username, directory, password, or submit-after."
$	    GOTO _EXIT
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .NE. TYPE_MULTINET -
	   .AND. FTP_CLIENT_TYPE .NE. TYPE_MGFTP -
	   .AND. FTP_CLIENT_TYPE .NE. TYPE_TCPWARE
$	THEN
$	    WRITE SYS$ERROR "Invalid FTP Client -- only \MULTINET\, \TCPWARE\, or \MADGOAT FTP\ are allowed."
$	    GOTO _EXIT
$	ENDIF
$
$!$	IF CONFIG_PASSIVE .AND. (FTP_CLIENT_TYPE .EQ. TYPE_MGFTP .OR. -
$!				 FTP_SERVER_TYPE .EQ. TYPE_MGFTP)
$!$	THEN
$!$	    WRITE SYS$ERROR "PASSIVE isn't supported by MadGoat FTP client or server."
$!$	    GOTO _EXIT
$!$	ENDIF
$
$	IF FTP_SERVER_TYPE .NE. TYPE_MULTINET -
	   .AND. FTP_SERVER_TYPE .NE. TYPE_MGFTP -
	   .AND. FTP_SERVER_TYPE .NE. TYPE_TCPWARE -
	   .AND. FTP_SERVER_TYPE .NE. TYPE_UNIX
$	THEN
$	    WRITE SYS$ERROR "Invalid FTP Server.  Only MultiNet, MadGoat FTP, TCPware, and UNIX are supported."
$	    GOTO _EXIT
$	ENDIF
$
$	IF .NOT. VALID_CONFIGURATION
$	THEN
$	    WRITE SYS$ERROR "Invalid configuration -- see above reason"
$	    GOTO _EXIT
$	ENDIF
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$	IF F$MODE() .EQS. "INTERACTIVE"
$	THEN
$	    READ SYS$COMMAND CHECK/PROMPT="Ready [Y]? "/END_OF_FILE=_ABORT
$	ELSE
$	    CHECK := Y
$	ENDIF
$
$	IF .NOT. CHECK .AND. CHECK .NES. "" THEN GOTO _ABORT
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$	IF CONFIG_SUBMIT_AFTER .NES. "NONE" .AND. F$MODE() .NES. "BATCH"
$	THEN
$	    GOTO _SUBMIT
$	ENDIF
$          
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!  Obtain the list of files on the remote system
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$	OPEN/WRITE FILE 'TEMPFILE_1'
$	COUNT = 0
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MULTINET
$	THEN
$	    IF CONFIG_PASSIVE
$	    THEN WRITE FILE "PASSIVE ON"
$	    ELSE WRITE FILE "PASSIVE OFF"
$	    ENDIF
$	    WRITE FILE "EXIT-ON-ERROR ON"
$	    WRITE FILE "PROMPT-FOR-MISSING-ARGUMENTS OFF"
$	    WRITE FILE "VERBOSE"											!DM
$	    IF DEBUG THEN WRITE FILE "STATISTICS"
$	    WRITE FILE "CONNECT ", CONFIG_SITE
$	    WRITE FILE "USER ", CONFIG_USERNAME
$	    WRITE FILE "PASS ", CONFIG_PASSWORD
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE FILE "STRUCTURE VMS"
$	    ELSE
$		WRITE FILE "TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE FILE "PWD"
$	ENDIF  ! multinet
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MGFTP
$	THEN
$	    WRITE FILE "SET BATCH"
$	    IF CONFIG_PASSIVE
$	    THEN WRITE FILE "SET PASSIVE"
$	    ELSE WRITE FILE "SET NOPASSIVE"
$	    ENDIF
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE FILE "SET STRUCTURE VMS"
$	    ELSE
$		WRITE FILE "SET TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE FILE "PWD"
$	ENDIF  ! madgoat
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_TCPWARE
$	THEN
$	    IF CONFIG_PASSIVE
$	    THEN WRITE FILE "SET PASSIVE"
$	    ELSE WRITE FILE "SET NOPASSIVE"
$	    ENDIF
$	    IF DEBUG THEN WRITE FILE "SET DEBUG/CLASS=REPLIES"
$	    WRITE FILE "CONNECT ", CONFIG_SITE, " ", -
		  CONFIG_USERNAME, " ", CONFIG_PASSWORD
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE FILE "STRUCTURE VMS"
$	    ELSE
$		WRITE FILE "TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE FILE "PWD"
$	ENDIF  ! tcpware
$
$	COUNT = 0
$ _GEN_FILE_LOOP: 
$	IF COUNT .GE. CONFIG_DIR_TOTAL THEN GOTO _EXIT_GEN_FILE_LOOP
$	DIRECTORY_NAME = F$ELEMENT(0,",",CONFIG_DIRECTORIES_'COUNT')
$	DIRECTORY_NAME2 = DIRECTORY_NAME - "/..." - "..."
$	WRITE FILE "SPAWN WRITE SYS$OUTPUT ""<<<REMOTE_DIRECTORY ''DIRECTORY_NAME2'>>>"""
$	IF FTP_SERVER_TYPE .EQ. TYPE_UNIX .AND. -
	   F$EXTRACT(F$LENGTH(DIRECTORY_NAME)-4, 4, DIRECTORY_NAME) .EQS. "/..." -
	   THEN DIRECTORY_NAME = "-RlL " + F$EXTRACT(0, F$LENGTH(DIRECTORY_NAME)-4, DIRECTORY_NAME)
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MULTINET THEN -
	   WRITE FILE "DIR """, DIRECTORY_NAME, """"
$!RL	   WRITE FILE "DIR """, DIRECTORY_NAME, """ FTP_DIR:"
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MGFTP -
	   .OR. FTP_CLIENT_TYPE .EQ. TYPE_TCPWARE THEN -
	   WRITE FILE "DIR """, DIRECTORY_NAME, """"
$!RL	   WRITE FILE "DIR """, DIRECTORY_NAME, """/OUTPUT=FTP_DIR:"
$	COUNT = COUNT + 1
$	GOTO _GEN_FILE_LOOP
$
$ _EXIT_GEN_FILE_LOOP: 
$	WRITE FILE "EXIT"
$	CLOSE FILE
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Contents of input file:"
$	IF DEBUG THEN TYPE/OUTPUT=SYS$ERROR 'TEMPFILE_1'
$
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Connecting to remote system..."
$!RL$	IF F$SEARCH(TEMPFILE_2) .NES. "" THEN DELETE 'TEMPFILE_2';*
$!RL$	TYPE NLA0: /OUTPUT='TEMPFILE_2'
$!RL$	SET FILE/VERSION_LIMIT=0 'TEMPFILE_2'
$!RL$	IF F$SEARCH(TEMPFILE_4) .NES. "" THEN DELETE 'TEMPFILE_4';*
$!RL$	TYPE NLA0: /OUTPUT='TEMPFILE_4'
$!RL$	SET FILE/VERSION_LIMIT=0 'TEMPFILE_4'
$	IF F$SEARCH(TEMPFILE_3) .NES. "" THEN DELETE 'TEMPFILE_3';*
$
$	OLD_SYMBOL_SCOPE = F$ENVIRONMENT("SYMBOL_SCOPE")
$	SET SYMBOL/SCOPE=(GLOBAL,LOCAL)
$
$!RL$	IF DEBUG THEN SHOW LOG SYS$OUTPUT/FULL
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MULTINET
$	THEN
$	    SET noON
$!RL$	    OPEN/WRITE FTP_DIR 'TEMPFILE_2'
$!RL$	    DEFINE SYS$OUTPUT 'TEMPFILE_4'
$	    DEFINE SYS$OUTPUT 'TEMPFILE_3'
$	    'CONFIG_COMMAND' -
		  /NOINITIALIZATION -
		  /TAKE_FILE='TEMPFILE_1'
$	    STATUS = $STATUS
$	    DEASSIGN SYS$OUTPUT
$!RL$	    CLOSE FTP_DIR
$	    SET ON
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MGFTP
$	THEN
$	    SET noON
$!RL$	    OPEN/WRITE FTP_DIR 'TEMPFILE_2'
$!RL$	    DEFINE SYS$OUTPUT 'TEMPFILE_4'
$	    DEFINE SYS$OUTPUT 'TEMPFILE_3'
$	    'CONFIG_COMMAND' -
		  'CONFIG_SITE' -
		  /USERNAME="''CONFIG_USERNAME'" -
		  /PASSWORD="''CONFIG_PASSWORD'" -
		  /INITIALIZATION='TEMPFILE_1'
$	    STATUS = $STATUS
$	    DEASSIGN SYS$OUTPUT
$!RL$	    CLOSE FTP_DIR
$	    SET noON
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_TCPWARE
$	THEN
$	    SET noON
$!RL$	    OPEN/WRITE FTP_DIR 'TEMPFILE_2'
$!RL$	    DEFINE SYS$OUTPUT 'TEMPFILE_4'
$	    DEFINE SYS$OUTPUT 'TEMPFILE_3'
$	    DEFINE/USER FTP_STARTUP 'tempfile_1'
$	    'CONFIG_COMMAND'
$	    STATUS = $STATUS
$	    DEASSIGN SYS$OUTPUT
$!RL$	    CLOSE FTP_DIR
$	    SET noON
$	ENDIF
$
$	SET SYMBOL/SCOPE=('OLD_SYMBOL_SCOPE')
$
$!RL$	IF F$SEARCH(TEMPFILE_3) .NES. "" THEN DELETE 'TEMPFILE_3';*
$!RL$	COPY/CONCATENATE 'TEMPFILE_4','TEMPFILE_2' 'TEMPFILE_3'
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Output from FTP session:"
$	IF DEBUG THEN TYPE/OUTPUT=SYS$ERROR 'TEMPFILE_3'
$
$	IF .NOT. STATUS THEN GOTO _ERROR
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$! Determine which files we will need to get from the remote system
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$	OPEN/READ FILE 'TEMPFILE_3'
$	IF F$SEARCH(TEMPFILE_1) .NES. "" THEN DELETE 'TEMPFILE_1';
$	OPEN/WRITE OUTFILE 'TEMPFILE_1'
$	TYPE NLA0: /OUTPUT='TEMPFILE_4'
$	OPEN/APPEND REPORT_FILE 'TEMPFILE_4'
$	WRITE REPORT_FILE "(This message generated by FTP_MIRROR.COM)"
$	WRITE REPORT_FILE ""
$	WRITE REPORT_FILE "New files at site: ", CONFIG_SITE
$	WRITE REPORT_FILE ""
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MULTINET
$	THEN
$	    IF CONFIG_PASSIVE THEN WRITE OUTFILE "PASSIVE ON"
$	    WRITE OUTFILE "EXIT-ON-ERROR ON"
$	    WRITE OUTFILE "PROMPT-FOR-MISSING-ARGUMENTS OFF"
$	    WRITE OUTFILE "VERBOSE"											!DM
$	    IF DEBUG THEN WRITE OUTFILE "STATISTICS"
$	    WRITE OUTFILE "CONNECT ", CONFIG_SITE
$	    WRITE OUTFILE "USER ", CONFIG_USERNAME
$	    WRITE OUTFILE "PASS ", CONFIG_PASSWORD
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE OUTFILE "STRUCTURE VMS"
$	    ELSE
$		WRITE OUTFILE "TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE OUTFILE "PWD"
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MGFTP
$	THEN
$	    WRITE OUTFILE "SET BATCH"
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE OUTFILE "SET STRUCTURE VMS"
$	    ELSE
$		WRITE OUTFILE "SET TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE OUTFILE "PWD"
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_TCPWARE
$	THEN
$	    IF CONFIG_PASSIVE THEN WRITE OUTFILE "SET PASSIVE"
$	    IF DEBUG THEN WRITE OUTFILE "SET DEBUG/CLASS=REPLIES"
$	    WRITE OUTFILE "CONNECT ", CONFIG_SITE, " ", -
		  CONFIG_USERNAME, " ", CONFIG_PASSWORD
$	    IF CONFIG_FILE_TRANSFER .EQS. "VMS"
$	    THEN
$		WRITE OUTFILE "STRUCTURE VMS"
$	    ELSE
$		WRITE OUTFILE "TYPE ", CONFIG_FILE_TRANSFER
$	    ENDIF
$	    WRITE OUTFILE "PWD"
$	ENDIF  ! tcpware
$
$	GET_FILE_COUNT = 0
$
$	LOCAL_DIRECTORY = ""
$	LOCAL_FILENAME = ""
$	NOT_LOGGED_IN = 0
$ _READ_FILE_LOOP:
$	READ/END_OF_FILE=_EXIT_READ_FILE_LOOP FILE RECORD
$	IF F$EDIT(RECORD,"COLLAPSE") .EQS. "" THEN GOTO _READ_FILE_LOOP
$	IF DEBUG THEN WRITE SYS$ERROR F$FAO("-Debug- Record is: \!AS\", RECORD)
$	RECORD = F$EDIT(RECORD,"COMPRESS")
$	XXX = F$EDIT(F$ELEMENT(0," ",RECORD),"UPCASE")									!DM
$	IF XXX .EQS. "LIST" THEN GOTO _READ_FILE_LOOP									!DM
$	IF XXX .EQS. "PORT" THEN GOTO _READ_FILE_LOOP									!DM
$	IF XXX .EQS. "QUIT" THEN GOTO _READ_FILE_LOOP									!DM
$	IF XXX .EQS. "RUN" THEN GOTO _READ_FILE_LOOP									!DM
$	IF XXX .EQS. "TYPE:" THEN GOTO _READ_FILE_LOOP									!DM
$	IF XXX .EQS. "TYPE" THEN GOTO _READ_FILE_LOOP									!DM
$	IF F$EXTRACT(0,5,RECORD) .EQS. "<257 " -
	   .OR. F$EXTRACT(0,4,RECORD) .EQS. "257 "
$	THEN
$	    REMOTE_ROOT = F$ELEMENT(1," ",RECORD)
$	    IF F$EXTRACT(0,1,REMOTE_ROOT) .EQS. """" THEN REMOTE_ROOT = F$ELEMENT(1,"""",REMOTE_ROOT)
$	    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Remote root now: ", REMOTE_ROOT
$	    GOTO _READ_FILE_LOOP
$	ENDIF
$
$	IF F$EXTRACT(0,5,RECORD) .EQS. "<530 " -									!DM
	   .OR. F$EXTRACT(0,4,RECORD) .EQS. "530 "									!DM
$	THEN														!DM
$	    NOT_LOGGED_IN = 1												!DM
$	    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Login at remote failed."						!DM
$	    GOTO _EXIT_READ_FILE_LOOP											!DM
$	ENDIF														!DM
$															!DM
$	IF F$EXTRACT(0,10,RECORD) .EQS. "Directory "
$	THEN 
$	    RECORD = F$EXTRACT(10,F$LENGTH(RECORD)-10,RECORD)
$	    IF DEBUG THEN WRITE SYS$ERROR F$FAO("-Debug- Record changed: \!AS\", RECORD)
$	ENDIF
$	IF F$EDIT(F$ELEMENT(0," ",RECORD),"UPCASE") .EQS. "<<<REMOTE_DIRECTORY"
$!RL	   .AND. LOCAL_DIRECTORY .EQS. ""
$	THEN
$	    LOCAL_DIRECTORY = ""
$	    RECORD = F$ELEMENT(0,">",F$ELEMENT(1," ",RECORD))
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$	    THEN
$		RECORD = RECORD + ":"
$	    ELSE
$!RL$		IF RECORD - ":" .EQS. RECORD THEN -
$!RL		   RECORD = REMOTE_ROOT - "]" + (RECORD - "[")
$		GOTO _READ_FILE_LOOP
$	    ENDIF
$	    IF DEBUG THEN WRITE SYS$ERROR F$FAO("-Debug- Record changed: \!AS\", RECORD)
$	ENDIF
$
$	IF RECORD .EQS. "" .OR. -
	   (FTP_SERVER_TYPE .NE. TYPE_UNIX .AND. -
	    RECORD .NES. F$EDIT(RECORD,"UPCASE")) THEN -
	   GOTO _READ_FILE_LOOP      ! no lowercase in files/directories
$	C = F$EXTRACT(0,1,RECORD)
$	IF C .EQS. "<" .OR. C .EQS. "%" .OR. C .EQS. "[" THEN GOTO _READ_FILE_LOOP					!DM
$	IF FTP_SERVER_TYPE .EQ. TYPE_UNIX .AND. -
	   F$TYPE(C) .EQS. "INTEGER" THEN GOTO _READ_FILE_LOOP
$	IF FTP_SERVER_TYPE .EQ. TYPE_UNIX .AND. -
	   F$ELEMENT(0," ",RECORD) .EQS. "total"
$	THEN
$	    TMP3 = F$EDIT(RECORD - F$ELEMENT(0," ",RECORD),"TRIM")
$	    IF F$TYPE(TMP3) .EQS. "INTEGER" THEN GOTO _READ_FILE_LOOP
$	ENDIF
$
$	IF F$LOCATE(":",F$ELEMENT(0," ",RECORD)) .NE. F$LENGTH(F$ELEMENT(0," ",RECORD))
$	THEN
$	    ! we have a directory
$	    LOCAL_DIRECTORY = ""
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$	    THEN
$		REMOTE_DIRECTORY = F$ELEMENT(0,":",RECORD)
$		IF F$EXTRACT(0,1,REMOTE_DIRECTORY) .NES. "/"
$		THEN
$		    IF F$EXTRACT(F$LENGTH(REMOTE_ROOT)-1,1,REMOTE_ROOT) .NES. "/" THEN -
		       REMOTE_DIRECTORY = "/" + REMOTE_DIRECTORY
$		    REMOTE_DIRECTORY = REMOTE_ROOT + REMOTE_DIRECTORY
$		ENDIF
$		IF F$EXTRACT(F$LENGTH(REMOTE_DIRECTORY)-1,1,REMOTE_DIRECTORY) -
		   .NES. "/" THEN -
		   REMOTE_DIRECTORY = REMOTE_DIRECTORY + "/"
$	    ELSE
$		REMOTE_DIRECTORY = F$ELEMENT(0," ",RECORD)
$	    ENDIF
$	    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Remote directory now: ", REMOTE_DIRECTORY
$	    ! now we have to find it in our mappings
$	    COUNT = 0
$ _FIND_LOOP: 
$	    IF COUNT .GE. CONFIG_DIR_TOTAL THEN GOTO _EXIT_FIND_LOOP
$	    TMP = F$ELEMENT(0,",",CONFIG_DIRECTORIES_'COUNT')
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$	    THEN
$		IF F$EXTRACT(0,1,TMP) .NES. "/"
$		THEN
$		    IF F$EXTRACT(F$LENGTH(REMOTE_ROOT)-1,1,REMOTE_ROOT) .NES. "/" THEN -
		       TMP = "/" + TMP
$		    TMP = REMOTE_ROOT + TMP
$		ENDIF
$	    ELSE
$		IF F$EXTRACT(0,2,TMP) .EQS. "[." THEN -
		   TMP = F$EXTRACT(0,F$LENGTH(REMOTE_ROOT)-1,REMOTE_ROOT) + -
		   F$EXTRACT(1,999,TMP)
$		IF F$EXTRACT(0,1,TMP) .EQS. "[" THEN -
		   TMP = F$ELEMENT(0,"[",REMOTE_ROOT) + TMP
$	    ENDIF
$	    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Remote directory to check for: ", TMP
$	    ENDING = "...]"
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX THEN ENDING = "..."
$	    LE = F$LENGTH(ENDING)
$	    IF F$EXTRACT(F$LENGTH(TMP)-LE,LE,TMP) -
	       .EQS. ENDING
$	    THEN
$		TMP = F$EXTRACT(0,F$LENGTH(TMP)-F$LENGTH(ENDING),TMP)
$		IF TMP .EQS. F$EXTRACT(0,F$LENGTH(TMP),REMOTE_DIRECTORY)
$		THEN
$		    ! we have a mapping
$		    LOCAL_DIRECTORY = F$ELEMENT(1,",",CONFIG_DIRECTORIES_'COUNT')
$		    IF F$EXTRACT(F$LENGTH(LOCAL_DIRECTORY)-4,4,LOCAL_DIRECTORY) .EQS. "...]"
$		    THEN
$			TMP2 = REMOTE_DIRECTORY
$			IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$			THEN
$			    ALLOWED_CHARACTERS = "ABCDEFGHIKJLMNOPQRSTUVWXYZabcdefghikjlmnopqrstuvwxyz0123456789-_$/."
$			    I = 0
$ LOOP_CHARACTERS1:	    
$			    C = F$EXTRACT(I,1,TMP2)
$			    IF C .EQS. "." THEN -
			       TMP2 = F$EXTRACT(0,I,TMP2) + "_" + F$EXTRACT(I+1,F$LENGTH(TMP2)-I-1,TMP2)
$			    IF C .EQS. "/"
$			    THEN
$				IF I .LT. F$LENGTH(TMP2)-1
$				THEN
$				    TMP2 = F$EXTRACT(0,I,TMP2) + "." + F$EXTRACT(I+1,F$LENGTH(TMP2)-I-1,TMP2)
$				ELSE
$				    TMP2 = F$EXTRACT(0,I,TMP2) + "]"
$				ENDIF
$			    ENDIF
$			    IF ALLOWED_CHARACTERS - C .EQS. ALLOWED_CHARACTERS THEN -
			       TMP2 = F$EXTRACT(0,I,TMP2) + "$" + F$EXTRACT(I+1,F$LENGTH(TMP2)-I-1,TMP2)
$			    I = I + 1
$			    IF I .LT. F$LENGTH(TMP2) THEN GOTO LOOP_CHARACTERS1
$			    TMP2 = TMP2
$			ENDIF
$			IF DEBUG THEN -
			   WRITE SYS$ERROR "-Debug- TMP = """,TMP,""""
$			IF DEBUG THEN -
			   WRITE SYS$ERROR "-Debug- TMP2 = """,TMP2,""""
$			IF DEBUG THEN -
			   WRITE SYS$ERROR "-Debug- LOCAL_DIRECTORY = """,-
			   LOCAL_DIRECTORY,""""
$			LOCAL_DIRECTORY = F$EXTRACT(0,F$LENGTH(LOCAL_DIRECTORY)-4,LOCAL_DIRECTORY) + F$EXTRACT(F$LENGTH(TMP)-(FTP_SERVER_TYPE .EQ. TYPE_UNIX),999,TMP2)
$
$		    ENDIF
$		    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Local directory now: ", LOCAL_DIRECTORY
$		ENDIF
$	    ELSE
$		IF FTP_SERVER_TYPE .EQ. TYPE_UNIX -
		   .AND. F$EXTRACT(F$LENGTH(TMP)-1,1,TMP) .NES. "/" THEN -
		   TMP = TMP + "/"
$		IF TMP .EQS. REMOTE_DIRECTORY
$		THEN
$		    ! we have a mapping
$		    LOCAL_DIRECTORY = F$ELEMENT(1,",",CONFIG_DIRECTORIES_'COUNT') - "..."
$		    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Local directory now: ", LOCAL_DIRECTORY
$		ENDIF
$	    ENDIF
$	    COUNT = COUNT + 1
$	    GOTO _FIND_LOOP
$ _EXIT_FIND_LOOP: 
$	    IF LOCAL_DIRECTORY .EQS. "" 
$	    THEN 
$		WRITE SYS$ERROR "Error - no mapping for remote directory ", REMOTE_DIRECTORY
$		WRITE SYS$ERROR "Error - skipping directory ", REMOTE_DIRECTORY
$	    ELSE
$		IF F$PARSE(LOCAL_DIRECTORY) .EQS. "" THEN CREATE/DIRECTORY/LOG 'LOCAL_DIRECTORY'
$	    ENDIF
$	    GOTO _READ_FILE_LOOP
$	ENDIF ! f$locate
$
$	IF LOCAL_DIRECTORY .EQS. "" THEN GOTO _READ_FILE_LOOP
$
$!
$!!!  Determine if we need to get a file
$!
$
$	IF F$EDIT(F$ELEMENT(0," ",RECORD),"COLLAPSE") .NES. ""
$	THEN
$	    GET_FILE = FALSE
$	    ! assume we have a remote filename
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$	    THEN
$		RECORD_C = F$EDIT(RECORD,"COMPRESS,TRIM")
$		REMOTE_PROTECTION = F$ELEMENT(0," ",RECORD_C)
$		REMOTE_LINKS = F$ELEMENT(1," ",RECORD_C)
$		REMOTE_USER = F$ELEMENT(2," ",RECORD_C)
$		REMOTE_GROUP = F$ELEMENT(3," ",RECORD_C)
$		REMOTE_SIZE = F$ELEMENT(4," ",RECORD_C)
$		REMOTE_MONTH = F$ELEMENT(5," ",RECORD_C)
$		REMOTE_DAY = F$ELEMENT(6," ",RECORD_C)
$		REMOTE_YEARORTIME = F$ELEMENT(7," ",RECORD_C)
$		IF REMOTE_YEARORTIME - ":" .EQS. REMOTE_YEARORTIME
$		THEN ! Mon day year
$		    REMOTE_TIMESTAMP = F$CVTIME(REMOTE_DAY+"-"+REMOTE_MONTH+"-"+REMOTE_YEARORTIME+":0:0:0","COMPARISON")
$		ELSE
$		    REMOTE_TIMESTAMP = F$CVTIME(REMOTE_DAY+"-"+REMOTE_MONTH+"-"+F$CVTIME("",,"YEAR")+":"+REMOTE_YEARORTIME,"COMPARISON")
$		    IF REMOTE_TIMESTAMP .GTS. F$CVTIME("+1-","COMPARISON") THEN -
		       REMOTE_TIMESTAMP = F$CVTIME(REMOTE_DAY+"-"+REMOTE_MONTH+"-"+F$CVTIME("-365-",,"YEAR")+":"+REMOTE_YEARORTIME,"COMPARISON")
$		ENDIF
$		FILENAME = RECORD_C - REMOTE_PROTECTION - REMOTE_LINKS -
			   - REMOTE_USER - REMOTE_GROUP - REMOTE_SIZE -
			   - REMOTE_MONTH - REMOTE_DAY - REMOTE_YEARORTIME
$		FILENAME = F$EDIT(FILENAME,"TRIM")
$	    ELSE
$		FILENAME = F$ELEMENT(0," ",RECORD)
$		REMOTE_TIMESTAMP = F$ELEMENT(2," ",RECORD) + " " + F$ELEMENT(3," ",RECORD)
$		IF F$EDIT(REMOTE_TIMESTAMP,"COLLAPSE") .EQS. "" 
$		THEN
$		    ! date is on the next line...
$ _READ_DATE_LINE:  
$		    READ/END_OF_FILE=_EXIT_READ_FILE_LOOP FILE RECORD
$! Watch out.  Some client, like the MadGoat FTP client, will sputter lines
$! like this right in the middle of the directory output:
$!	<226 File transfer Okay; Closing data connection.
$! Fortunately, it is very easy to check, since we expect this line to start
$! with a space
$		    IF F$EXTRACT(0,1,RECORD) .NES. " " THEN -
		       GOTO _READ_DATE_LINE
$		    RECORD = F$EDIT(RECORD,"COMPRESS")
$		    REMOTE_TIMESTAMP = F$ELEMENT(2," ",RECORD) + " " + F$ELEMENT(3," ",RECORD)
$		ENDIF
$		REMOTE_TIMESTAMP = F$CVTIME(REMOTE_TIMESTAMP,"COMPARISON")
$	    ENDIF
$	    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Remote file is: ", FILENAME
$	    IF FTP_SERVER_TYPE .EQ. TYPE_UNIX
$	    THEN
$		IF F$EXTRACT(0,1,REMOTE_PROTECTION) .NES. "-" THEN -
		   GOTO _READ_FILE_LOOP
$	    ELSE
$		IF F$PARSE(FILENAME,,,"TYPE") .EQS. ".DIR" THEN -
		   GOTO _READ_FILE_LOOP
$	    ENDIF
$
$	    OLD_LOCAL_FILENAME = LOCAL_FILENAME
$	    IF FTP_SERVER_TYPE .EQS. TYPE_UNIX
$	    THEN
$		LOCAL_FILENAME = FILENAME
$		IF F$EXTRACT(F$LENGTH(LOCAL_FILENAME)-3,3,LOCAL_FILENAME) .EQS. ".gz"
$		THEN
$		    LOCAL_FILENAME = F$EXTRACT(0,F$LENGTH(LOCAL_FILENAME)-3,LOCAL_FILENAME)
$		    IF LOCAL_FILENAME - "." .EQS. LOCAL_FILENAME
$		    THEN
$			LOCAL_FILENAME = LOCAL_FILENAME + ".gz"
$		    ELSE
$			LOCAL_FILENAME = LOCAL_FILENAME + "-gz"
$		    ENDIF
$		ENDIF
$		IF F$EXTRACT(F$LENGTH(LOCAL_FILENAME)-2,2,LOCAL_FILENAME) .EQS. ".Z"
$		THEN
$		    LOCAL_FILENAME = F$EXTRACT(0,F$LENGTH(LOCAL_FILENAME)-2,LOCAL_FILENAME)
$		    IF LOCAL_FILENAME - "." .EQS. LOCAL_FILENAME
$		    THEN
$			LOCAL_FILENAME = LOCAL_FILENAME + ".Z"
$		    ELSE
$			LOCAL_FILENAME = LOCAL_FILENAME + "_Z"
$		    ENDIF
$		ENDIF
$		ALLOWED_CHARACTERS = "ABCDEFGHIKJLMNOPQRSTUVWXYZabcdefghikjlmnopqrstuvwxyz0123456789-_$."
$		IF DEBUG THEN WRITE SYS$ERROR "-Debug- (1) LOCAL_FILENAME=""",-
		   LOCAL_FILENAME,""""
$		I = 0
$ LOOP_CHARACTERS2: 
$		C = F$EXTRACT(I,1,LOCAL_FILENAME)
$		IF C .EQS. "." -
		   .AND. LOCAL_FILENAME - "." - "." .NES. LOCAL_FILENAME - "." THEN -
		   LOCAL_FILENAME = F$EXTRACT(0,I,LOCAL_FILENAME) + "_" + F$EXTRACT(I+1,F$LENGTH(LOCAL_FILENAME)-I-1,LOCAL_FILENAME)
$		IF ALLOWED_CHARACTERS - C .EQS. ALLOWED_CHARACTERS THEN -
		   LOCAL_FILENAME = F$EXTRACT(0,I,LOCAL_FILENAME) + "$" + F$EXTRACT(I+1,F$LENGTH(LOCAL_FILENAME)-I-1,LOCAL_FILENAME)
$		I = I + 1
$		IF I .LT. F$LENGTH(LOCAL_FILENAME) THEN GOTO LOOP_CHARACTERS2
$		IF DEBUG THEN WRITE SYS$ERROR "-Debug- (2) LOCAL_FILENAME=""",-
		   LOCAL_FILENAME,""""
$		LOCAL_FILENAME = F$PARSE(";",LOCAL_FILENAME,LOCAL_DIRECTORY)
$		IF DEBUG THEN WRITE SYS$ERROR "-Debug- (3) LOCAL_FILENAME=""",-
		   LOCAL_FILENAME,""""
$	    ELSE
$		LOCAL_FILENAME = F$PARSE(";",FILENAME,LOCAL_DIRECTORY)
$	    ENDIF
$	    IF DEBUG THEN WRITE SYS$ERROR "-Debug- Local file is: ", LOCAL_FILENAME
$	    IF OLD_LOCAL_FILENAME .EQS. LOCAL_FILENAME
$	    THEN
$		IF DEBUG THEN WRITE SYS$ERROR "-Debug- Skipping file ", FILENAME, " (it's an older version)"
$		GOTO _READ_FILE_LOOP
$	    ENDIF
$	    IF F$SEARCH(LOCAL_FILENAME) .EQS. ""
$	    THEN
$		! no such file exists, so we need to create directory (if
$		! necessary) and pull the file over
$		IF CONFIG_LAST_TIME_FILE .EQS. "" -
		   .OR. CONFIG_LAST_TIME .LTS. REMOTE_TIMESTAMP THEN GET_FILE = TRUE
$		IF GET_FILE .AND. DEBUG THEN -
		   WRITE SYS$ERROR "-Debug- Copying file ", REMOTE_DIRECTORY, FILENAME, " to ", LOCAL_FILENAME, " (we don't have a copy)."
$	    ELSE
$		! check dates to see if we should get a new copy
$		LOCAL_TIMESTAMP = F$CVTIME(F$FILE(LOCAL_FILENAME,"RDT"),"COMPARISON")
$		IF DEBUG THEN WRITE SYS$ERROR "-Debug- Local file date: ", LOCAL_TIMESTAMP, ", remote file date: ", REMOTE_TIMESTAMP
$		IF LOCAL_TIMESTAMP .LES. REMOTE_TIMESTAMP
$		THEN 
$		    IF CONFIG_LAST_TIME_FILE .EQS. "" -
		       .OR. CONFIG_LAST_TIME .LTS. REMOTE_TIMESTAMP THEN GET_FILE = TRUE
$		    IF GET_FILE .AND. DEBUG THEN -
		       WRITE SYS$ERROR "-Debug- Getting file ", REMOTE_DIRECTORY, FILENAME, " to ", LOCAL_FILENAME," (we have an old copy)."
$		ENDIF
$	    ENDIF
$	    IF GET_FILE 
$	    THEN 
$		GET_FILE_COUNT = GET_FILE_COUNT + 1
$		WRITE OUTFILE "GET """, REMOTE_DIRECTORY, FILENAME, """ ", -
		      LOCAL_FILENAME
$		WRITE REPORT_FILE F$FAO("  !3UL.  !AS!AS -> !AS", -
					GET_FILE_COUNT, -
					REMOTE_DIRECTORY, FILENAME, -
					LOCAL_FILENAME)
$		IF GET_FILE_COUNT .GE. CONFIG_MAXIMUM_FILES THEN GOTO _EXIT_READ_FILE_LOOP				!DM
$	    ENDIF
$	ENDIF
$
$	GOTO _READ_FILE_LOOP
$ _EXIT_READ_FILE_LOOP:	
$	CLOSE FILE
$	WRITE OUTFILE "EXIT"
$	CLOSE OUTFILE
$	CLOSE REPORT_FILE
$
$	IF F$SEARCH(TEMPFILE_2) .NES. "" THEN DELETE 'TEMPFILE_2';
$
$	IF GET_FILE_COUNT .EQ. 0 .OR. NOT_LOGGED_IN
$	THEN
$	    WRITE SYS$OUTPUT "No files to get.  Exiting."
$	    GOTO _SUBMIT
$	ENDIF
$	WRITE SYS$OUTPUT F$FAO("!/Getting !UL file!%S!/", GET_FILE_COUNT)
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!  Get the new files from the remote system
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Contents of input file:"
$	IF DEBUG THEN TYPE/OUTPUT=SYS$ERROR 'TEMPFILE_1'
$
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Connecting to remote system..."
$	OLD_SYMBOL_SCOPE = F$ENVIRONMENT("SYMBOL_SCOPE")
$	SET SYMBOL/SCOPE=(GLOBAL,LOCAL)
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MULTINET 
$	THEN
$	    SET noON
$	    DEFINE/USER_MODE SYS$OUTPUT 'TEMPFILE_2'
$	    'CONFIG_COMMAND' -
		  /NOINITIALIZATION -
		  /TAKE_FILE='TEMPFILE_1'
$	    STATUS = $STATUS
$	    SET ON
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_MGFTP
$	THEN
$	    SET noON
$	    DEFINE/USER_MODE SYS$OUTPUT 'TEMPFILE_2'
$	    'CONFIG_COMMAND' -
		  'CONFIG_SITE' -
		  /USERNAME="''CONFIG_USERNAME'" -
		  /PASSWORD="''CONFIG_PASSWORD'" -
		  /INITIALIZATION='TEMPFILE_1'
$	    STATUS = $STATUS
$	    SET ON
$	ENDIF
$
$	IF FTP_CLIENT_TYPE .EQ. TYPE_TCPWARE
$	THEN
$	    SET noON
$	    DEFINE/USER_MODE SYS$OUTPUT 'TEMPFILE_2'
$	    DEFINE/USER FTP_STARTUP 'tempfile_1'
$	    'CONFIG_COMMAND'
$	    STATUS = $STATUS
$	    SET noON
$	ENDIF
$
$	SET SYMBOL/SCOPE=('OLD_SYMBOL_SCOPE')
$
$	IF DEBUG THEN WRITE SYS$ERROR "-Debug- Output from FTP session:"
$	IF DEBUG THEN TYPE/OUTPUT=SYS$ERROR 'TEMPFILE_2'
$
$	IF CONFIG_LAST_TIME_FILE .NES. "" .AND. .NOT. STATUS
$	THEN
$	    OPEN/WRITE FOO 'CONFIG_LAST_TIME_FILE'
$	    WRITE FOO CONFIG_NEXT_TIME
$	    CLOSE FOO
$	ENDIF
$
$	IF CONFIG_MAILTO .NES. ""
$	THEN
$	    IF STATUS
$	    THEN
$		MAIL_SUBJECT = F$FAO("!AS: !UL file!%S transferred to local system", -
				     CONFIG_SITE, GET_FILE_COUNT)
$		MAIL_PN = F$FAO("!AS: !UL file!%S", -
				CONFIG_SITE, GET_FILE_COUNT)
$	    ELSE
$		SHOW SYMBOL STATUS
$		MAIL_SUBJECT = F$FAO("!AS: Following files were not transferred - check logs", -
				     CONFIG_SITE)
$		MAIL_PN = F$FAO("!AS: Failure!!", CONFIG_SITE)
$	    ENDIF
$	    SET noON
$	    MAIL 'TEMPFILE_4' 'CONFIG_MAILTO' -
		 /SUBJECT="''MAIL_SUBJECT'" -
		 /PERSONAL_NAME="''MAIL_PN'"
$	    SET ON
$	ENDIF
$
$!
$!!!  Purge local directories
$!
$
$	COUNT = 0
$ _PURGE_LOOP: 
$	IF COUNT .GE. CONFIG_DIR_TOTAL THEN GOTO _EXIT_PURGE_LOOP
$	FOO = CONFIG_DIRECTORIES_'COUNT'
$	IF (F$SEARCH(F$PARSE("*.*",F$ELEMENT(1,",",FOO))) .NES. "") THEN PURGE/LOG 'F$ELEMENT(1,",",FOO)'*.*		!DM
$	COUNT = COUNT + 1
$	GOTO _PURGE_LOOP
$_EXIT_PURGE_LOOP:
$
$_SUBMIT:
$	IF CONFIG_SUBMIT_AFTER .NES. "NONE"
$	THEN
$	    SET VERIFY
$	    SUBMIT -
		   /NOTIFY -
		   /LOG_FILE=FTP_MIRROR.LOG -
		   /PARAMETERS='F$ELEMENT(0,";",CONFIGURATION_FILE)' -
		   /noPRINTER -
		   /QUEUE='CONFIG_QUEUE' -
		   /NAME="FTP_Mirror" -
		   /AFTER="''CONFIG_SUBMIT_AFTER'" -
		   /KEEP -
		   'F$ELEMENT(0,";",F$ENVIRONMENT("PROCEDURE"))' 
$	    SET NOVERIFY
$	ENDIF
$	GOTO _EXIT
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$ _EXIT: 
$	GOSUB _CLEANUP
$	WRITE SYS$OUTPUT "Leaving FTP_Mirror ..."
$	IF F$TYPE(ORIGINAL_PRIV) THEN JUNK = F$SETPRV(ORIGINAL_PRIV)
$	VERIFY = F$VERIFY(VERIFY)
$	EXIT 1
$
$ _NO_CONFIG_FILE: 
$	WRITE SYS$ERROR "Could not find configuration file ",P1
$	WRITE SYS$ERROR "Aborting..."
$	GOTO _EXIT
$ 
$ _ERROR: 
$	ERROR_STATUS = $STATUS
$	WRITE SYS$ERROR "Unexpected error (%X''F$FAO("!XL",ERROR_STATUS)') in FTP_MIRROR.COM"
$	GOSUB _CLEANUP
$	IF F$TYPE(ORIGINAL_PRIV) THEN JUNK = F$SETPRV(ORIGINAL_PRIV)
$	VERIFY = F$VERIFY(VERIFY)
$	EXIT ERROR_STATUS
$
$ _ABORT: 
$	WRITE SYS$ERROR "User aborted FTP_MIRROR.COM"
$	GOTO _EXIT
$
$ _CLEANUP: 
$	CLOSE/NOLOG FILE
$	CLOSE/NOLOG OUTFILE
$	CLOSE/NOLOG REPORT_FILE
$	IF .NOT. DEBUG .AND. F$SEARCH(TEMPFILE_1) .NES. "" THEN -
	   DELETE 'TEMPFILE_1';*
$	IF .NOT. DEBUG .AND. F$SEARCH(TEMPFILE_2) .NES. "" THEN -
	   DELETE 'TEMPFILE_2';*
$	IF .NOT. DEBUG .AND. F$SEARCH(TEMPFILE_3) .NES. "" THEN -
	   DELETE 'TEMPFILE_3';*
$	IF .NOT. DEBUG .AND. F$SEARCH(TEMPFILE_4) .NES. "" THEN -
	   DELETE 'TEMPFILE_4';*
$	RETURN
================================================================================
Archive-Date: Tue, 13 Apr 1999 18:14:30 +0200
Date: Tue, 13 Apr 1999 18:14:22 +0200
Message-ID: <1176-Tue13Apr1999181422+0200-levitte@lp.se>
From: Richard Levitte - VMS Whacker <levitte@lp.se>
Reply-To: bugs@free.lp.se, levitte@lp.se
To: bugs@free.lp.se, SYSTEM@wolverine.acornsw.com
In-Reply-To: <990413114508.21a00185@wolverine.acornsw.com> (SYSTEM@wolverine.acornsw.com)
Subject: Re: Fixed a couple more things in FTP_MIRROR.COM (added a new feature as well).
MIME-Version: 1.0
Content-Type: Text/Plain; Charset=ISO-8859-1
Content-Transfer-Encoding: 8bit

Thank you.

-- 
R Levitte, Levitte Programming;  Spannv. 38, I;  S-168 35  Bromma;  SWEDEN
    Tel: +46-8-26 52 47; Cell: +46-708-26 53 44; Fax: +46-708-26 53 88
  PGP key fingerprint = 35 3E 6C 9E 8C 97 85 24  BD 9F D1 9E 8F 75 23 6B
 http://richard.levitte.org/pubkey2.asc for my public key.  levitte@lp.se

          "price, performance, quality.  Choose any two you like"
================================================================================
Archive-Date: Thu, 15 Apr 1999 18:45:27 +0200
Date: Thu, 15 Apr 1999 10:38:28 -0400
From: SYSTEM@wolverine.acornsw.com
Reply-To: bugs@free.lp.se, SYSTEM@wolverine.acornsw.com
To: bugs@free.lp.se
Message-ID: <990415103828.21e000c0@wolverine.acornsw.com>
Subject: Fixed a problem with enumerated directories and symbolic links.

$	VERIFY = 'F$VERIFY(F$TRNLNM("FTP_MIRROR_VERIFY"))'
$	SET = "SET"
$	SET SYMBOL/SCOPE=(noGLOBAL,noLOCAL)
$	GOTO _START_FTP_MIRROR

DESCRIPTION:

  Automates mirroring a remote FTP site.

PARAMETERS:

  P1 - configuration filename

REQUIREMENTS:

Due to the different commands used by FTP Clients, only a few FTP Clients are 
supported.  Due to the different output generated by different FTP Servers,
parsing routines have only been written for a few FTP Servers.

  o one of the following FTP Clients (on your system):
      - MultiNet 
      - MadGoat FTP
      - TCPware

  o mirrored against one of the following FTP Servers (on the remote system):
      - MultiNet
      - MadGoat FTP
      - TCPware
      - Unix

 =----------------------------------------------------------------------=

Copyright © 1994 by Dan Wing.
Copyright © 1997 by MadGoat Software, Inc.
Copyright © 1998 by Richard Levitte.
Copyright © 1999 by Dick Munroe

This code may be freely distributed and modified for no commercial gain
as long as this copyright notice is retained.  This program is supplied
'as-is', and with no warranty.

Created September 21, 1994, by Dan Wing, TGV <dwing@Cisco.com>
Hacked a lot by Richard Levitte <richard@levitte.org>
Features added by Hunter Goatley <goathunter@madgoat.com>

Please send bug reports to <bugs@free.lp.se>.

 =----------------------------------------------------------------------=

  REVERSE CHRONOLOGICAL MODIFICATION HISTORY
  ------------------------------------------

  T0.8-7  15-APR-1999  Dick Munroe <munroe@acornsw.com>
     The code that picks up the LS options for unix servers needs to supply
     the options when the directory is fully enumerated.  This avoids
     a bug when enumerating directories (or files) which are actually
     symbolic links on the server.

  T0.8-6  14-APR-1999  Dick Munroe <munroe@acornsw.com>
     The invocation of FTP that gets the directory listings assumed that
     any error coming back from FTP meant that things were not supposed
     to work.  I have disabled this test and as a result the failure to
     log in is properly detected and the job resubmitted, however this
     may lead to other problems downstream.  I suspect that a somewhat
     more sophisticated error recovery scheme will need to be evolved.
     If things fail due to either a login failure, or other issue, the
     directory structures don't have to be purged.

  T0.8-5  13-APR-1999  Dick Munroe <munroe@acornsw.com>
     Some FTP servers have a time limit on them.  I'm adding a
     MAXIMUM_FILES parameter to the configuration that allows some
     control over the load placed on the server.  Once the maximum
     number of files have been transferred, then the job is rescheduled.
     Frequently FTP servers are busy and you can't get logged in, so
     check for the 530 status and reschedule the job if that happens.
     To avoid spurious errors, check to see if directories contain
     files during the purge processing.

  T0.8-4  09-APR-1999  Dick Munroe <munroe@acornsw.com>
     Using a multinet FTP client requires that the VERBOSE mode of
     FTP transfer be used.  This, in turn, left stuff in the log files
     that, for some reason, the command procedure didn't know how to
     process.  There were similar issues for hooking up to aol.com, so
     now this procedure seems to work with all the ftp sites that I'm
     using regularly.

  T0.8-3  23-APR-1998  Richard Levitte <richard@levitte.org>
     A small bug corrected.  REMOTE_DIRECTORY wasn't set correctly
     under some circumstances.  Under others, it was set when it
     really shoulden't.

  T0.8-2  20-APR-1998  Richard Levitte <richard@levitte.org>
     Worked around the fact that the MadGoat client (and perhaps others)
     sputters lines like the following one right in the middle of the
     directory output:

	<226 File transfer Okay; Closing data connection.

  T0.8-1  07-APR-1998  Richard Levitte <richard@levitte.org>
     Corrected a small bug that caused a erroneous download to be made
     for a serie of Unix directories.  Of course, if `ls' could output
     the directory name for the first directory listed, we wouldn't
     have these problems...

  T0.8	   6-APR-1998	Hunter Goatley <goathunter@MadGoat.com>
     Explicitly enable or disable passive mode according to file setting.

  T0.7    06-APR-1998  Richard Levitte <richard@levitte.org>
     Merged in changes that Hunter Goatley <goathunter@madgoat.com>
     added in 27-MAY-1997.  His comment was:

	Updated for newer MGFTP releases and for TCPware.

  T0.6    05-APR-1998  Richard Levitte <richard@levitte.org>
     - Now understands the output from a Unix FTP server, and can
       download files from it.  ALL files are currently downloaded in
       Image mode.
     - An added feature is that "/..." at the end of a Unix directory
       specification means the same thing as the standard VMS
       ellipsis.
     - CAUTION:  Unix file specifications can ONLY be used as the
       first argument of the DIRECTORY configuratoin parameter.
     - Name conversion for Unix file specifications is done according
       to the following rules:
         1. An ending ".gz" is changed to "-gz" if there is another
            dot in the file name.
         2. And ending ".Z is changed to "_Z" if there is another dot
            in the file name.
         3. All remaining dots except the last are changed to
            underscores, except the last one in a file name.
         4. All other characters that are not legal in a VMS file name
            are changed to dollars.
     - A hack that saves the current time in a file has been added.
       If that file is found and there is a time specification in it,
       it is used to limit the download of file to those newer than
       that time.  The name of this file is configurable.
     - A mail address to send logs to is configurable.

  T0.5	  02-APR-1998  Richard Levitte <richard@levitte.org>
     Many hacks, among other supporting elipsis in directory specs,
     and support for the Process Software FTP server.  Unfortunatelly,
     I haven't made many notes of my changes.

  T0.0    25-OCT-1994  Dan Wing, wing@tgv.com
     Initial release.

$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$
$ _START_FTP_MIRROR: 
$
$	ON WARNING THEN GOTO _ERROR
$	ON CONTROL_Y THEN GOTO _ABORT
$
$	FTP_MIRROR_VERSION = "T0.8-3 BETA TEST Prerelease 7"								!DM
$	WRITE SYS$OUTPUT F$FAO("!/FTP_Mirror, version !AS.!/Started by !AS on node !AS on !AS, !AS !8AS.", -
			       FTP_MIRROR_VERSION, -
			       F$EDIT(F$GETJPI(0,"USERNAME"),"TRIM"), -
			       F$GETSYI("NODENAME"), -
			       F$CVTIME(,,"WEEKDAY"), -
			       F$CVTIME(,"ABSOLUTE","DATE"), -
			       F$CVTIME(,,"TIME"))
$
$	TRUE = 1
$	FALSE = 0
$	DEBUG = FALSE
$	IF F$TRNLNM("FTP_MIRROR_DEBUG") THEN DEBUG = TRUE
$	IF DEBUG THEN WRITE SYS$ERROR "FTP_Mirror debugging enabled."
$
$! setup defaults.  These can be overridden in the configuration file
$
$	CONFIG_FTP_CLIENT           = "MadGoat FTP"
$	CONFIG_COMMAND              = "FTP"
$	CONFIG_FTP_SERVER           = "MadGoat FTP"
$	CONFIG_SITE                 = ""
$	CONFIG_USERNAME             = "anonymous"
$	IF F$TRNLNM("UCX$INET_HOST") .NES. "" THEN CONFIG_PASSWORD = "mirror@" + F$TRNLNM("UCX$INET_HOST")
$	IF F$TRNLNM("MULTINET_HOST_NAME") .NES. "" THEN CONFIG_PASSWORD = "mirror@" + F$TRNLNM("MULTINET_HOST_NAME")
$	CONFIG_PASSIVE              = FALSE
$	CONFIG_SUBMIT_AFTER         = "+12:00:00"
$	CONFIG_QUEUE                = "SYS$BATCH"
$	CONFIG_FILE_TRANSFER        = "VMS"
$	CONFIG_LAST_TIME_FILE       = ""
$	CONFIG_MAILTO               = ""
$	CONFIG_MAXIMUM_FILES	    = %X7FFFFFFF									!DM
$
$	VALID_CONFIGURATION = TRUE           ! assume the best
$
$	TEMPFILE_1 = "SYS$SCRATCH:FTP_MIRROR_1_" + F$GETJPI(0,"PID") + ".TMP"
$	TEMPFILE_2 = "SYS$SCRATCH:FTP_MIRROR_2_" + F$GETJPI(0,"PID") + ".TMP"
$	TEMPFILE_3 = "SYS$SCRATCH:FTP_MIRROR_3_" + F$GETJPI(0,"PID") + ".TMP"
$	TEMPFILE_4 = "SYS$SCRATCH:FTP_MIRROR_4_" + F$GETJPI(0,"PID") + ".TMP"
$
$	CONFIG_LAST_TIME = ""
$	CONFIG_DIR_TOTAL = 0
$
$	TYPE_MULTINET = 1
$	TYPE_MGFTP    = 2
$	TYPE_TCPWARE  = 3
$	TYPE_UNIX     = 128
$	TYPE_OTHER    = 255
$
$	IF P1 .EQS. "" THEN P1 = "FTP_MIRROR.DAT"
$! make sure CONFIGURATION_FILE contains a full path, but also make sure
$! you get the right directory.  Guess what F$PARSE does to non-concealed
$! multivalued logical names.  It's not a pretty sight.  --  Richard Levitte
$	CONFIGURATION_FILE = F$SEARCH(P1)
$	IF CONFIGURATION_FILE .EQS. "" THEN GOTO _NO_CONFIG_FILE
$	GOSUB _CLEANUP
$
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$	OPEN/READ/ERROR=_ERROR FILE 'CONFIGURATION_FILE'
$ _CONFIG_LOOP:	
$	READ/END_OF_FILE=_EXIT_CONFIG_LOOP/ERROR=_ERROR FILE RECORD
$	RECORD = F$EDIT(RECORD,"COMPRESS,UNCOMMENT")
$	IF RECORD .EQS. "" THEN GOTO _CONFIG_LOOP
$
$	PARA1 = F$EDIT(F$ELEMENT(0," ",RECORD),"UPCASE")
$	PARA2 = F$ELEMENT(1," ",RECORD)
$	PARA3 = F$ELEMENT(2," ",RECORD)
$  
$	VALID_RECORD = FALSE
$
$	IF PARA1 .EQS. "SITE"
$	THEN
$	    CONFIG_SITE = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "USERNAME"
$	THEN
$	    CONFIG_USERNAME = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "PASSWORD"
$	THEN
$	    CONFIG_PASSWORD = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "DIRECTORY"
$	THEN
$	    CONFIG_DIRECTORIES_'CONFIG_DIR_TOTAL' = PARA2 + "," + PARA3
$	    CONFIG_DIR_TOTAL = CONFIG_DIR_TOTAL + 1
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "COMMAND"
$	THEN
$	    CONFIG_COMMAND = F$EXTRACT(F$LOCATE(" ",RECORD)+1,-1,RECORD)
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "PASSIVE"
$	THEN
$	    CONFIG_PASSIVE = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "PRIV"
$	THEN
$	    ORIGINAL_PRIV = F$SETPRV(PARA2)
$	    IF .NOT. F$PRIVILEGE(PARA2) THEN WRITE SYS$OUTPUT "%%Warning - not all requested privileges are authorized."
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "SUBMIT_AFTER"
$	THEN
$	    CONFIG_SUBMIT_AFTER = F$EDIT("''PARA2' ''PARA3'","TRIM")
$	    IF F$EDIT(PARA2,"UPCASE") .EQS. "NONE" -
	       .OR. F$EDIT(PARA3,"UPCASE") .EQS. "ONE" THEN -
	       CONFIG_SUBMIT_AFTER = "NONE"
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "BATCH_QUEUE"
$	THEN
$	    CONFIG_QUEUE = PARA2
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "FTP_CLIENT"
$	THEN
$	    CONFIG_FTP_CLIENT = F$EDIT(PARA2,"UPCASE")
$	    IF CONFIG_FTP_CLIENT .EQS. "MULTINET" 
$	    THEN 
$		CONFIG_FTP_CLIENT = "MultiNet"
$		CONFIG_COMMAND = "MULTINET FTP"
$		VALID_RECORD = TRUE
$	    ENDIF
$	    IF CONFIG_FTP_CLIENT .EQS. "MADGOAT" -
	       .OR. CONFIG_FTP_CLIENT .EQS. "MADGOAT_FTP"
$	    THEN 
$		CONFIG_FTP_CLIENT = "MadGoat FTP"
$		CONFIG_COMMAND = "FTP"
$		VALID_RECORD = TRUE
$	    ENDIF
$	    IF CONFIG_FTP_CLIENT .EQS. "TCPWARE"
$	    THEN
$		CONFIG_FTP_CLIENT = "TCPware"
$		CONFIG_COMMAND = "FTP"
$		VALID_RECORD = TRUE
$	    ENDIF
$	ENDIF
$
$	IF PARA1 .EQS. "FTP_SERVER"
$	THEN
$	    CONFIG_FTP_SERVER = F$EDIT(PARA2,"UPCASE")
$	    IF CONFIG_FTP_SERVER .EQS. "MULTINET" THEN -
	       CONFIG_FTP_SERVER = "MultiNet"
$	    IF CONFIG_FTP_SERVER .EQS. "MADGOAT" -
	       .OR. CONFIG_FTP_SERVER .EQS. "MADGOAT_FTP" -
	       THEN CONFIG_FTP_SERVER = "MadGoat FTP"
$	    IF CONFIG_FTP_SERVER .EQS. "TCPWARE" THEN -
	       CONFIG_FTP_SERVER = "TCPware"
$	    IF CONFIG_FTP_SERVER .EQS. "UNIX" THEN -
	       CONFIG_FTP_SERVER = "Unix"
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "FILE_TRANSFER"
$	THEN
$	    CONFIG_FILE_TRANSFER = F$EDIT(PARA2,"UPCASE")
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "LAST_TIME_FILE"
$	THEN
$	    CONFIG_LAST_TIME_FILE = F$EDIT(PARA2,"UPCASE")
$	    IF F$SEARCH(CONFIG_LAST_TIME_FILE) .NES. ""
$	    THEN
$		OPEN/READ FOO 'CONFIG_LAST_TIME_FILE'
$		READ FOO CONFIG_LAST_TIME
$		CONFIG_LAST_TIME = F$CVTIME(CONFIG_LAST_TIME,"COMPARISON")
$		CLOSE FOO
$	    ELSE
$		CONFIG_LAST_TIME = "1-JAN-1900"
$	    ENDIF
$	    ! We remove oen day just to make sure we get all files in
$	    ! spite of all kinds of timezone junk.  So we might get
$	    ! duplicates at times...  So what?
$	    CONFIG_NEXT_TIME = F$CVTIME("-1-","ABSOLUTE")
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "MAILTO"
$	THEN
$	    CONFIG_MAILTO = F$EDIT(PARA2,"UPCASE")
$	    VALID_RECORD = TRUE
$	ENDIF
$
$	IF PARA1 .EQS. "MAXIMUM_FILES"											!DM
$	THEN														!DM
$	    CONFIG_MAXIMUM_FILES = F$INTEGER(F$EDIT(PARA2,"UPCASE"))							!DM
$	    VALID_RECORD = TRUE												!DM
$	ENDIF														!DM
$															!DM
$	IF .NOT. VALID_RECORD
$	THEN
$	    WRITE SYS$OUTPUT "%%Warning - invalid configuration file record \", RECORD, "\"
$	    VALID_CONFIGURATION = FALSE
$	ENDIF
$
$	GOTO _CONFIG_LOOP
$  
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$ _EXIT_CONFIG_LOOP: 
$	CLOSE FILE
$
$	IF .NOT. VALID_CONFIGURATION
$	THEN
$	    WRITE SYS$OUTPUT "Error in configuration file."
$	    GOTO _EXIT
$	ENDIF
$
$	FTP_CLIENT_TYPE = TYPE_OTHER
$	IF CONFIG_FTP_CLIENT .EQS. "MultiNet" THEN -
	   FTP_CLIENT_TYPE = TYPE_MULTINET
$	IF CONFIG_FTP_CLIENT .EQS. "MadGoat FTP" THEN -
	   FTP_CLIENT_TYPE = TYPE_MGFTP
$	IF CONFIG_FTP_CLIENT .EQS. "TCPware" THEN -
	   FTP_CLIENT_TYPE = TYPE_TCPWARE
$
$	FTP_SERVER_TYPE = TYPE_OTHER
$	IF CONFIG_FTP_SERVER .EQS. "MultiNet" THEN -
	   FTP_SERVER_TYPE = TYPE_MULTINET
$	IF CONFIG_FTP_SERVER .EQS. "MadGoat FTP" THEN -
	   FTP_SERVER_TYPE = TYPE_MGFTP
$	IF CONFIG_FTP_SERVER .EQS. "TCPware" THEN -
	   FTP_SERVER_TYPE = TYPE_TCPWARE
$	IF CONFIG_FTP_SERVER .EQS. "Unix" THEN -
	   FTP_SERVER_TYPE = TYPE_UNIX
$
$	WRITE SYS$OUTPUT ""
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Remote site:",CONFIG_SITE)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Remote username:",CONFIG_USERNAME)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Remote password:",CONFIG_PASSWORD)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","FTP server:",CONFIG_FTP_SERVER)
$	WRITE SYS$OUTPUT ""
$	WRITE SYS$OUTPUT "  Directories:  (remote)                (local)"
$
$	COUNT = 0
$ _DISPLAY_LOOP_1: 
$	IF COUNT .GE. CONFIG_DIR_TOTAL THEN GOTO _EXIT_DISPLAY_LOOP_1
$	WRITE SYS$OUTPUT F$FAO("    !33AS !35AS", -
			       F$ELEMENT(0,",",CONFIG_DIRECTORIES_'COUNT'), -
			       F$ELEMENT(1,",",CONFIG_DIRECTORIES_'COUNT'))
$	IF F$PARSE(F$ELEMENT(1,",",CONFIG_DIRECTORIES_'COUNT'),,,,"SYNTAX_ONLY") .EQS. ""
$	THEN
$	    WRITE SYS$ERROR F$FAO("!5** Local directory specification (above) is invalid VMS syntax.")
$	    VALID_CONFIGURATION = FALSE
$	ENDIF
$	COUNT = COUNT + 1
$	GOTO _DISPLAY_LOOP_1
$ _EXIT_DISPLAY_LOOP_1: 
$
$	WRITE SYS$OUTPUT ""
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","FTP client:",CONFIG_FTP_CLIENT)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","DCL command:",CONFIG_COMMAND)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","File transfer mode:",CONFIG_FILE_TRANSFER)
$	IF CONFIG_PASSIVE
$	THEN
$	    CONFIG_PASSIVE = TRUE
$	    WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Passive mode:","Yes")
$	ELSE
$	    CONFIG_PASSIVE = FALSE
$	    WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Passive mode:","No")
$	ENDIF
$	IF CONFIG_LAST_TIME .NES. "" THEN -
	   WRITE SYS$OUTPUT F$FAO("  !40AS !AS",-
				  "Only get files created after:",-
				  CONFIG_LAST_TIME)
$	WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Resubmit after:",-
			       CONFIG_SUBMIT_AFTER)
$	IF CONFIG_SUBMIT_AFTER .NES. "NONE" THEN -
	   WRITE SYS$OUTPUT F$FAO("  !40AS !AS","Batch queue:",CONFIG_QUEUE)
$	IF CONFIG_MAILTO .NES. "" THEN -
	   WRITE SYS$OUTPUT F$FAO("  !40AS !AS",-
				  "Mail reports to:",-
				  CONFIG_MAILTO)
$	IF CONFIG_MAXIMUM_FILES .NE. %X7FFFFFFF THEN -									!DM
	   WRITE SYS$OUTPUT F$FAO("  !40AS !UL",-									!DM
				  "Maximum