/* REXX */ /* vtexinst.cmd, version 2 Copyright (C) 2001--2005 Walter Schmidt, Erlangen VTeX/2 installation program to be run from a local directory, which must contain all required files */ /* Load REXXUTIL */ ret = RxFuncAdd("SysLoadFuncs", "REXXUTIL", "SysLoadFuncs") call SysLoadFuncs /* Load text strings for SysFileDel and SysRmDir return codes. */ CALL LoadDELRCText /* provides text strings for SysFileDel return codes */ CALL LoadRDRCText /* provides text strings for SysRmDir return codes */ /* Initialization -------------- */ /* This distribution */ SCRIPTVERSION = 8.442 /* version of the installation program */ EMTEX=0.56 /* matching version of emTeX/TDS */ INTRO = 'Installation program for VTeX/2 ' || SCRIPTVERSION || ' and later' OBSOLETE = 'vtex/install/obsolete.os2' /* list of obsolete files */ OLDVERSION = 8.440 /* FM and INI files of this version can be used still. */ /* Also, the EC fonts are not reinstalled, when this verson is present, */ /* and "full reinstall" is not selected. */ /* The files in the distribution: */ /* number of version-dependent files*/ varfile.0 = 6 /* number of version-independent files */ fixedfile.0 = 1 /* number of optional files (which must be version-independent, too) */ optfile.0 = 4 varfile.1 = "vtex2" varfile.2 = "vtex-doc" varfile.3 = "vtex-special" varfile.4 = "vtex-fonts" varfile.5 = "vtex-base" varfile.6 = "vtex-base2" fixedfile.1 = "vtex-fonts2.zip" optfile.1 = "vtex-gex.zip" optfile.2 = "vtex-sem.zip" optfile.3 = "vtex-koma.zip" optfile.4 = "vtex-cbfonts.zip" /* the name of the file, where the version info will be stored */ VERSIONFILE = "\vtex\install\VERSION" /* query boot volume */ bootdrv = querybootdrv() if bootdrv = '' then signal nobootdrv /* query working directory */ wrkdir = strip(directory(), "T", "\") /* start writing the log file */ logfile = wrkdir || "\vtexinst.log" rc = sysfiledelete(logfile) if rc > 2 then signal logfileerr call wlog 'vtexinst ' || SCRIPTVERSION call wlog date() time() call wlog 'OS/2:' SysOS2Ver() call wlog 'Shell:' value("OS2_SHELL", , "OS2ENVIRONMENT") call wlog 'Boot drive =' bootdrv call wlog 'Working directory = "' || wrkdir || '"' call wlog 'PATH = "' || VALUE("PATH", , "OS2ENVIRONMENT") || '"' call wlog 'Unzip program = "' || SysSearchPath("PATH", "unzip.exe") || '"' /* Ask for the drive where to install or update VTeX */ say say INTRO say say "Which version of VTeX/2 do you want to install?" answer = linein() call wlog 'Requested version: ' || '"' || answer || '"' parse value answer with major '.' minor '.' subver if (major='' or minor='') then signal versionerr versionid = major|| minor || subver newver = major || '.' || minor || subver if newver < SCRIPTVERSION then signal tooold else call wlog 'New version ID:' newver say "On which volume (drive) do you want VTeX/2 to be installed or updated?" say "(hit only to select the boot volume)" answer = linein() texdrive = translate(substr(answer,1,1)) || ":" if texdrive = ":" then texdrive = bootdrv call wlog 'VTeX volume = "' ||texdrive|| '"' /* determine version of existing VTeX */ ver = SysIni(texdrive || VERSIONFILE, "VTEX2", "VERSION") if ver = "ERROR:" then do if stream(texdrive||"\texmf\vtex\config\psfig.sty", "C", "QUERY EXISTS") <> "" then ver = 7.32 else ver = 0 end say if ver > 7.32 then say "VTeX version " || ver || " detected on volume " || texdrive call wlog 'Current version ID =' ver if ver > newver then signal toonew /* force full re-install ? */ if ver >= OLDVERSION then do say say "By default, your VTeX/2 system will be updated only." say "However, you may also force a full reinstall, e.g.," say "in case the current installation is corrupt." say say "Do you request a full reinstall? (y/n)" answer = translate(substr(linein(),1,1)) if answer = "Y" then do ver = 0 call wlog 'Full install requested' end end /* search for emTeX/TDS on the same drive */ emtexver = SysIni(texdrive"\texmf\emtex\data\EMTEXTDS.INI", "EMTEXTDS", "VERSION") if emtexver <> "ERROR:" then do say say "emTeX/TDS version" emtexver "detected." call wlog 'Current emTeX =' emtexver if emtexver < EMTEX then signal oldemtex end /* determine the actual names of the required ZIP files */ /* and make sure they exist */ res = 1 if ver < newver then do do i = 1 to varfile.0 varfile.i = varfile.i || '-' || versionid || '.zip' call wlog 'Required: ' varfile.i if (stream(varfile.i, "C", "QUERY EXISTS") = "") then do res = 0 call wlog 'missing file:' varfile.i say "missing file:" varfile.i end end end if ver < OLDVERSION then do do i = 1 to fixedfile.0 call wlog 'Required: ' fixedfile.i if (stream(fixedfile.i, "C", "QUERY EXISTS") = "") then do res = 0 call wlog 'missing file:' fixedfile.i say "missing file:" fixedfile.i end end end if res <> 1 then signal fileerr /* Last exit */ say say "VTeX/2 on volume " || texdrive || " will be installed/updated." say "Continue? (y/n)" answer = translate(substr(linein(),1,1)) if answer <> "Y" then signal cancel /* Go to the target drive ---------------------- */ call setlocal call directory(texdrive||"\") call wlog 'current directory changed to' directory() call wlog ' ' /* Unpack the ZIP archives ----------------------- */ vtex: SIGNAL on error name unziperr /* overwrite existing files by default */ ret=value("UNZIP", "-qqo", "OS2ENVIRONMENT") /* unzip the required files: */ if ver < newver then do /* back up existing configuration files first */ call saveconfig("\vtex\bin\vtex.ini") call saveconfig("\texmf\vtex\config\hyphen.cfg") call saveconfig("\texmf\vtex\config\plain.cfg") call saveconfig("\texmf\vtex\config\pdf.fm") call saveconfig("\texmf\vtex\config\ps.fm") do i = 1 to varfile.0 varfile.i = wrkdir || "\" || varfile.i call wlog "unzip " || varfile.i "unzip " || varfile.i end say "New configuration files \texmf\vtex\config\hyphen.cfg and .\plain.cfg installed." call wlog "New configuration files \texmf\vtex\config\hyphen.cfg and .\plain.cfg installed." end if ver < OLDVERSION then do do i = 1 to fixedfile.0 fixedfile.i = wrkdir || "\" || fixedfile.i call wlog "unzip " || fixedfile.i "unzip " || fixedfile.i end end /* unzip optional files, if present */ do i = 1 to optfile.0 optfile.i = wrkdir || "\" || optfile.i if stream(optfile.i, "C", "QUERY EXISTS") <> "" then do call wlog "unzip " || optfile.i "unzip " || optfile.i end end SIGNAL on error /* Removing obsolete files created by previous versions ---------------------------------------------------- */ if ver < newver then do say "Removing possibly obsolete files..." do while lines(OBSOLETE) > 0 l = strip(linein(OBSOLETE)) if l \= '' then do if substr(l, length(l), 1) = "\" then do l = substr(l, 1, (length(l)-1)) call wlog "Trying to delete directory" l call ddt(l) end else do call wlog "Trying to delete file" l call SysFileDelete(l) end end end say " ...done." end /* Writing the version number -------------------------- */ writever: ret = SysIni(texdrive || VERSIONFILE, "VTEX2", "VERSION", newver) say if ret = "" then do call wlog "version number" newver "written" say "Version number" newver "written." end else do call wlog "Writing version number failed with rc =" ret say "Writing the version number failed." end cfgfiles: call wlog ' ' say /* Restore FM and INI files or configure the new ones -------------------------------------------------- */ if ver < OLDVERSION then do /* FM files: */ call readconfig "\texmf\vtex\config\pdf.fm" call fmedit texdrive config.1 = '% pdf.fm, for PDF mode, created by vtexinst ' date() time() call writeconfig "\texmf\vtex\config\pdf.fm" /* we just hope that writing of the file was successful... */ call readconfig "\texmf\vtex\config\ps.fm" call fmedit texdrive config.1 = '% ps.fm, for PS mode, created by vtexinst ' date() time() call writeconfig "\texmf\vtex\config\ps.fm" /* we just hope that writing of the file was successful... */ say "New configuration files \texmf\vtex\config\pdf.fm and .\ps.fm installed." call wlog "New configuration files \texmf\vtex\config\pdf.fm and .\ps.fm installed." /* configure INI file: */ if texdrive <> "c:" then do call readconfig "\vtex\bin\vtex.ini" call iniedit texdrive call writeconfig "\vtex\bin\vtex.ini" /* we just hope that writing of the file was successful... */ end say "New configuration file \vtex\bin\vtex.ini installed." call wlog "New configuration file \vtex\bin\vtex.ini installed." end else do /* restore FM and INI files: */ call restconfig("\texmf\vtex\config\pdf.fm") call restconfig("\texmf\vtex\config\ps.fm") call restconfig("\vtex\bin\vtex.ini") end say "@pause" /* Updating config.sys ------------------- */ /* Skip this step, if PATH includes vtex already */ /* In this case we assume that LIBPATH is ok, too. */ p = value("PATH", , "OS2ENVIRONMENT") if substr(p, length(p), 1) <> ";" then p = p || ";" call wlog ' ' call wlog 'PATH = "' || p || '"' if pos(texdrive||"\VTEX\BIN;", translate(p)) <> 0 then signal done say say "The installation program is going to update the file config.sys now." say "If you prefer to do this manually, then enter `n' below," say "otherwise enter `y' to continue." say "Continue? (y/n)" answer = translate(substr(linein(),1,1)) if answer <> "Y" then signal done call wlog 'updating config.sys' /* make sure that config.sys can be found */ configfile = bootdrv||"\config.sys" if stream(configfile,"C","QUERY EXISTS") = "" then signal noconfig call readconfig configfile if pathedit("PATH", texdrive||"\vtex\bin;") = 0 then signal updfailed if libpathedit(texdrive||"\vtex\dll;") = 0 then signal updfailed tempfile=SysTempFileName(bootdrv||"\config??.sys") if tempfile="" then signal updfailed signal on error name updfailed savedfile = filespec("N", tempfile) "@ren" configfile savedfile say say "The file" configfile "has been renamed to" savedfile "." call wlog configfile ' renamed to ' savedfile res = writeconfig(configfile) if res=0 then do call beep 440,250 say "Writing a new file" configfile "failed". say "Rename" savedfile "to config.sys and apply the changes manually." call wlog 'Writing new' configfile 'failed.' end else do say say "A new file" configfile "has been written." say "Shutdown and reboot OS/2 now to make the changes come into effect." call wlog 'New config.sys created.' end /* exiting */ done: call wlog 'Finis.' say say "Finis." say "Do not forget to generate (new) format files now!" exit /* Error handling: */ logfileerr: say say "Error: I cannot write to the file" logfile "." exit versionerr: say say "The installation program cannot proceed," say "because you have specified an invalid version number," exit toonew: say say "The version of VTeX/2 found on your PC is already newer" say "than the version you have requested to install." call wlog 'Existing VTeX/2 is newer than the version to be installed.' exit tooold: say say "This version of the installation program is not suitable" say "for VTeX/2 prior to version" SCRIPTVERSION say exit oldemtex: call wlog 'Obsolete emTeX found.' say say "You cannot install VTeX/2" newver "over emTeX prior to" EMTEX exit nobootdrv: call wlog 'Could not locate boot volume.' say say "The installation program cannot proceed," say " because the boot partition cannot be located." say "VTeX/2 could not be installed." exit noconfig: call wlog 'Could not locate config.sys.' say say "The installation program could not locate the file config.sys" say "and was unable to determine whether it needs to be updated." say "Please, see the installation instructions for the required changes" say "and how to apply them manually." exit updfailed: call wlog 'Updating config.sys failed.' say say "Updating config.sys failed for unknown reason." say "The file config.sys has *** not *** been changed." say "Please, read the installation instructions" say "and apply any changes manually." exit error: call wlog 'Error: "'condition('D')'"' 'failed.' call beep 440,250 say say 'Error: "'condition('D')'"' 'failed.' say 'VTeX/2 could not be installed successfully.' exit fileerr: call wlog 'Required file(s) not found.' call beep 440,250 say say "One or more of the files required to" say "install or update VTeX/2" newver "were not found." say "VTeX/2 could not be installed." exit unziperr: call wlog '"unzip" failed.' call beep 440,250 say say 'The program "unzip" failed or was not found.' say 'VTeX/2 could not be installed.' exit cancel: call wlog 'Terminated by the user.' say "You have terminated the installation program." exit /* Procedures used above: */ /* query boot drive usage: querybootdrv() returns: letter of boot drive incl. colon */ querybootdrv: PROCEDURE bootdr = value('COMSPEC', , 'OS2ENVIRONMENT') bootdr = filespec('D', bootdr) if bootdr = "" then do say "Please, tell me the letter of the boot volume:" answer = linein() bootdr = substr(strip(answer),1,1)||":" end return bootdr /* save file by appending .sav to the name usage: call saveconfig file returns: 1 if succesful */ saveconfig: PROCEDURE expose logfile parse arg file start = lastpos("\", file) + 1 if start > 1 then do len = length(file) - start + 1 stem = substr(file, start, len) end else stem = file if (stream(file, "C", "QUERY EXISTS") <> '') then do "@copy" file file||".sav" call wlog "Configuration file" file "saved as" stem||".sav ." return 1 end else return 0 /* restore saved file usage: call restconfig file returns: 1 if successful */ restconfig: PROCEDURE expose logfile parse arg file if (stream(file||".sav", "C", "QUERY EXISTS") <> '') then do "@copy" file||".sav" file call wlog "Configuration file" file "restored." return 1 end else return 0 /* read config file usage: call readconfig filename returns: (nothing) */ readconfig: PROCEDURE expose config. cmax parse arg infile cmax=0 do while lines(infile) > 0 cmax=cmax+1 config.cmax=linein(infile) end /* do */ call stream infile, "C", "CLOSE" return /* write config file usage: call writeconfig filename returns: 1 if successful 0 if writing the file failed */ writeconfig: PROCEDURE expose config. cmax parse arg outfile call SysFileDelete outfile do i = 1 TO cmax if config.i <> "deleted" then do res = lineout(outfile, config.i) end end /* do */ call stream outfile, "C", "CLOSE" if res <> 0 then return 0 else return 1 /* edit a path usage: pathedit(path, entry, op) op = "D" means "delete this entry" op = "A" (default) means "add entry" returns 1 if successful 0 if path or entry to be deleted not found 2 if entry to be added was already present */ pathedit: PROCEDURE expose config. cmax parse arg rpath, rdirectory, rop op = translate(rop) path = strip(translate(rpath)) trigger = " "||path||"=" directory = translate(rdirectory) i=0 do forever i=i+1 if i>cmax then leave posi = pos(trigger, translate(config.i)) if posi > 1 then do cmd = subword(translate(config.i), 1, 1) if cmd = "SET" then leave end end /* do */ if i>cmax then return 0 setting = substr(config.i, (posi+length(trigger))) setting = strip(setting) if substr(directory,length(directory),1) <> ";" then directory = directory || ";" if substr(setting,length(setting),1) <> ";" then setting = setting || ";" if op="D" then do posi = pos(directory,translate(setting)) if posi<>0 then config.i= "SET " || path || "=" || delstr(setting, posi, length(directory)) else return 0 end /* do */ else do if pos(directory,translate(setting))<>0 then return 2 else do setting=setting || rdirectory config.i = "SET " || path || "=" || setting end /* do */ end /* do */ return 1 /* edit LIBPATH usage: libpathedit(entry, op) op = "D" means "delete this entry, if existing" op = "A" (default) means "add entry" returns: 1 if successful 0 if LIBPATH or entry to be deleted not found 2 if entry to be added was already present */ libpathedit: PROCEDURE expose config. cmax parse arg rdirectory, rop directory = translate(rdirectory) op = translate(rop) i=0 do forever i=i+1 if i>cmax then leave posi = pos("LIBPATH=", translate(config.i)) if posi = 1 then leave end /* do */ if i>cmax then return 0 setting = substr(config.i, 9) setting=strip(setting) if substr(directory,length(directory),1) <> ";" then directory = directory || ";" if substr(setting,length(setting),1) <> ";" then setting = setting || ";" if op="D" then do posi = pos(directory,translate(setting)) if posi<>0 then config.i= "LIBPATH=" || delstr(setting, posi, length(directory)) else return 0 end /* do */ else do if pos(directory,translate(setting))<>0 then return 2 else do setting=setting || rdirectory config.i = "LIBPATH=" || setting end /* do */ end /* do */ return 1 /* edit vtex,ini usage: call iniedit drive drive = drive letter of VTeX drive including colon returns: 1 if successful 0 otherwise */ iniedit: PROCEDURE expose config. cmax parse arg drive drive = drive || "\" default = "c:\" i =0 do forever i=i+1 if i>cmax then leave start = 1 do forever j = pos(default, config.i, start) if j=0 then leave config.i = overlay(drive, config.i, j) start = j+2 end end /* do */ return 1 /* edit FM file usage: call fmedit drive drive = drive letter of VTeX drive including colon returns: 1 if successful 0 otherwise */ fmedit: PROCEDURE expose config. cmax parse arg drive i = 0 ctrl =2 do forever i = i+1 if i>cmax then leave if pos('TEXMF = "c:/texmf/"', config.i) <> 0 then do config.i = ' TEXMF = "'||drive||'/texmf/"' ctrl = ctrl - 1 end end /* exactly 2 matches must be found */ if ctrl = 0 then return 1 else return 0 /* write message to log file */ wlog: PROCEDURE expose logfile parse arg string rc = lineout(logfile, string) return rc /* Procedures for deleting a directory tree */ DDT: parse arg user_dir /* Check to make sure the directory exists */ rc=SysFileTree(user_dir,dir_list, 'D') IF dir_list.0 = 0 THEN DO SAY user_dir 'not found.' RETURN END DROP dir_list. /* Mark all the read-only files to be non read-only */ rc=SysFileTree(user_dir || '\*.*', dir_list, 'FSO', '****','----') DROP dir_list. /* Go through the list of files and delete each one */ rc=SysFileTree(user_dir || '\*.*', dir_list, 'FSO') DO x = 1 TO dir_list.0 rc = SysFileDelete(dir_list.x) if rc <> 0 then SAY dir_list.x '........' DELRCText.RC END DROP dir_list. /* Go through all the subdirectories and remove them. */ /* We go backwards through the list in order to delete the */ /* lowest level sudirectories first and work our way back up */ /* the tree. */ rc=SysFileTree(user_dir || '\*.*', dir_list, 'DSO') DO x = dir_list.0 TO 1 BY -1 rc=SysRmDir(dir_list.x) if RC <> 0 then SAY dir_list.x '........' RDRCText.RC END DROP dir_list. /* Delete the topmost directory */ rc=SysRmDir(user_dir) SAY user_dir '........' RDRCText.RC RETURN LoadDELRCText: /* provides text strings for SysFileDel return codes */ /* The return codes and strings are in the online Rexx manual */ DELRCText.0 = 'File deleted successfully. ' DELRCText.2 = 'Error. File not found. ' DELRCText.3 = 'Error. Path not found. ' DELRCText.5 = 'Error. Access denied. ' DELRCText.26 = 'Error. Not DOS disk. ' DELRCText.32 = 'Error. Sharing violation. ' DELRCText.36 = 'Error. Sharing buffer exceeded. ' DELRCText.87 = 'Error. Invalid parameter. ' DELRCText.206 = 'Error. Filename exceeds range error. ' RETURN LoadRDRCText: /* provides text strings for SysRmDir return codes */ /* The return codes and strings are in the online Rexx manual */ RDRCText.0 = 'Directory removal was successful. ' RDRCText.2 = 'Error. File not found. ' RDRCText.3 = 'Error. Path not found. ' RDRCText.5 = 'Error. Access denied. ' RDRCText.16 = 'Error. Current Directory. ' RDRCText.26 = 'Error. Not DOS disk. ' RDRCText.87 = 'Error. Invalid parameter. ' RDRCText.108 = 'Error. Drive locked. ' RDRCText.206 = 'Error. Filename exceeds range error. ' RETURN /* finis */