1$ ! vms/install.com -- set up nethack 'playground'
2$! $NHDT-Date: 1573172443 2019/11/08 00:20:43 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.12 $
3$! Copyright (c) 2016 by Robert Patrick Rankin
4$! NetHack may be freely redistributed.  See license for details.
5$ !
6$ ! $NHDT-Date: 1573172452 2019/11/08 00:20:52 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.12 $
7$ !
8$ ! Use vmsbuild.com to create nethack.exe, makedefs, and lev_comp *first*.
9$ !
10$ ! Note: this command procedure is also used by the top level Makefile
11$ ! if you build and install with MMS or MMK.  In that situation, only the
12$ ! Makefile will need any editing.
13$ !
14$ ! Edit this file to define gamedir & gameuic, or else invoke it with two
15$ ! command line parameters, as in:
16$ !	@[.sys.vms]install "disk$users:[games.nethack]" "games"
17$ ! or	@[.sys.vms]install "[-.play]" "[40,1]"
18$ !
19$	! default location is old playground, default owner is installer
20$	gamedir = f$trnlnm("NETHACKDIR")	!location of playground
21$	if gamedir.eqs."" then  gamedir = f$trnlnm("HACKDIR")
22$	gameuic = f$user()			!owner of playground
23$	! --- nothing below this line should need to be changed ---
24$	if p1.nes."" then  gamedir := 'p1'
25$	if p2.nes."" then  gameuic := 'p2'
26$
27$	! note: all filespecs contain some punctuation,
28$	!	to avoid inadvertent logical name interaction
29$	play_files = "PERM.,RECORD.,LOGFILE.,XLOGFILE.,PANICLOG."
30$	help_files = "HELP.,HH.,CMDHELP.,KEYHELP.,WIZHELP.,OPTHELP.," -
31		   + "HISTORY.,LICENSE."
32$	data_files = "DATA.,RUMORS.,ORACLES.,OPTIONS.,QUEST.DAT,TRIBUTE.," -
33		   + "ENGRAVE.,EPITAPH.,BOGUSMON."
34$	sysconf_file = "[.sys.vms]sysconf"
35$	guidebook  = "[.doc]Guidebook.txt"
36$	invoc_proc = "[.sys.vms]nethack.com"
37$	trmcp_file = "[.sys.share]termcap"
38$	spec_files = "AIR.LEV,ASMODEUS.LEV,ASTRAL.LEV,BAALZ.LEV,BIGRM-*.LEV," -
39		   + "CASTLE.LEV,EARTH.LEV,FAKEWIZ%.LEV,FIRE.LEV," -
40		   + "JUIBLEX.LEV,KNOX.LEV,MEDUSA-%.LEV,MINEFILL.LEV," -
41		   + "MINETN-%.LEV,MINEND-%.LEV,ORACLE.LEV,ORCUS.LEV," -
42		   + "SANCTUM.LEV,SOKO%-%.LEV,TOWER%.LEV,VALLEY.LEV," -
43		   + "WATER.LEV,WIZARD%.LEV"
44$	spec_input = "bigroom.des castle.des endgame.des " -
45		   + "gehennom.des knox.des medusa.des mines.des " -
46		   + "oracle.des sokoban.des tower.des yendor.des"
47$	qstl_files = "%%%-GOAL.LEV,%%%-FIL%.LEV,%%%-LOCA.LEV,%%%-STRT.LEV"
48$	qstl_input = "Arch.des Barb.des Caveman.des Healer.des " -
49		   + "Knight.des Monk.des Priest.des Ranger.des Rogue.des " -
50		   + "Samurai.des Tourist.des Wizard.des Valkyrie.des"
51$	dngn_files = "DUNGEON."
52$	dngn_input = "dungeon.pdf"
53$	dlb_files  = help_files + "," + data_files + "," -
54		   + spec_files + "," + qstl_files + "," + dngn_files
55$	data_libry = "nh-data.dlb"
56$	xtrn_files = "LICENSE.,HISTORY.,OPTIONS.,SYMBOLS."
57$ makedefs := $sys$disk:[-.util]makedefs
58$ lev_comp := $sys$disk:[-.util]lev_comp
59$ dgn_comp := $sys$disk:[-.util]dgn_comp
60$ dlb	   := $sys$disk:[-.util]dlb
61$ milestone = "write sys$output f$fao("" !5%T "",0),"
62$ if p3.nes."" .and. f$edit(p4,"UPCASE").nes."VERBOSE" then  milestone = "!"
63$ echo = "write sys$output"
64$ warn = echo	!could be "write sys$error"
65$!
66$! make sure we've got a playground location
67$ gamedir := 'gamedir'
68$ if gamedir.eqs."" then  gamedir = "[.play]"	!last ditch default
69$ gamedir = f$parse(gamedir,,,,"SYNTAX_ONLY") - ".;"
70$ if gamedir.eqs."" then  write sys$error "% must specify playground directory"
71$ if gamedir.eqs."" then  exit %x1000002C	!ss$_abort
72$
73$!
74$!	['p3' is used in Makefile.top]
75$ if p3.nes."" then  goto make_'p3'
76$
77$	milestone "<installation...>"
78$!
79$make_data_plus_dlb:
80$make_data:
81$	! start from a known location -- [.sys.vms]
82$	set default 'f$parse(f$environment("PROCEDURE"),,,"DIRECTORY")'
83$! generate miscellaneous data files
84$	set default [-.-.dat]	!move to data directory
85$	milestone "(data)"
86$ makedefs -d	!data.base -> data
87$	milestone "(rumors)"
88$ makedefs -r	!rumors.tru + rumors.fal -> rumors
89$	milestone "(oracles)"
90$ makedefs -h	!oracles.txt -> oracles
91$	milestone "(dungeon preprocess)"
92$ makedefs -s
93$	milestone "(engrave, epitaph, bogusmon)"
94$ makedefs -e	!dungeon.def -> dungeon.pdf
95$	milestone "(quest text)"
96$ makedefs -q	!quest.txt -> quest.dat
97$	milestone "(special levels)"
98$ lev_comp 'spec_input' !special levels
99$	milestone "(quest levels)"
100$ lev_comp 'qstl_input' !quest levels
101$	milestone "(dungeon compile)"
102$ dgn_comp 'dngn_input' !dungeon database
103$	set default [-]		!move up
104$ if p3.nes."" .and. f$edit(p3,"UPCASE").nes."DATA_PLUS_DLB" then  exit
105$
106$make_dlb:
107$	! start from a known location -- [.sys.vms]
108$	set default 'f$parse(f$environment("PROCEDURE"),,,"DIRECTORY")'
109$! construct data library
110$	set default [-.-.dat]	!move to data directory
111$	milestone "(dlb setup)"
112$! since DLB doesn't support wildcard expansion and we don't have shell
113$! file globbing, start by making a file listing its intended contents
114$ create nhdat.lst
115$	if f$search("nhdat.lst;-1").nes."" then -
116		purge/noConfirm/noLog nhdat.lst
117$! an old data file might fool us later, so get rid of it
118$	if f$search(data_libry).nes."" then -
119		delete/noConfirm/noLog 'data_libry';*
120$	if f$trnlnm("PFILE$").nes."" then  close/noLog pfile$
121$ open/Append pfile$ nhdat.lst
122$ i = 0
123$dloop:
124$   g = f$element(i,",",dlb_files)
125$   if g.eqs."," then  goto ddone
126$   wild = f$locate("*",g).ne.f$locate("%",g)
127$   fcnt = 0
128$floop:
129$	f = f$search(g)
130$	if f.eqs."" then  goto fdone
131$	fcnt = fcnt + 1
132$! strip device, directory, and version from name
133$	f = f$parse(f,,,"NAME") + f$parse(f,,,"TYPE")
134$! strip trailing dot, if present, and change case
135$	f = f$edit(f + "#" - ".#" - "#","LOWERCASE")
136$	if f$extract(3,1,f).eqs."-" then -	!"xyz-foo.lev" -> "Xyz-foo.lev"
137		f = f$edit(f$extract(0,1,f),"UPCASE") + f$extract(1,255,f)
138$	write pfile$ f
139$	if wild then  goto floop
140$fdone:
141$   if fcnt.eq.0 then  warn "? no file(s) found for """,g,""""
142$   i = i + 1
143$   goto dloop
144$ddone:
145$ close pfile$
146$	milestone "(dlb create)"
147$ dlb "-cfI" 'data_libry' nhdat.lst
148$	set default [-]		!move up
149$ if p3.nes."" then  exit
150$
151$!
152$! set up the playground and save directories
153$	milestone "(directories)"
154$make_directories:
155$	srctree = f$environment("DEFAULT")
156$	set default 'gamedir'
157$ if f$parse("[-]").eqs."" then  create/dir/log [-] !default owner & protection
158$ if f$parse("[]" ).eqs."" then - !needs to be world writable
159   create/directory/owner='gameuic'/prot=(s:rwe,o:rwe,g:rwe,w:rwe)/log []
160$ if f$search("SAVE.DIR;1").eqs."" then -
161   create/directory/owner='gameuic'/prot=(s:rwe,o:rwe,g:rwe,w:rwe)/log -
162	[.SAVE]/version_limit=2
163$	set default 'srctree'
164$ if p3.nes."" then  exit
165$!
166$! create empty writeable files -- logfile, scoreboard, multi-user access lock
167$! [if old versions are already present, validate and retain them if possible]
168$make_writeable_files:
169$	milestone "(writeable files)"
170!-!$ create/owner='gameuic'/prot=(s:rwed,o:rwed,g:rwed,w:rwed) -
171!-!	'gamedir''play_files'
172$	i = 0
173$ploop:	if f$trnlnm("PFILE$").nes."" then  close/nolog pfile$
174$	f = f$element(i,",",play_files)
175$	if f.eqs."," then  goto pdone
176$	i = i + 1
177$	f = gamedir + f
178$	if f$search(f).eqs."" then  goto pmake	!make it if not found
179$	if f$file_attrib(f,"RFM").nes."STMLF" then  goto prej !must be stream_lf
180$	open/read/error=prej pfile$ 'f'
181$	read/end=ploop pfile$ pline	!empty is ok
182$	close pfile$
183$	pfield = f$element(0," ",pline)	!1st field is version number
184$	if f$locate(".",pfield).lt.f$length(pfield) then  goto ploop	!keep
185$prej:	rename/new_vers 'f' *.old	!reject old version
186$pmake:	create/fdl=sys$input:/owner='gameuic' 'f'/log
187file
188 organization sequential
189 protection (system:rwd,owner:rwd,group:rw,world:rw)
190record
191 format stream_lf
192$	goto ploop
193$pdone:
194$ if p3.nes."" then  exit
195$!
196$! copy over the remaining game files, then make them readonly
197$make_readonly_files:
198$	milestone "(readonly files)"
199$ if f$search("[.dat]''data_libry'").nes.""
200$ then	call copyfiles 'f$string(data_libry+","+xtrn_files)' [.dat] "r"
201$ else	!'dlb_files' is too long for a single command
202$	k = 200 + f$locate(",",f$extract(200,999,dlb_files))
203$	call copyfiles 'f$extract(0,k,dlb_files)' [.dat] "r"
204$	call copyfiles 'f$extract(k+1,999,dlb_files)' [.dat] "r"
205$ endif
206$ if p3.nes."" then  exit
207$!
208$make_executable:
209$	milestone "(nethack.exe)"
210$ call copy_file [.src]nethack.exe 'gamedir'nethack.exe "re"
211$ if p3.nes."" then  exit
212$!
213$! provide invocation procedure (if available)
214$make_procedure:
215$ if f$search(invoc_proc).eqs."" then  goto skip_dcl
216$ if f$search("''gamedir'nethack.com").nes."" then -
217    if f$cvtime(f$file_attr("''gamedir'nethack.com","RDT")) -
218      .ges. f$cvtime(f$file_attr(invoc_proc,"RDT")) then  goto skip_dcl
219$	milestone "(nethack.com)"
220$ call copy_file 'invoc_proc' 'gamedir'nethack.com "re"
221$skip_dcl:
222$ if p3.nes."" then  exit
223$!
224$! provide plain-text Guidebook doc file (if available)
225$make_documentation:
226$ if f$search(guidebook).eqs."" then  goto skip_doc
227$	milestone "(Guidebook)"
228$ call copy_file 'guidebook' 'gamedir'Guidebook.doc "r"
229$skip_doc:
230$ if p3.nes."" then  exit
231$!
232$! provide last-resort termcap file (if available)
233$make_termcap:
234$ if f$search(trmcp_file).eqs."" then  goto skip_termcap
235$ if f$search("''gamedir'termcap").nes."" then  goto skip_termcap
236$	milestone "(termcap)"
237$ call copy_file 'trmcp_file' 'gamedir'termcap "r"
238$skip_termcap:
239$ if p3.nes."" then  exit
240$!
241$! provide template sysconf file (needed if nethack is built w/ SYSCF enabled)
242$make_sysconf:
243$ if f$search(sysconf_file).eqs."" then  goto skip_sysconf
244$ if f$search("''gamedir'sysconf_file").nes."" then  goto skip_sysconf
245$       milestone "(sysconf)"
246$ call copy_file 'sysconf_file' 'gamedir'sysconf "r"
247$!	owner should be able to manually edit sysconf; others shouldn't
248$ set file/Prot=(s:rwd,o:rwd,g:r,w:r) 'gamedir'sysconf
249$skip_sysconf:
250$ if p3.nes."" then  exit
251$!
252$! done
253$	milestone "<done>"
254$ define/nolog nethackdir 'gamedir'
255$ define/nolog hackdir 'gamedir'
256$ echo -
257    f$fao("!/ Nethack installation complete. !/ Playground is !AS !/",gamedir)
258$ exit
259$
260$!
261$! copy one file, resetting the protection on an earlier version first
262$copy_file: subroutine
263$ if f$search(p2).nes."" then  set file/Prot=(s:rwed,o:rwed) 'p2'
264$ copy/Prot=(s:'p3'wd,o:'p3'wd,g:'p3',w:'p3') 'p1' 'p2'
265$ set file/Owner='gameuic'/Prot=(s:'p3',o:'p3') 'p2'
266$endsubroutine !copy_file
267$
268$!
269$! copy a comma-separated list of wildcarded files, one file at a time
270$copyfiles: subroutine
271$ i = 0
272$lloop:
273$   g = f$element(i,",",p1)
274$   if g.eqs."," then  goto ldone
275$   g = p2 + g
276$   wild = f$locate("*",g).ne.f$locate("%",g)
277$   fcnt = 0
278$eloop:
279$	f = f$search(g)
280$	if f.eqs."" then  goto edone
281$	fcnt = fcnt + 1
282$	f = f - f$parse(f,,,"VERSION")
283$	e = f$parse(f,,,"NAME") + f$parse(f,,,"TYPE")
284$	call copy_file 'f' 'gamedir''e' "''p3'"
285$	if wild then  goto eloop
286$edone:
287$   if fcnt.eq.0 then  warn "? no file(s) found for """,g,""""
288$   i = i + 1
289$   goto lloop
290$ldone:
291$endsubroutine !copyfiles
292$
293$!<eof>
294