;;;; Hey Emacs, this script might as well be -*- lisp -*-
;;;;
;;;; Install_AmiTCP - AmiTCP/IP installation script for Installer
;;;;
;;;; Copyright © 1996 AmiTCP/IP Group,
;;;;                  NSDi - Network Solutions Development Inc., Finland
;;;;                  All rights reserved.
;;;;
;;;; $Id: Install_AmiTCP,v 4.14 1994/10/24 20:57:34 jraja Exp $
;;;;
;;;; This script has been tested with Installer 1.24:
;;;;
;;;;     Installer and Installer project icon
;;;;     (c) Copyright 1991-93 Commodore-Amiga, Inc.  All Rights Reserved.
;;;;     Reproduced and distributed under license from Commodore.
;;;;
;;;;     INSTALLER SOFTWARE IS PROVIDED "AS-IS" AND SUBJECT TO CHANGE;
;;;;     NO WARRANTIES ARE MADE.  ALL USE IS AT YOUR OWN RISK.  NO LIABILITY
;;;;     OR RESPONSIBILITY IS ASSUMED.
;;;;
;;;; Use following Icon tooltypes / Command line options:
;;;; APPNAME=AmiTCP/IP
;;;; MINUSER=AVERAGE
;;;;
;;;;
;;;; What we are?
;;;;
(set app-name (cat @app-name " 4.3 Demo Version"))
(welcome "    Welcome to the " app-name " installation.\n")

;;;;
;;;; "Needs"
;;;;
(set need-version 37  ; version of operating system need by AmiTCP/IP
     need-memory (* 512 1024))
(set 
 ;;
 ;; Defaults, used if user want's to
 ;;
 default-provider "T-Online"		; name for this default-set
 my-host-if "cslip0"			; CSLIP by default
 my-host-if-type 1			; SLIP/CSLIP
 my-host-if-point-to-point 1		; point-to-point interface
 is-if-dynamic 1			; dynamic
 my-host-addr "0.0.0.0"			; dynamic
 my-host-name ""			; dynamic
 my-host-aliases ""			; ditto
 my-full-name ""			; -"-
 my-host-mtu 1006
 my-domain-name "Btx.DTAG.DE"		; T-Online
 default-user-name "amiga"
 name-server-list "NAMESERVER 194.25.2.129\n"
 domain-list (cat "DOMAIN " my-domain-name "\n")
 my-serial-device "serial.device"	; the offered default default

 ;;
 ;; Destination directories of the AmiTCP/IP
 ;;
 atcp-name "AmiTCP"
 atcp-assign (cat atcp-name ":")	; Assign to AmiTCP
 ;; Exported files
 export-dir (tackon atcp-assign "export")
 ;; Configuration
 conf-dir (tackon atcp-assign "db")
 ;; User binaries
 bin-dir (tackon atcp-assign "bin")
 ;; documentation
 doc-dir (tackon atcp-assign "doc")
 ;; devices directory
 devs-dir (tackon atcp-assign "devs")
 ;; AmigaGuide documentation
 help-dir (tackon atcp-assign "help")
 ;; DOS handlers
 l-dir (tackon atcp-assign "l")
 ;; libraries
 libs-dir (tackon atcp-assign "libs")
 ;;
 ;; If you add directories above, then also add the name of the variable below.
 ;; This is to have "for i in a b c d ..." construct
 ;;
 ;; These directories are always present
 dir-pat (cat "(" "devs" "|" "db" "|" "bin" "|" "doc" "|" 
	      "help" "|" "l" "|" "libs" ")")
 ;;
 ;; The source directory name
 source-dir (if (= 1 (exists @icon))
		    (pathonly (expandpath @icon))
		  (expandpath @icon))
 ;;
 ;; directories in exports
 ;;
 dist-networks-dir (tackon source-dir "export/Devs/Networks")
 ;; Mounts
 tcp-mount (cat 
	    "Assign TCP: Exists > NIL:\n" 
	    "IF Warn\n"
	    "  Mount TCP: from AmiTCP:devs/Inet-Mountlist\n"
	    "EndIf\n")
 )
 ;; How to get needed information?
(set
 net-setup-help
     "    You can get this information from your network administration.\n")

;;; copy "more" to ram: to be able to use it
(set
 pager-cmd 
 (if (exists "SYS:Utilities/More" (noreq))
     ((copyfiles
       (prompt "Copying sys:utilities/more to ram: for use")
       (source "SYS:Utilities/More")
       (dest   "RAM:")
       (safe)
       (optional "nofail"))
      "RAM:More")
   ("more")))

;; Return old AmiTCP: assign if we are aborting
(onerror
 (if old-atcp-directory
     (makeassign atcp-name old-atcp-directory)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 ask-ip-address
 ;;  Procedure to ask an IP address
 ;;
 ;; arguments:
 ;;  ::ask-ip-prompt   - Prompt text
 ;;  ::ask-ip-help     - help text
 ;;  ::ask-ip-need     - empty result allowed if not true
 ;;  ::ask-ip-default  - default value for the asked IP address
 ;;
 ;; locally used names:
 ;;  ::ask-ip-result
 (set ::ask-ip-result "")
 (while
     ((set ::ask-ip-result
	   (askstring
	    (prompt ::ask-ip-prompt
		    (if (NOT ::ask-ip-need)
			(cat "\nGive an empty string if you want to "
			     "by-pass this option."))
		    (if ::ask-ip-result
			(cat "\n\nYou entered an invalid value\n\""
			     ::ask-ip-result "\".\n"
			     "Enter a valid IP address.")))
	    (default ::ask-ip-default)
	    (help net-setup-help
		  ::ask-ip-help
		  "\n    Internet address is a string of at most four "
		  "decimal numbers separated by dots. For example, "
		  "\"130.233.161.40\" is a valid internet address.\n"
		  "    You will be asked again for the address, "
		  "if the address you entered is invalid.")))
      ;; loop while answer is unacceptable
      (if ::ask-ip-result
	  (NOT (patmatch "# #(1|2|3|4|5|6|7|8|9|0).#(1|2|3|4|5|6|7|8|9|0|.)# "
			 ::ask-ip-result))
	 ::ask-ip-need)))
 ::ask-ip-result)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 check-system-version
 ;; is your Exec recent enough?
 (set exec-version (/ (getversion) 65536))
 (transcript "Running on exec version " exec-version ".")
 (if (< exec-version need-version)	; check operating system version
     ((transcript "Installation aborted due to too low exec version.")
      (abort "The " @app-name " needs at least Exec version " need-version
	    " to run.\nYou have only version " exec-version ".\n")
      )))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 check-available-memory
 ;;
 (transcript "Checking available memory.")
 (set avail-mem (+ (database "total-mem")))
 (if (< avail-mem need-memory)
     ((message "Your system has only " (/ avail-mem 1024) " kilobytes of "
	       "free memory, while the " @app-name " needs at least "
	       (/ need-memory 1024) " to be useful.\n"
	       "You can continue the installation but be warned!")
      (transcript "User decided to continue installation while available "
		  "memory was below the recommended minimum."))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 check-user-level
 ;;
 (transcript "Checking user level.")
 (if (< @user-level 1)
     ((transcript "Aborting installation due to insufficient user level.")
      (abort "User level must be at least Average."))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 check-old-assign
 ;; If there is already the AmiTCP/IP installed, store the assign
 ;; to old-atcp-directory
 (transcript "Checking for already installed AmiTCP.")
 (if (exists atcp-assign (noreq))
     (set old-atcp-directory (getassign atcp-name)))
 (if old-atcp-directory
     (transcript "Existing AmiTCP detected at directory " 
		 old-atcp-directory ".")))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 ask-accept-license ;; Ask if the user accepts license conditions
 (transcript "Asking if the user accepts the license conditions.")
;;
;; use "more" to show the full license text
;;
 (run (cat "run " pager-cmd) (tackon source-dir "LICENSE") (safe))
 (message "\nAmiTCP/IP is a copyrighted propiertary software of "
	  "the Network Solutions Development Inc.\n"
          "\nPlease read the shown license text carefully.\n"
          "\nBy proceeding the installation of this software you "
	  "indicate that you accept the license conditions.\n"
	  )
 )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 select-destination-directory
 ;; Select destination directory for the installation. We suggest the user
 ;; to install to the place from where the installer was started. This is
 ;; since normally this software will be unarchived to its proper location
 ;; and the files don't have to be copied any more.
 ;;
 (transcript "Selecting destination directory for the installation.")
 (while
     ((set @default-dest
	   (askdir
	    (prompt "Select directory where to install the " app-name ".\n"
		    "Most of the files don't have to be copied, if you accept "
		    "the offered default.")
	    (help "    Here you can specify location where to install "
		  "the " app-name ".\n"
		  "    Installation can be made on-place. "
		  "This is recommended if you have already unarchived "
		  "the " app-name " archive to its final location. "
		  "In this case "
		  "most of the files are left where they are. "
		  "Only necessary files are copied to different "
		  "positions.\n"
		  "    Installation must NOT be made on top of an older "
		  "version of the " @app-name ".")
	    (newpath)
	    (default source-dir)))
      (if (= 2 (exists @default-dest))
	  ;; check that installation is not tried over the old version
	  (if (OR (exists (tackon @default-dest "bin/AmiTCP")) ; version 1.0
		  (> (getversion (tackon source-dir "AmiTCP"))
		     (if (exists (tackon @default-dest "AmiTCP"))
			 (getversion (tackon @default-dest "AmiTCP"))
		       $7FFFFFFF)))
	      ((message "You are possibly trying to install the " @app-name " "
			"over an old version of it.\n"
			"It is not allowed.\n"
			"You should select some other directory or abort "
			"the installation.")
	       1)
	    0)
	((makedir @default-dest
		 (infos))
	 0))))

 ;; Make the AmiTCP: assign
 (makeassign atcp-name @default-dest))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 copy-files-to-destination ;;; Copy all files if not installing on-place
 ;;
 (if (= source-dir
	(expandpath @default-dest))
     (if (> @user-level 1)
	 (message "\nSource and destination directories are the same, "
		  "not copying."
		  (help "    The " app-name " files don't have to be copied, "
			"since the source and the destination directories are "
			"the same.")))
   ((transcript "Copying " app-name " files from " source-dir " to "
		@default-dest ".")
    (foreach source-dir dir-pat
	     ((set dest-dir (tackon @default-dest @each-name))
	      (if (NOT (exists dest-dir))
		  (makedir dest-dir))
	      (copyfiles (all)
			 (source (expandpath @each-name))
			 (dest dest-dir)
			 (prompt "Copying files to the selected location.")
			 (optional "askuser"))))
    (copyfiles (source source-dir)
	       (dest @default-dest)
	       (prompt "Copying files to the selected location.")
	       (pattern "#?")
	       (files)
	       (infos)
	       (optional "askuser"))))
 ;;
 ;; Create AmiTCP:log if it does not exist already
 ;;
 (if (NOT (= 2 (exists (tackon atcp-assign "log"))))
     (makedir (tackon atcp-assign "log")))
 ;;
 ;; Create AmiTCP:home if it does not exist already
 ;;
 (if (NOT (= 2 (exists (tackon atcp-assign "home"))))
     (makedir (tackon atcp-assign "home")))
 ;;
 ;; Add script flags to the scripts, pure flags to pure programs
 ;;
 (protect (tackon bin-dir "netstat") "+s +e")
 (protect (tackon bin-dir "SynClock") "+s +e")
 (protect (tackon bin-dir "stopnet") "+s +e")
 (protect (tackon bin-dir "NapsaTerm") "+p +e")
 )


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 ask-slip-config
 ;;
 ;; the my-host-if has to be set before this is called
 ;;
 ;; This sets the if-config-file on return ("" if not applicaple).
 ;; The config file is returned without the path and it will be put to the 
 ;; ENV:Sana2 directory by the generated startnet script.
 ;; The contents is stored in if-config.
 ;;
 (transcript "Creating configuration file for SLIP/CSLIP devices.")

 ;;
 ;; Subroutine to check if the device exists
 ;;
 (procedure
  serial-device-exists
  ;;
  ;; Check if serial device (my-serial-device) exists either as a file or
  ;; as a resident device.
  ;;
  (if (<> my-serial-device "")
      (if (= 1 (exists my-serial-device)) ;; file exists?
	  (<> (getversion my-serial-device) 0) ;; file version available?
	(if (<> (getversion (fileonly my-serial-device) (resident)) 0)
					;; resident version available?
	    ((set my-serial-device (fileonly my-serial-device)) ;; remove path
	     1) ;; true, exists
	  ))
    )
  )

 ;;
 ;; Loop until the user is satisfied
 ;;
 (while
     ((set my-serial-device
	   (askfile (prompt "Select the SERIAL device driver for "
			    my-host-if ":\n"
			    "NOTE: See Help."
			    )
		    (default (if (patmatch "#?:#?" my-serial-device)
				 my-serial-device
			       (expandpath (cat "DEVS:" (fileonly my-serial-device)))))
		    (help "    You should select the serial device driver to "
			  "be used for the transport of " my-host-if ". "
			  "You will be separately asked for the unit number.\n"
			  "    This list lists all devices in DEVS:. "
			  "Normally you would want to select "
			  "`serial.device', but "
			  "if your serial device is ROM resident, "
			  "e.g. gvpser.device, "
			  "you should enter its name manually.\n"
			  )))
      (if (NOT (serial-device-exists))
	  (if (<> my-serial-device "")
	      ((message "\n"
			"   The serial device " my-serial-device " does not "
			"exist. You will be prompted again for the serial "
			"device.")
	       1 ; ask again
	       )
	    1 ; empty string was given, DO ask again
	    )
	(
	 ;;
	 ;; remove the prefix from the file name
	 ;;
	 (if (= (pathonly (expandpath my-serial-device))
		(expandpath "DEVS:"))
	     (set my-serial-device (fileonly my-serial-device)))
	 
	 (set my-serial-unit
	      (asknumber
	       (prompt "\nSelect unit number for the " my-serial-device ":")
	       (default 0)
	       (help "    Select the unit number for the device "
		     my-serial-device " to use. This is 0 for the "
		     "internal serial port, but might be other for "
		     "other serial devices."))
	      my-serial-baud
	      (asknumber
	       (prompt "\nGive the baud rate for the " my-serial-device 
		       " unit " my-serial-unit ".\n"
		       "\nPlease start with a low value like 9600, "
		       "if you are not absolutely sure that your SLIP "
		       "line works at higher speeds.\n")
	       (default 9600)
	       (help "    The baud rate MUST match the one used while "
		     "dialling to the SLIP provider.\n"
		     "    Since higher speeds may have some problems, you "
		     "should always start with some reasonably low baud "
		     "rate (like 9600) and then, when your SLIP setup "
		     "works, try out the higher speeds."))
	      my-slip-options-bitmap
	      (askoptions
	       (prompt "\nSelect additional options to be used with the "
		       my-host-if ":\n"
		       "\nPlease see Help for explanations for each option.")
	       (choices "Carrier Detect" "Hardware-handshake (CTS/RTS)"
			"EOF-mode")
	       (default %110)
	       (help "    Carrier Detect (CD): "
		     "If selected, causes the " my-host-if " to pay "
		     "attention to the status of the carrier detect line. "
		     "If this isn't selected, the CD signal will be "
		     "ignored.\n"
		     "    Hardware-handshake (7WIRE): "
		     "If selected, the seven wire (or hardware, i.e., "
		     "CTS/RTS) handshaking is used with the modem. "
		     "This option is strongly recommended for high baud "
		     "rates.\n"
		     "    EOF-mode (EOFMODE): "
		     "If selected, causes " my-host-if " to use EOFMODE. "
		     "This reduces the CPU load considerably, but it "
		     "won't work with all different (buggy) serial "
		     "devices (like the a2232)."))
	      my-slip-options
	      (cat (if (in my-slip-options-bitmap 0)
		       "CD ")
		   (if (in my-slip-options-bitmap 1)
		       "7WIRE ")
		   (if (in my-slip-options-bitmap 2)
		       "EOFMODE"))
	      )
	 
	 (if (not (askbool
		   (prompt
		    "This is the information you gave for the configuration "
		    "for the " my-host-if ":\n"
		    "\nSerial device: " my-serial-device
		    "\nSerial unit: " my-serial-unit
		    "\nSerial baud rate: " my-serial-baud
		    "\nSLIP options: " my-slip-options
		    "\n\nIs this correct?")
		   (help
		    "    Check the information shown. If you do not "
		    "confirm it, all of it will be asked again.")))
	     1			; ask it all again
	   (
	    ;; store the file name and the configuration string
	    (set if-config-file my-host-if)
	    (if (= my-host-if "slip0") ;; special case
		(set if-config-file "rhslip0")
	      (if (= my-host-if "cslip0")
		  (set if-config-file "rhslip0")))
	    (set if-config-file
		 (cat if-config-file ".config"))
	    (set if-config
		 (cat my-serial-device " "
		      my-serial-unit " "
		      my-serial-baud " "
		      "0.0.0.0 MTU=1500 "
		      my-slip-options))
	    0				; no need to ask again
	    ))))
      )
   )
 )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 update-devices
 (transcript "Updating Sana-II device drivers.")
 ;;
 ;; Create directory DEVS:Networks if it does not exist already
 ;;
 (if (NOT (= 2 (exists "DEVS:Networks")))
     (makedir "DEVS:Networks"))
 ;;
 ;; Copy each driver in the distribution to the DEVS:Networks if necessary
 ;;
 (working "Checking Sana-II device drivers...")
 (if (= 2 (exists dist-networks-dir))
     (foreach
       dist-networks-dir "#?.device"
       ((set dist-name (tackon dist-networks-dir @each-name)
	     devs-name (tackon "DEVS:Networks" @each-name)
	     dist-version (getversion dist-name)
	     copy-it (NOT (exists devs-name)))
	;;
	;; Check if the driver should be copied over
	;;
	(if (NOT copy-it)
	    (set copy-it
	             ; or if the driver in DEVS:Networks is of older version
		 (< (set devs-version (getversion devs-name)) dist-version)))
	(if (NOT copy-it)
	    (set copy-it
		     ; or if the files are of the same version but different
		 (set sum-differs (if (= dist-version devs-version)
				      (<> (getsum dist-name)
					  (getsum devs-name))
				    0))))
	(if copy-it
	    (copyfiles
	     (prompt "Should this Sana-II driver be installed in Devs:Networks?\n"
		     (if devs-version
			 (cat "A driver with the same name exists already"
			      (if sum-differs
				  (cat ", it has the same version, but the "
				       "files are not the same.")
				(cat ", but the driver in the "
				     "DEVS:Networks is of older version.")))
		       ""))
	     (help
	      "    The Sana-II drivers should be located in "
	      "the DEVS:Networks directory.\n"
	      "    This directory is the official location for the Sana-II "
	      "device drivers.")
	     (source (pathonly dist-name))
	     (choices (fileonly dist-name))
	     (dest "DEVS:Networks")
	     (files)
	     (optional "nofail" "askuser")
	     (confirm "average"))))))

 ;;; ask user which export/Env/Sana2 files should be copied
 (if (= 2 (exists (tackon source-dir "export/Env/Sana2")))
     (if
	 (askbool (prompt "\nDo you want to install example Sana-II "
			  "configuration files?\n"
			  "Copies will be confirmed.")
		  (help "    This release contains example configuration "
			"files for the SLIP devices and Agnet (a Sana-II "
			"pseudo device).\n"
			"    The copying of each file will confirmed.")
		  (default 1))
	 (copyfiles
	  (prompt "Select Sana-II configuration files to be copied:")
	  (help "    These configuration files are for example only. "
		"You need to edit them for them to be useful. Refer to "
		"the documentation of the Sana-II device in question. "
		"The AmiTCP:doc directory contains documentation for "
		"the drivers included in this release.\n"
		"    The files will be copied to the ENVARC: by default. "
		"Normally they will be copied to ENV: on next reboot.")
	  (source (tackon source-dir "export/Env/Sana2"))
	  (dest "ENVARC:sana2")
	  (all)
	  (files)
	  (optional "nofail" "askuser")
	  (confirm "average")))
   ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 ask-update-devices
 (if (= 2 (exists dist-networks-dir))
     (if use-default-provider
	 ((transcript "Updating Sana-II devices...")
	  (update-devices))
       (if (askbool
	    (prompt "\nDo you want to update your Sana-II network device "
		    "drivers?\n"
		    "Each copy will be confirmed.")
	    (help
	     "    Each new AmiTCP/IP distribution usually contains "
	     "updated versions of some of the provided Sana-II network "
	     "device drivers. If you choose \"Yes\", this installation "
	     "script will check for each device, if this is the case."))
	   (update-devices)
	 (transcript "User did not want to update Sana-II drivers.")))
   (transcript "Directory " dist-networks-dir " not found.")))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 ask-if-dynamic ;; Ask if the network connection is dynamic
 (set is-if-dynamic
      (askbool (prompt "\nIs your network connection dynamic?")
	       (help "    If your network connection is dynamic, your IP "
		     "address will change each time you connect to the "
		     "network. Because of this you can not have a "
		     "fixed host name either. If this is the case, "
		     "you will not be asked for the host name.\n"
		     "    If your network connection is not "
		     "dynamic, then you should have a fixed IP address.\n"
		     "    The \"startnet\" script produced by this "
		     "installation script will have an optional IP "
		     "address argument, which you should use if your "
		     "network connection is dynamic.\n")
	       (default is-if-dynamic)))
 )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 ask-hostname ;; Get host name, domain and aliases
 ;;
 ;; Get the hostname from environment variable
 ;;
 (set def-full-name (if (exists "ENV:HOSTNAME")
			(getenv "HOSTNAME")
		      "")
      my-host-name ""
      my-host-aliases ""
      my-domain-name "")
 ;;
 ;; Break the name into the host and domain parts
 ;;
 (set ::index 0
      ::length (strlen def-full-name))
 (while (AND (< ::index ::length)
	     (NOT (= (substr def-full-name ::index 1) ".")))
   (set ::index (+ ::index 1)))
 (if (= ::index ::length)
     (set def-host-name ""
	  def-domain-name "")
   (set def-host-name (substr def-full-name 0 ::index)
	def-domain-name (substr def-full-name (+ ::index 1))))
 ;;
 ;; If the network connection is dynamic, do not ask the host name, but leave
 ;; it empty.
 ;;
 (if (not is-if-dynamic)
     ;;
     ;; Ask the host name from the user
     ;;
     (while (OR (= my-host-name "")
		;; check that name has no dots
		((set ::index 0
		      ::length (strlen my-host-name))
		 (while (AND (< ::index ::length)
			     (NOT (= (substr my-host-name ::index 1) ".")))
		   (set ::index (+ ::index 1)))
		 (NOT (= ::index ::length))))
       (set my-host-name
	    (askstring
	     (prompt
	      (cat "\nEnter the host name of your computer (not including "
		   "domain)"
		   (if (= my-host-name "")
		       ":"
		     (cat ".\nThe value " my-host-name " is illegal, since it "
			  "contains a dot."))))
	     (help net-setup-help
		   "    Host name is a string NOT containing dots (.), "
		   "example: \"my-amiga\".\n"
		   "    Domain specifies the administrative domain of the "
		   "network where your host is connected. For example, "
		   "\"nsdi.fi\" is the domain name of the Network "
		   "Solutions Development Inc., Finland.\n")
	     (default def-host-name))))
   )
 ;;
 ;; ask the domain name from the user
 ;;
 (set my-domain-name
      (askstring
       (prompt (if is-if-dynamic 
		   "\nEnter your domain name:"
		 "\nEnter the domain part of your host name:"))
       (help net-setup-help
	     "    Domain specifies the administrative domain of the "
	     "network where your host is connected. For example, "
	     "\"nsdi.fi\" is the domain name of the Network "
	     "Solutions Development Inc., Finland.\n"
	     "    If you do not have a domain name server, then you might "
	     " not have a domain, either. In this case you can leave the "
	     "domain empty.\n")
       (default def-domain-name)))
 ;;
 ;; Set the full name of this host. 
 ;;
 (set my-full-name (if my-host-name
		       (cat my-host-name
			    (if my-domain-name
				(cat "." my-domain-name)
			      ""))))
 ;;
 ;; ask alias names for this host if the host name is not empty
 ;;
 (if my-host-name
     (while
	 (set new-host-name
	      (askstring
	       (prompt "Give aliases to your computer " my-full-name
		       " one at a time."
		       (if my-host-aliases
			   (cat "\n\nAliases are:\n" my-host-aliases)))
	       (default "")
	       (help net-setup-help
		     "    Your computer may have additional names "
		     "(aliases) to its official name.\n"
		     "    The plain host name (" my-host-name ") will "
		     "be understood by the " app-name " automatically, so "
		     "you do not need to include that as an alias. "
		     )))
       (set my-host-aliases (cat my-host-aliases " " new-host-name))))
 )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Ask network interfaces
;;;
;;; Loop until no device is given.
;;;
(procedure
 ask-interfaces
 ;;
 ;; Procedure to ask the network device driver name
 ;;
 ;; (Returns TRUE if an interface was selected)
 ;;
 ;; NOTE: Currently only 8 choises within each interface type are allowed
 ;;       (excluding the "none" entry).
 ;; 
 (procedure
  if-ask-device
  (set my-host-if-type
       ((set choice
	     (askchoice
	      (prompt (cat "Select the network interface type to be used:")
		      (help "    You should select your network interface "
			    "type from the given choices. If your device type "
			    "is "
			    "not listed select some other (which matches "
			    "closest to your device) and alter "
			    "the installation (and db/interfaces file) "
			    "by hand.\n"
			    "    Select \"None\" if you do not want to "
			    "configure an interface.")
		      (choices "None"			; 0
			       "SLIP/CSLIP"		; 1
;			       "PPP"			; 2
			       )
		      (default 1))))
	;;;
	;;; Destination IP address is asked for p-to-p interfaces only
	;;; also, the destination IP address suffices as the default 
	;;; gateway address in most cases.
	;;;
	(set my-host-if-point-to-point 1)
	choice)
       
       my-host-if
       (if (= my-host-if-type 0)
	   ""
	 ((set choice
	       (askchoice
		(prompt (cat "Select the network interface to be used:"))
		(help "    You should select your network interface "
		      "from the given choices. If your device is "
		      "not listed select some other (which matches "
		      "closest to your device) and alter "
		      "the installation (and db/interfaces file) "
		      "by hand.\n"
		      "    Select \"None\" if you do not want to "
		      "configure an interface.")
		(select (- my-host-if-type 1)
			(			; type 1 (SLIP/CSLIP)
			 (choices "None"	; 0
				  "rhslip"	; 1
				  "rhcslip"	; 2
				  )
			 (default 2))
;			(			; type 2 (PPP)
;			 (choices "None"	; 0
;				  "ppp"		; 1
;				  )
;			 (default 1))
			)
		))
	  (if (= choice 0)
	      ""
	    ;;;
	    ;;; Following names must match the ones defined in db/interfaces
	    ;;;
	    (select (+ (* (- my-host-if-type 1) 8) (- choice 1))
					; type 1 (SLIP/CSLIP)
		    "slip0"	; (1) 
		    "cslip0"	; (2)
		    ""		; (3)
		    ""		; (4)
		    ""		; (5)
		    ""		; (6)
		    ""		; (7)
		    ""		; (8)
;					; type 2 (PPP)
;		    "ppp0"	; (1) 
;		    ""		; (2)
;		    ""		; (3)
;		    ""		; (4)
;		    ""		; (5)
;		    ""		; (6)
;		    ""		; (7)
;		    ""		; (8)
		    ))))))


 ;;
 ;; Ask for the IP address of this host
 ;;
 (procedure
  if-ask-address
  (set ::ask-ip-prompt (cat
			(if is-if-dynamic
			    (cat 
			     "Your IP address is dynamic, but you still "
			     "should give a default "))
			"IP address for the interface " my-host-if ".\n"
			(if is-if-dynamic
			    (cat 
			     "When you start the " app-name " "
			     "with \"startnet\", "
			     "You should give the correct IP address as an "
			     "argument to override the default.")))
       ::ask-ip-help (cat "    If you have no connection to the global "
			  "Internet and are configuring a private network, "
			  "you can select your IP addresses from following "
			  "ranges: (see RFC1597)\n\n"
			  "10.0.0.0 - 10.255.255.255\n"
			  "172.16.0.0 - 172.31.255.255\n"
			  "192.168.0.0 - 192.168.255.255\n\n"
			  "NOTE: The addresses at the end of the ranges are "
			  "NOT usable IP addresses for a host! So select your "
			  "address from INSIDE the range (for example: "
			  "10.1.1.1).")
       ::ask-ip-need 1
       ::ask-ip-default ""
       my-host-addr (ask-ip-address)))

 (procedure
  if-ask-mtu
  (set my-host-mtu
       (asknumber
	(prompt "\nGive the Maximum Transfer Unit (MTU) for the "
		my-host-if ":\n")
	(range 76 1500)
	(default (if (and (>= my-host-mtu 76) (<= my-host-mtu 1500))
		     my-host-mtu
		   576))
	(help "    Smaller MTU values offer better interactive response, "
	      "but higher MTU values yeald better throughput.\n"
	      "    The value 576 is very common choice."
	      ))
       )
  )

 ;;
 ;; Ask for confirmation on given information
 ;;
 (procedure
  if-confirmation
  (askbool
   (prompt "This is the information you gave for this interface:\n"
	   "\nInterface: " my-host-if
	   "\nInterface address: " (if is-if-dynamic
				       "<dynamic>" 
				     my-host-addr)
	   "\nMTU: " my-host-mtu
	   "\n\nIs this correct?")
   (help "    Check the information shown. If you do not confirm it, "
	 "all of it will be asked again.")))

 ;;
 ;; Set startup string to contain configuration for the loopback device
 ;; (Other information will be later appeneded to this string variable).
 ;;

 ;;
 ;; Ask for interfaces
 ;;
 (while
     (if (if-ask-device)
	 ((if-ask-address)
	  (if-ask-mtu)
	  (if (if-confirmation)
	      ((transcript "Adding interface " my-host-if)
	       0) ;; interface given
	    1) ;;; confirmation not given, ask again
	   )
       1 ;;; none selected, ask again
       ))
 )


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; resolv.conf configuration
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
(procedure
 ask-nameservers ;;; Ask addresses to the name servers
 ;;
 (set name-server-list ""
      name-server-text-list "")
 (while
     (set ::ask-ip-prompt
	  (cat "Enter the IP addresses of the name servers (one at a time). "
	       "The name servers will be searched in the given order.\n"
	       (if name-server-text-list
		   ("\nIncluded name servers are: %s\n"
		    name-server-text-list)))
	  ::ask-ip-help
	  (cat "    A name server is used to resolve host "
	       "names to internet addresses. This allows you "
	       "to use symbolic names for the hosts instead "
	       "of internet addresses.\n"
	       "    In Unix systems the name server addresses are "
	       "usually stored into the file `/etc/resolv.conf`.\n")
	  ::ask-ip-need 0
	  ::ask-ip-default ""
	  name-server-addr (ask-ip-address))
   (set name-server-list (cat name-server-list
			      "NAMESERVER " name-server-addr "\n")
	name-server-text-list (cat name-server-text-list "\n"
				   name-server-addr))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
(procedure
 ask-domains
 ;;
 (set domain-list ""
      text-domain-list "")
 (while
     (set domain
	  (askstring
	   (prompt
	    "Give domain names (one at a time) to search.\n"
	    "Press proceed after you have given each domain.\n"
	    "Give empty domain after you have finished.\n"
	    (if text-domain-list
		(cat "\nIncluded domains are:"
		    text-domain-list)))
	  (help
	   net-setup-help
	   "    In many environments more than one search domain "
	   "is needed for name resolution.\n"
	   "    For example, most of computers in the Helsinki "
	   "University of Technology are under single domain: "
	   "\"hut.fi\", so the full name of computer named "
	   "\"vipu\" would be \"vipu.hut.fi\". If the default "
	   "domain is \"hut.fi\", then this computer can be "
	   "referred without the domain part of the name (just "
	   "\"vipu\"). However, the computer science department "
	   "has its own domain \"cs.hut.fi\". When computers of "
           "the computer science department "
	   "are referred, the full name must be supplied, e.g. "
	   "\"colossus.cs.hut.fi\". This can be avoided by "
	   "providing \"cs.hut.fi\" as a secondary search domain. "
	   "The domains are searched in the given order. It is "
	   "fastest to give the most used domain first.\n"
	   "    In Unix systems the domain names are "
	   "usually stored into the file `/etc/resolv.conf`.\n")
	  (default (if domain-list "" my-domain-name))))
  (set domain-list ("%sDOMAIN %s\n" domain-list domain)
       text-domain-list (cat text-domain-list "\n" domain)
       default-domain "")))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 create-config-file
 ;;
 (textfile (dest (tackon conf-dir "resolv.conf"))
	   (append
	    (if name-server-list (cat "; Name servers\n" name-server-list)))
	   (append
	    (if domain-list (cat "; Domain names\n" domain-list)))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 create-startup-script
 ;;
 ;; Create the network startup-script (AmiTCP:bin/startnet)
 ;;
 (textfile (dest (tackon bin-dir "startnet"))
	   (append
	    (cat
					;;; Script header
	     ".key IPADDRESS\n"
	     ".bra {\n"
	     ".ket }\n"
	     ".def IPADDRESS " my-host-addr "\n"
	     "\n"
					;;; Log in
	     "; log in\n"
	     "echo\n"
	     "echo login: " default-user-name "\n"
	     (tackon bin-dir "login") " -f " default-user-name "\n"
					;;; Start AmiTCP
	     "run AmiTCP:AmiTCP\n"
	     "WaitForPort AMITCP\n"
					;;; Create interface config file
	     (if if-config-file
		 (cat
		  "; Assure that ENV:Sana2 exists\n"
		  "if not exists ENV:Sana2\n"
		  "  makedir ENV:Sana2\n"
		  "endif\n"
		  "; Create " my-host-if " configuration file\n"
		  "echo \"" if-config "\" >ENV:Sana2/" if-config-file "\n"))
					;;; Configure the network interface
	     "; Configure " my-host-if "\n"
	     (tackon bin-dir "ifconfig") " " my-host-if " {IPADDRESS}"
	     " mtu " my-host-mtu
	     "\n"
					;;; Add the host name to the netdb
	     (if my-host-name
		 (cat
		  "; Add IP address entry for this host \n"
		  "rx \"address AMITCP; 'ADD START HOST {IPADDRESS} "
		  my-full-name " " my-host-aliases "'\""
		  "\n"))
					;;; Set the ENV:HOSTNAME
	     "setenv HOSTNAME `AmiTCP:bin/hostname`\n"
					;;; Mount TCP: (inet-handler)
	     tcp-mount
	     "\n")))
 (protect (tackon bin-dir "startnet") "+s +e"))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 update-user-startup
 ;;
 (set started-at-boot 0
      to-be-added-to-startup
      (cat "assign " atcp-assign " " @default-dest "\n"
	   "path " bin-dir " add\n"
	   (if (not is-if-dynamic)
	       (if (askbool
		    (prompt
		     "\nDo you want the " @app-name
		     " to be started at the system startup?")
		    (help
		     "    If you decide not to start the " @app-name " at "
		     "startup, you can later start it by giving command "
		     "\"startnet\" "
		     "at the command shell."))
		   ((set started-at-boot 1)
		    (tackon bin-dir "startnet\n"))))
	   )
      complete-to-be-added-to-startup (cat ";BEGIN " @app-name "\n"
					   to-be-added-to-startup
					   ";END " @app-name "\n"))
 ;; Ask for confirmation to add
 (if use-default-provider
     (set do-the-startup 1)
   (set do-the-startup
	(askbool
	 (prompt "\nDo you want Installer to make the required changes to "
		 "your s:user-startup script?\n"
		 "\n(There is a problem with Installer making these "
		 "changes if you do not have the original boot volume "
		 "mounted. Installer may crash or corrupt your system "
		 "in that case.)")
	 (help "If you do not want Installer make the changes, it will "
	       "create a script file containing commands which you should "
	       "add to the s:user-startup file."))))
 (if do-the-startup
     ;; Do the addition
     (startup
      @app-name
      (command to-be-added-to-startup)
      (prompt "Installer will modify your S:User-Startup file. "
	      "Following lines will be appended to it:\n\n"
	      complete-to-be-added-to-startup)
      (help "   Installer needs to make indicated modifications to "
	    "your user startup file to make sure that everything is "
	    "correctly set up to run the " @app-name ".\n"
	    "   You should make modifications later by hand "
	    "if you skip this part."))
   ;; Let user add commands
   ((set addition-to-user-startup
	 (tackon atcp-assign "addition-to-user-startup"))
    (textfile (dest addition-to-user-startup)
	      (append complete-to-be-added-to-startup))
    (message "Installer created file " addition-to-user-startup
	     ", which you can add to your startup file by hand. "
	     "The file includes following changes:\n\n"
	     complete-to-be-added-to-startup))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 ask-copy-old-configuration
 ;;
 ;; Copy old configuration files
 ;; Returns TRUE if AmiTCP does not need to be configured.
 ;; The reconfiguration is forced if old AmiTCP version is not 4 or higher,
 ;; since the bin/startnet must be modified.
 ;;
 (set
  edit-change-fingerd "t:edit-change-fingerd"
  old-conf-dir (tackon old-atcp-directory "db")
  old-resolv.conf (tackon old-conf-dir "resolv.conf")
  old-startnet (tackon old-atcp-directory "bin/startnet")
  old-motd (tackon old-conf-dir "motd"))
 ;;
 ;; return version of the old AmiTCP detected
 ;;
 (procedure 
  get-old-atcp-version
  (if (exists (tackon old-atcp-directory "AmiTCP") (noreq))
      (/ (getversion (tackon old-atcp-directory "AmiTCP")) 65536)
    0))
 ;;
 (set old-atcp-version (get-old-atcp-version))
 ;;
 ;; following is called only if old version is high enough
 ;;
 (procedure 
  copy-myhost-config 
  (if (AND (exists old-resolv.conf)
	   (exists old-startnet))
      ((if (>= @user-level 2)
	   (message "\nCopying files\n\n"
		    old-resolv.conf "\n"
		    old-startnet "   \n"
		    "\nto directory \"" @default-dest "\"."))
       (copyfiles
	(source old-resolv.conf)
	(dest conf-dir)
	(files))
       (copyfiles
	(source old-startnet)
	(dest bin-dir)
	(files))
       1				; succeeded
       )))
 ;;
 (procedure 
  copy-rest-config
  (copyfiles
   (prompt
    "Select configuration files you want to copy from old configuration")
   (help
    "    You may copy your old configuration files or use untouched files "
    "came with the new distribution.")
   (source old-conf-dir) 
   (dest conf-dir)
   (files)
   (confirm)
   (if (exists (tackon old-conf-dir "networks"))
       (choices				; release 4.0 or later
	"AmiTCP.config"
	"group"
;	"interfaces"
	"hosts"
	"networks"
	"services"
	"protocols"
	"passwd"
	)
     (if (exists (tackon old-conf-dir "inet.access"))
	 (choices			; release 3.0 beta 2 or later
	  "AmiTCP.config"
	  "group"
	  "hosts"
	  "services"
	  "protocols"
	  "passwd"
	  )
       (if (exists (tackon old-conf-dir "interfaces"))
	   (choices			; release 3.0 beta 1 or later
	    "AmiTCP.config"
	    "group"
	    "hosts"
	    "services"
	    "protocols"
	    "passwd"
	    )
	 (if (exists (tackon old-conf-dir "passwd"))
	     (choices			; release 2.2 or later
	      "AmiTCP.config"
	      "group"
	      "hosts"
	      "services"
	      "protocols"
	      "passwd")
	   (choices			; an old release
	    "AmiTCP.config"
	    "hosts"
	    "services"
	    "protocols")))))
   (optional "nofail" "force" "askuser")))
 ;;
 (procedure 
  copy-motd
  (if (exists old-motd)
      ((if (>= @user-level 2)
	   (message "\nCopying file\n\n"
		    old-motd "\n"
		    "(Message Of The Day)\n"
		    "\nto directory \"" conf-dir "\"."))
       (copyfiles
	(source old-motd)
	(dest conf-dir)
	(files)))))
 ;;
 (procedure 
  update-napsaprefs
  (set old-napsaprefs
       (if (exists (tackon old-atcp-directory "db/NapsaPrefs") (noreq))
	   (tackon old-atcp-directory "db/NapsaPrefs")
	 (if (exists "s:NapsaPrefs")
	     "s:NapsaPrefs")
	 ""))
  (if old-napsaprefs
      (;;
       (copyfiles 
	(source old-napsaprefs)
	(dest conf-dir)
	(files)
	(confirm)
	(prompt "\nUse your old Napsaterm preferences?")
	(help  "    Installer have found an existing NapsaPrefs file "
	       old-napsaprefs ". You can copy it to new configuration "
	       "directory.")))))
 (procedure 
  copy-extra-binaries
  "")
 (if (<> (expandpath old-conf-dir) (expandpath conf-dir))
     (
      (transcript "Ready to copy old configuration.")
      (if (askbool
	   (default 0)
	   (prompt
	    "\nDo you want to use settings from an earlier installation?")
	   (help
	    "    Installer have detected existing configuration "
	    "directory \"" old-conf-dir "\" which "
	    "can be used to configure the " app-name ". You can keep most "
	    "of your previous configuration. This is important if you have "
	    "installed extra applications.\n"
	    (if (< old-atcp-version 4)
		(cat "    However, since the configuration practice of the "
		     @app-name " has changed since your old version, you must "
		     "reconfigure the " @app-name " itself. Sorry for the "
		     "incovenience.\n")
	      (cat "    Installer will copy your \"" old-startnet "\" script and "
		   "\"" old-resolv.conf "\" configuration.\n"))
	    "    Other configuration files will be then "
	    (if (> @user-level 1) 
		"optionally")
	    " copied.\n"))
	  ((set no-reconfig (if (>= old-atcp-version 4)
				(copy-myhost-config)))
	   (copy-rest-config)
	   (copy-motd)
	   (update-napsaprefs)
	   (copy-extra-binaries)
	   no-reconfig) ;; FALSE if AmiTCP needs to be reconfigured
	0))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 ;;
 ;; Check if user exists in the user database
 ;;
 ;; takes the user name in ::user-name
 ;;
 does-user-exist
 (if (run (cat "search " (tackon conf-dir "passwd") " \"" ::user-name "|\" NONUM ")
	  (safe))
     0
   1)
 )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure 
 ;;
 ;; Add a new user into AmiTCP:db/passwd
 ;;
 add-new-user
 (if (= anu::setdefaults 0)
     (set   
      anu::passwd (tackon conf-dir "passwd")
      anu::passwd-new (cat anu::passwd ".new")
      anu::passwd-old (cat anu::passwd ".old")
      anu::tempfile "t:run-the-password"
      anu::helptext (cat "    You must give an login name, user ID, group ID"
			 "real name and home directory for each user.\n")
      anu::setdefaults 1
      anu::username (cat default-user-name)
      anu::UID 200
      anu::GID 100
      anu::realname ""
      anu::homedir "AmiTCP:home"
      anu::shell "shell"))
 (while
     ((set anu::username
	   (askstring
	    (default anu::username)
	    (prompt "Enter the login name of the new user:\n")
	    (help anu::helptext
		  "    The login name consists of lowercase letters a-z "
		  "and numbers.  Its recommended maximum length is 8 "
		  "characters.\n"
		  "    Examples of acceptable login names are `ppessi' "
		  "and `an345'.")))
      (set ::user-name anu::username)
      (if (does-user-exist)
	  ((message "User " anu::username " already exists.")
	   1))))
 (set anu::UID
      (asknumber
       (default anu::UID)
       (prompt (cat "Enter the user ID of the user " anu::username ":\n"))
       (help anu::helptext
	     "    The user ID is a numeric unique identifier for each "
	     "user. "
	     "It is a number between 100 - 32767 for ordinary users.\n")))
 (set anu::GID
      (asknumber
       (default anu::GID)
       (prompt (cat "Enter the primary group ID of the user " 
		    anu::username ":\n"))
       (help anu::helptext
	     "    The group ID is a numeric identifier of groups. "
	     "Each user has a primary group, which is usually 100, "
	     "group \"users\".\n")))
 (set anu::realname
      (askstring
       (default anu::realname)
       (prompt (cat "Enter the real name of the user " anu::username ":\n"))
       (help anu::helptext
	     "    The real name can contain any characters except "
	     "comma (`,'), colon (`:') or bar (`|').")))
 (set anu::homedir
      (askdir
       (default anu::homedir)
       (prompt (cat "Give the home directory of the user " anu::username ":\n"))
       (help anu::helptext
	     "    When user logs in, the current directory is changed to"
	     "her home directory.  Also, the finger information (.plan"
	     "and .project) is retrieved from home directory.")
       (newpath)))
 (if (not use-default-provider)
     (set anu::shell
	  (askstring
	   (default anu::shell)
	   (prompt (cat "Enter the name of command interpreter for the user "
			anu::username ":\n"))
	   (help anu::helptext
		 "    The command interpreter value can be either "
		 "`shell' or `cli'."))))
 (set anu::passwd-entry 
      (cat anu::username "||" anu::UID "|" anu::GID "|" 
	   anu::realname "|" anu::homedir "|" anu::shell "\n"))
 (if (askbool 
      (prompt (cat "Are you sure you want to add following user:\n\n"
		   "Login name: " anu::username "\n"
		   "User ID: " anu::UID "\n"
		   "Group ID: " anu::GID "\n"
		   "Real name: " anu::realname "\n"
		   "Home directory: " anu::homedir "\n"
		   "Shell: " anu::shell "\n"))
      (choices (cat "Add " anu::username) (cat "Skip " anu::username))
      (help "You can still skip creating the new user."))
     ((textfile (dest anu::passwd-new)
		(include anu::passwd)
		(append anu::passwd-entry))
      (copyfiles (source anu::passwd)
		 (dest conf-dir)
		 (newname "passwd.old")
		 (optional "askuser"))
      (copyfiles (source anu::passwd-new)
		 (dest conf-dir)
		 (newname "passwd")
		 (optional "askuser"))
      (textfile (dest anu::tempfile)
		(append (cat 
			 "failat 5000\n"
			 (tackon bin-dir "login") " " anu::username "\n"
			 (tackon bin-dir "passwd") " " anu::username "\n"
			 "endshell\n"))
		(safe))
      (run (cat "newshell from " anu::tempfile))
      (set anu::username ""
	   anu::UID (+ anu::UID 1)
	   anu::realname "")
      1))
 )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 ;;
 ;; Add a new users into AmiTCP:db/passwd
 ;;
 add-new-users
 (while
     (askbool (prompt "\nDo you want to create a new user account?\n"
		      "\nYou will be logged in with the new account "
		      "immediately to set the password.")
	      (choices "Proceed" "Cancel")
	      (help "    You are about to add a new users into user database. "
		    "Remember that the user id of each user must be unique! "
		    "You will be logged in with the new user account to "
		    "set the password for the new user.\n"))
   (add-new-user))
 )
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure 
 ;;
 ;; Ask for the default user
 ;;
 ask-default-user
 (while
     ((set default-user-name
	   (askstring
	    (default default-user-name)
	    (prompt "Enter the default user name\n")
	    (help "    The AmiTCP/IP can handle currently only one user "
		  "at a time.  The default user is selected with `login' "
		  "command by system startup script. ")))
      (set ::user-name default-user-name)
      (if (= defaulf-user-name "")
	  1
	(if (NOT (does-user-exist))
	    (NOT (add-new-user))))))
 )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure
 ;;
 ;; Install passwd and group databases
 ;;
 install-user-databases
 (transcript "Installing user databases")
 (procedure get-mufs-version
	    (set mufs-vernum (getversion "multiuser.library" (resident)))
	    (set mufs-ver (/ mufs-vernum 65536))
	    (set mufs-rev (- mufs-vernum (* ver 65536))))
 (procedure passwd-create
	    (copyfiles
	     (prompt "Copying " passwd-source " to AmiTCP:db/passwd.")
	     (source passwd-source)
	     (dest conf-dir)
	     (newname "passwd")
	     (optional "nofail")))
 (procedure group-create
	    (copyfiles
	     (prompt "Copying " group-source " to AmiTCP:db/group.")
	     (source group-source)
	     (dest conf-dir)
	     (newname "group")
	     (optional "nofail")))
 (set passwd-source
      (tackon source-dir "db/passwd-example"))
 (set group-source (tackon source-dir "db/group-example"))
 (if (>= @user-level 2)
     (message 
      "\n"
      "Copying user database from file"
      "\n\n\"" passwd-source "\"\n\n"
      "and group database from file"
      "\n\n\"" group-source "\"\n\n"))
 (passwd-create)
 (group-create)
 )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; (Re-)configure AmiTCP/IP
;;;
(procedure
 config-amitcp
 (transcript "Reconfiguring " @app-name ".")
 (complete 45) (ask-default-user)
 (if (not use-default-provider)
     (
      (complete 50) (ask-if-dynamic)
      (complete 52) (ask-hostname)
      (complete 60) (ask-interfaces)
      ))

 (complete 75)
 ;;
 ;; Ask interface configuration. First the 'if-config-file'
 ;; is cleared. Following calls change it if necessary. Later
 ;; the config file is created if this variable is non-nil
 ;;
 (set if-config-file "")
 (if (= my-host-if-type 1)
     (ask-slip-config))
 
 (if (not use-default-provider)
     (
;;      (complete 75) (ask-gateway)	;; Not needed by this version
      (complete 80) (ask-nameservers)
      (complete 85) (ask-domains)
      ))
 (complete 90) (update-user-startup)
 (complete 95) (create-startup-script)
 (complete 96) (create-config-file)
 )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Installatation sequence
;;;
(message "Please remember during this installation:\n\n"
	 "    Read the instructions provided behind the \"Help\" "
	 "buttons, if you are not absolutely sure what you are doing.\n"
	 "    Please read the file \"README.FIRST\". It contains "
	 "valuable info you cannot afford to miss. (This file is "
	 "shown automatically at the end of the first time installation.)"
	 )

(complete 00) (transcript "On making " app-name ".")
(complete 01) (check-user-level)
(complete 02) (check-system-version)
(complete 03) (check-available-memory)
(complete 04) (check-old-assign)

(set use-default-provider
     (askbool (prompt "Do you want to use predefined settings for the "
		      default-provider "?")
	      (help "If you select \"Yes\", then the predefined "
		    "configuration values for " default-provider
		    " will be used, and NOT asked.")))

(complete 05) (select-destination-directory)

(if (exists (tackon conf-dir "resolv.conf"))
    ( ;; Already configured, ask user what s/he wants to do
     (transcript @app-name " already configured, presenting options")
     (while
	 ((complete 10)
	  (set choice
	       (askchoice
		(prompt "The " app-name " seems to be already installed. "
			"Select one of following:")
		(help "    Installer has detected that the file "
		      "\"AmiTCP:db/resolv.conf\" exists already. Normally "
		      "this means that the installation has been "
		      "successfully completed.\n"
		      "    You can now select what part of the full "
		      "installation you want to repeat. This selection will "
		      "be repeatedly presented, until \"Done\" is choosed.")
		(choices "Update Sana-II drivers"		; 0
			 "Add new users"                        ; 1
			 "Reconfigure AmiTCP/IP"		; 2
			 "Done")				; 3
		(default 3)))
	  (<> choice 3))
       (select choice
	       ;; (0)
	       (update-devices)
	       ;; (1)
	       (add-new-users)
	       ;; (2)
	       (config-amitcp)
	       )
       )
     )
  ( 
   (complete 08) (ask-accept-license)	     ; ask if user accepts the license
   (complete 10) (copy-files-to-destination) ; copy AmiTCP/IP files
   (complete 20) (ask-update-devices)	     ; update Sana-II drivers
   (if (if (if old-atcp-directory
	       (exists (tackon old-atcp-directory "db/AmiTCP.config") 
			(noreq)))
	   ((complete 40)
	    (ask-copy-old-configuration)))
       ((if (exists (tackon conf-dir "passwd"))
	    (transcript "There is already a user database.")
	  ((complete 70)
	   (install-user-databases))) ; install passwd/group
	(complete 90) (update-user-startup)
	)
     (;; First time installation (or old version is < 4), do it all
      (if (exists (tackon conf-dir "passwd"))
	  (transcript "There is already a user database.")
	((complete 40)
	 (install-user-databases))) ; install passwd/group

      ;; Configure AmiTCP/IP
      (config-amitcp)))	; This must be the last one!
   ;; show something
   (run (cat "run " pager-cmd) (tackon atcp-assign "HowToOrder") (safe))
   (run (cat "run " pager-cmd) (tackon atcp-assign "README.FIRST") (safe))
   )
  )
;;; All done!
(complete 100)
(exit "You should reboot your Amiga to make sure that everything is set "
      "up properly for the " @app-name ". After the reboot, "
      (if started-at-boot
	  (cat "the " @app-name " should be running. If this is not a case, "))
      "type \"startnet"
      (if is-if-dynamic " <current-IP-address>")
      "\" in a command shell to start the "
      @app-name ".")

; EOF
