/* REXX */ /* vtexinst.cmd Copyright (C) 2001 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 */ VERSION = 7.530 /* version of this distribution */ EMTEX=0.56 /* matching version of emTeX/TDS */ FMVER = 7.32 /* FM files as of this version may still be used */ HYVER = 7.530 /* hyphen.cfg & plain.cfg as of this version may still be used */ INIVER = 7.460 /* vtex.ini as of this version may still be used */ INTRO = 'Installation program for VTeX/2' VERSION 'as of 2002-01-27' /* The files in the distribution: */ distfile.0 = 8 distver.0 = 8 /* required */ distfile.1 = "vtex2.zip" distfile.2 = "vtex-doc.zip" distfile.3 = "vtex-special.zip" distfile.4 = "vtex-fonts2.zip" distfile.5 = "vtex-fonts.zip" distfile.6 = "vtex-texmf.zip" distver.1 = 7.530 distver.2 = 7.530 distver.3 = 7.530 distver.4 = 7.530 distver.5 = 7.460 distver.6 = 7.460 LASTREQ = 6 /* optional */ distfile.7 = "vtex-gex.zip" distfile.8 = "vtex-sem.zip" distver.7 = 7.320 distver.8 = 7.460 /* Make sure that the following conditions are satisfied: */ /* distver.1 >= INIVER */ /* (distver.3 >= FMVER) & (distver.3 >= HYVER) */ /* the name of the file, where the version info will be stored */ VERSIONFILE = "\vtex\install\VERSION" /* query boot drive */ 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' VERSION date() time() call wlog 'OS/2:' SysOS2Ver() call wlog 'shell:' value("OS2_SHELL", , "OS2ENVIRONMENT") call wlog 'boot drive = "' || bootdrv || '"' call wlog 'working directory = "' || wrkdir || '"' /* Ask for the drive where to install or update VTeX */ say say INTRO say say "On which drive do you want VTeX/2 to be installed or updated?" say "(hit only to select the boot drive)" answer = linein() texdrive = translate(substr(answer,1,1)) || ":" if texdrive = ":" then texdrive = bootdrv call wlog 'VTeX drive = "' ||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 if ver > 0 then do say if ver = 7.32 then say "VTeX version 7.32(7.33) found." else say "VTeX version " || ver || " detected." end call wlog 'current version = "'|| ver || '"' /* force full re-install ? */ if ver > 0 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 else do /* fake version info, so that texmf.zip will not be installed */ distver.5 = 0 end end /* make sure the required ZIP files are in the current directory */ if CheckRequiredFiles("V") <> 1 then signal fileerr /* Locate the directory of the URW fonts, if VTeX is to be installed */ /* for the first time, or if pdf.fm and ps.fm are to be updated. */ if ver < FMVER then do gspath = AskForGsfonts() call wlog 'path of the URW fonts = "' || gspath || '"' if gspath = '' then signal nogsfonts end /* Last exit */ say say "VTeX/2 on drive " || 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() /* Check for unzip.exe ------------------- */ if SysSearchPath("PATH", "unzip.exe") = "" then signal unziperr /* Removing obsolete files created by previous versions ---------------------------------------------------- */ say "Removing possibly obsolete files ..." call SysFileDelete("\texmf\tex\latex\base\texsys.aux") call SysFileDelete("\texmf\source\latex\base\vtex2.txt") call SysFileDelete("\vtex\bin\bibtex.exe") call SysFileDelete("\vtex\bin\makeidx.exe") call SysFileDelete("\texmf\doc\makeindex\makeindex.txt") call SysFileDelete("\texmf\doc\vtex\local.ger") call SysFileDelete("\texmf\doc\vtex\psfonts.ger") call SysFileDelete("\texmf\tex\latex\seminar\fancybox.sty") call SysFileDelete("\texmf\tex\latex\amsmath\amstext.sty.org") call SysFileDelete("\texmf\vtex\config\latex.tex") /* call SysFileDelete("\texmf\tex\latex\base\texsys.cfg") */ say " done." /* Back up the configuration files ------------------------------- */ backup: call wlog ' ' 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") call wlog ' ' /* from now on, catch shell errors */ SIGNAL on error /* Unpack the ZIP archives ----------------------- */ vtex: /* overwrite existing files by default */ ret=value("UNZIP", "-qqo", "OS2ENVIRONMENT") do i = 1 to LASTREQ distfile.i = wrkdir || "\" || distfile.i if distver.i > ver then do call wlog "unzip " || distfile.i "unzip " || distfile.i end end /* unzip optional files, if present */ do i = (LASTREQ+1) to distfile.0 distfile.i = wrkdir || "\" || distfile.i if stream(distfile.i, "C", "QUERY EXISTS") <> "" then do call wlog "unzip " || distfile.i "unzip " || distfile.i end end /* The configuration file docstrip.cfg is special, */ /* because its contents must reflect the drive letter */ /* where TeX is installed. */ /* This file is generated unless it's already present.*/ /* Omit this for the time being filename = texdrive || "\texmf\tex\latex\local\docstrip.cfg" if stream(filename, "C", "QUERY EXISTS") = "" then do say "Creating the file docstrip.cfg ..." call lineout filename, "%% file docstrip.cfg, generated by vtexinst.cmd" call lineout filename, "%% do not edit this file!" call lineout filename, "\BaseDirectory{"||texdrive||"/texmf}" call lineout filename, "\UseTDS" call stream filename, "C", "CLOSE" say " done." end */ /* Writing the version number -------------------------- */ writever: ret = SysIni(texdrive || VERSIONFILE, "VTEX2", "VERSION", VERSION) say if ret = "" then do call wlog "version number" VERSION "written" say "Version number" VERSION "written." end else do call wlog "writing version number failed with rc =" ret say "Writing the version number failed." end /* Restore configuration files or write new ones --------------------------------------------- */ cfgfiles: call wlog ' ' say /* if version of current VTeX is at least INIVER, restore vtex.ini */ if ver >= INIVER then do call restconfig("\vtex\bin\vtex.ini") end /* otherwise configure vtex.ini appropriately, */ /* unless we install on drive c; */ else do say "New configuration file \vtex\bin\vtex.ini written." call wlog "New configuration file \vtex\bin\vtex.ini written." 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 end /* if version of current VTeX is at least FMVER, restore pdf.fm and ps.fm */ if ver >= FMVER then do call restconfig("\texmf\vtex\config\pdf.fm") call restconfig("\texmf\vtex\config\ps.fm") end /* otherwise edit the FM files appropriately, */ else do /* configure pdf.fm and ps.fm */ call readconfig "\texmf\vtex\config\pdf.fm" call fmedit texdrive, gspath 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, gspath 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 written." call wlog "New configuration files \texmf\vtex\config\pdf.fm and .\ps.fm written." end /* if version of current VTeX is at least HYVER, restore hyphenation cfg files */ if ver >= HYVER then do call restconfig("\texmf\vtex\config\hyphen.cfg") call restconfig("\texmf\vtex\config\plain.cfg") end else do say "New configuration files \texmf\vtex\config\hyphen.cfg and .\plain.cfg written." call wlog "New configuration files \texmf\vtex\config\hyphen.cfg and .\plain.cfg written." 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!" exit /* Error handling: */ logfileerr: say say "Error: I cannot write on the log file" logfile "." exit oldemtex: call wlog 'Obsolete emTeX found.' say say "Update emTeX/TDS to version" EMTEX "(or a later one)," say "before installing this version" VERSION "of VTeX/2 !" exit nogsfonts: call wlog 'Could not locate the URW fonts.' say say "The URW fonts were not found in the partition or folder you specified." say say "VTeX/2 cannot be installed without knowing the directory" say "of the Type 1 fonts supplied with Ghostscript." exit nobootdrv: call wlog 'Could not locate boot drive.' say say "The installation program cannot proceed, because" say "the boot drive cannot be located." 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." 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.' 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 were not found." exit unziperr: call wlog 'Program unzip.exe not found.' call beep 440,250 say say 'The required program "unzip.exe" could not be found.' 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 drive letter of the boot drive:" answer = linein() bootdr = substr(strip(answer),1,1)||":" end return bootdr /* Do all required ZIP files exist? usage: CheckRequiredFiles() or CheckRequiredFiles("V") returns: 1 if all files found, 0 otherwise */ CheckRequiredFiles: PROCEDURE expose distfile. distver. ver logfile LASTREQ parse arg verbose if verbose = "V" then say /* empty line to make messages more promonent */ res = 1 do i = 1 to LASTREQ if (distver.i > ver) & (stream(distfile.i, "C", "QUERY EXISTS") = "") then do res = 0 call wlog 'missing file:' distfile.i 'ver.' distver.1 if verbose = "V" then say "missing file:" distfile.i end end return res /* 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 gspath drive = drive letter of VTeX drive including colon gspath: directory, where the Base35 fonts reside returns: 1 if successful 0 otherwise */ fmedit: PROCEDURE expose config. cmax parse arg drive, gsfontpath gsfontpath = translate(gsfontpath, "/", "\") 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 if pos('URW = "c:/gs/fonts/"', config.i) <> 0 then do config.i = ' URW = "'||gsfontpath||'"' 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 AskForGsFonts: PROCEDURE expose bootdrv logfile /* determine ghostscript drive */ say say 'Enter the directory of the fonts, that came with with Ghostscript.' say 'If you do not know, enter the letter of the drive where you have' say 'installed Ghostscript/GSView, or hit to try the boot drive:' answer = translate(strip(linein()), "\", "/") if answer ='' then answer = bootdrv gspath = "" if length(answer) < 3 then do /* only drive given */ gsdrive = translate(substr(answer,1,1)) || ":" call wlog 'searching' gsdrive 'for the URW fonts...' call sysfiletree gsdrive||'\b018012l.pfb', rf, 'FSO', '*', '*' if rf.0 > 0 then do i = 1 to rf.0 path= filespec("D", rf.i) || filespec("P", rf.i) call wlog 'searching for fonts in' path if fontsexist(path) then do gspath = path say 'Fonts found in:' path call wlog 'font(s) found in' path leave end else call wlog 'font(s) not found in' path end else call wlog 'fonts not found on drive' gsdrive end else do /* full path given */ path = answer if substr(path,length(path),1) <> "\" then path = path || "\" call wlog 'searching' path 'for the URW fonts...' if fontsexist(path) then do gspath = path say 'Fonts found in:' path call wlog 'fonts found in' path end else call wlog 'fonts not found in' path end return gspath fontsexist: PROCEDURE parse arg path filea = path||'b018012l.pfb' fileb = path||'n019064l.pfb' filec = path||'s050000l.pfb' if ( stream(filea, "C", "QUERY EXISTS") <> '' ) & ( stream(fileb, "C", "QUERY EXISTS") <> '' ) & ( stream(filec, "C", "QUERY EXISTS") <> '' ) then return 1 else return 0 /* 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 */