/***************************************************/

/*****************************************
* Intialize Rexxutil Functions
******************************************/

  call RxFuncAdd 'SysLoadFuncs' , 'REXXUTIL', 'SysLoadFuncs'

  signal on syntax name MsgExit

  call SysLoadFuncs

  numeric digits 12

/******************************************
* Define message ids from *mid*.h
*******************************************/
  MSG_SYSINIT_BOOT_NOT_FD    = 1475
  MSG_INCORRECT_DOSVER       = 1210
  MSG_NO_META_MATCH          =  257
  MSG_PRINT_FILE_NOT_FOUND   = 1533
  MSG_COMP_INVALID_PATH      = 1171
  MSG_BOOT_MUST_RESTART      = 1716
  MSG_INSTALL_UNSUCCESSFUL   = 1975
  MSG_INSTALL_HY_HDR         = 1976
  MSG_PROC_NOT_FOUND         =  127
  MSG_REP_SOUR_PATH_REQ      = 1137
  MSG_SYS_INV_DRIVE          = 1461
  MSG_CHCP_INVALID_PARAMETER = 1761
  MSG_UNP_INSERT_PI          = 1218
  MSG_ERR_PROC_ARG           = 1249
  MSG_MBS_INVALID_COMMAND    =  872
  SPTReboot                  = x2d('FE00',4)
  SPTRebootErr               = x2d('FE08',4)
  SPTWithErr                 = x2d('0008',4)


/*****************************************
* Initialized globals
******************************************/
  GRADDKEYS    = 'NV GEN VGA'
  GRADDDSCS    = 'nvgradd gengradd vgagradd'
  graddPackDSC = 'grdpack.dsc'
  cidInst = ''
/*****************************************
* Set up Source and Target Paths
******************************************/
  parse source one two me
  srcPath = filespec('Drive', me) || filespec('Path', me)
  srcName = filespec('Name', me)


  os2bootPath = SysSearchPath('PATH', 'os2boot')
  if os2bootpath \= ''
   then bootDrive = filespec('drive', os2bootPath)
   else call MsgExit SysGetMessage(MSG_SYSINIT_BOOT_NOT_FD)

/******************************************
* Verify options if any
*******************************************/
  if arg() == 0
    then call Usage
    else do
       cmdline = arg(1)
       parse value(cmdline) with tmp1 '/' option tmp2
       if option \= ''
       then do
          if translate(option) == 'U'
          then do
             cidInst = ' /u'
             cmdline = tmp1 || tmp2
          end
          else do
             say MyGetMsg(SysGetMessage(MSG_MBS_INVALID_COMMAND,, '"' || '/' || option || '"'))
             call Usage
          end
       end
       parse value(cmdline) with gradd srcTmp bootTmp junk
       if junk \= '' then call Usage
       if wordpos(translate(gradd), GRADDKEYS) == 0
         then call Usage
         else dscFile = word(GRADDDSCS, wordpos(translate(gradd), GRADDKEYS)) || '.dsc'
       if srcTmp \= ''
         then do
            if filespec('Drive',srcTmp) == strip(srcTmp, 'T', '\')
              then srcChk = srcTmp
              else srcChk = strip(srcTmp, 'T', '\') || '\'
            call SysFileTree srcChk || srcName, 'file', 'F'
            if file.0 == 0
              then do
                 say MyGetMsg(SysGetMessage(MSG_PRINT_FILE_NOT_FOUND, ,'"' || srcChk || srcName || '"'))
                 say MyGetMsg(SysGetMessage(MSG_CHCP_INVALID_PARAMETER, ,srcTmp))
                 call Usage
              end
              else srcPath = srcChk
         end
       if bootTmp \= ''
         then do
            bootTmp   = strip(bootTmp, 'T', '\')
            call SysFileTree bootTmp || '\OS2BOOT', 'file', 'F'
            if file.0 == 0
              then do
                 msg = MyGetMsg(SysGetMessage(MSG_SYSINIT_BOOT_NOT_FD))
                 parse value(msg) with first 'OS2BOOT' last
                 msg = first || '"' || bootTmp || '\OS2BOOT"' || last
                 say msg
                 say MyGetMsg(SysGetMessage(MSG_SYS_INV_DRIVE))
                 call Usage
              end
              else bootDrive = bootTmp
         end
    end


/*****************************************
* Start logging
******************************************/

  installDir = bootDrive || '\os2\install'
  call SysFileTree installDir, 'file', 'D'
  if file.0 == 0 then call MsgExit MyGetMsg(SysGetMessage(MSG_COMP_INVALID_PATH, ,'"' || installDir || '"'))
  logFile = installDir || '\display.log'
  call SysFileTree logFile, 'file', 'F', ,'-----'
  startmsg = MyGetMsg(SysGetMessage(MSG_UNP_INSERT_PI,, SubStr(dscFile,1, pos('.', dscFile)-1 ) ))
  cmd = 'parse value(startmsg) with . '''D2c(10)''' installmsg '''D2c(13)''' junk'
  interpret cmd
  installmsg = strip(installmsg)
  call LogIt '======================================================================'
  say installmsg
  call LogIt installmsg ' - ' Date('L')  Time()
  '@if exist 'srcPath || 'build.lvl type 'srcPath || 'build.lvl >>'logFile


/*******************************************************
* Gradd is not supported on OS/2 Versions less than 3.0
* and it also requires a certain fixpak level for both
* version 3.x and 4.0.  Let us verify we have the right
* levels now.
********************************************************/
  parse value(SysOS2Ver()) with major '.' os2Ver
  rc = 1
  select
     when major < 2 then call MsgExit MyGetMsg(SysGetMessage(MSG_INCORRECT_DOSVER))
     when datatype(os2Ver) \= 'NUM' then call MsgExit MyGetMsg(SysGetMessage(MSG_INCORRECT_DOSVER))
     when os2Ver < 30  then call MsgExit MyGetMsg(SysGetMessage(MSG_INCORRECT_DOSVER))
     when os2Ver < 40  then needLevel = 2
     otherwise needLevel = 1
  end
  parse value(GetGraddLevel(bootDrive || '\os2\dll\gre2vman.dll')) with graddLevel graddStamp
  if \(graddLevel >= needLevel) then call MsgExit MyGetMsg(SysGetMessage(MSG_INCORRECT_DOSVER))
  rc = 0


/*******************************************************
* Setup path and Copy required files to \os2\install
********************************************************/

  oldPath = value('PATH', , 'OS2ENVIRONMENT')
  newPath = value('PATH', srcPath || ';' || oldPath, 'OS2ENVIRONMENT')

  rc = 0
  unpackFiles = srcPath || 'dspinstl.ex_ 'srcPath || 'inscfg32.dl_'
  do i = 1 to words(unpackFiles) while (rc == 0)
    cmd = 'unpack 'word(unpackFiles, i) bootDrive
    call LogIt cmd
    '@' || cmd || ' >> 'logfile ' 2>&1'
  end
  if rc \= 0 then call MsgExit ""


/********************************************************
* Obtain .DSC file
*********************************************************/

  call SysFileTree srcPath || dscFile, 'file', 'F'
  if file.0 == 0 then call MsgExit MyGetMsg(SysGetMessage(MSG_PRINT_FILE_NOT_FOUND,, '"' || srcPath || '*.dsc' || '"')),
                                   || MyGetMsg(SysGetMessage(MSG_NO_META_MATCH))
                 else parse value(file.1) with . . . . dscFile

  cmd = 'copy 'dscFile installDir
  dscFile = installDir || '\' || FileSpec('Name', dscFile)
  call LogIt cmd
  '@' || cmd || ' >> 'logfile ' 2>&1'
  if rc \= 0 then call MsgExit ""

  if SysFileTree(bootDrive || '\os2\video.cfg','file','F',,'+****') == 0
    then call SysFileDelete bootDrive || '\os2\video.cfg'

  if translate(gradd) == 'VGA' then call SysIni ,'PM_DISPLAYDRIVERS','DEFAULTSYSTEMRESOLUTION','DELETE:'



  cmd = 'copy 'srcPath || graddPackDSC installDir
  '@' || cmd || '>nul 2>&1'
  if rc \= 0 then graddPackDSC = ''
             else do
                graddPackDSC = installDir || '\' || graddPackDSC
                parse value(GetGraddLevel(srcPath || 'gre2vman.dll')) with . newStamp
             end

  dspInstall = bootDrive || '\os2\install\dspinstl.exe'
  if filespec('Drive', srcPath) \= strip(srcPath, 'T', '\')
    then srcPath = strip(srcPath, 'T', '\')


  if ((symbol('newStamp') == 'VAR') & (newStamp \= ''))
  then do
     if ((graddStamp == '') | ( newStamp > graddStamp))
       then '@' || dspInstall '/pk:other /s:' || srcPath || ' /t:' || bootDrive,
                          || ' /pd:' || strip(graddPackDSC) || ' /l:' || logFile
  end


  '@' || dspInstall '/pk:svga /s:' || srcPath || ' /t:' || bootDrive,
              || ' /pd:' || strip(dscFile) || ' /l:' || logFile || cidInst

  if ( (rc == 0) | ((cidInst \= '') & ( rc == SPTReboot)) )
    then call MsgExit MyGetMsg(SysGetMessage(MSG_BOOT_MUST_RESTART))
    else call MsgExit MyGetMsg(SysGetMessage(MSG_ERR_PROC_ARG,,dscFile))

/******************************************************
* Procedure for determining level of Gradd subsystem
*******************************************************/
GetGraddLevel: Procedure

parse arg graddModule

gtvVer = ''

if stream(graddModule,'c', 'query exists') \= ''
then do
    newQueue = RxQueue('Create')
    oldQueue = RxQueue('Set', newQueue)
    '@bldlevel 'graddModule '| rxqueue' newQueue
    do while queued() \=0
       parse upper pull tag data
       if tag == 'SIGNATURE:'
       then
          do while queued() \= 0
            parse upper pull tag data
            if tag == 'DESCRIPTION:'
               then parse value(data) with  'V' gtvVer gtvStamp .
          end
    end
    call RxQueue 'Delete', newQueue
    call RxQueue 'Set', oldQueue
end

if datatype(gtvVer)   \= 'NUM' then gtvVer = 0
if datatype(gtvStamp) \= 'NUM' then gtvStamp = 0

return gtvVer gtvStamp


/******************************************************
* Error message processing and exit
*******************************************************/
MsgExit:

   parse arg errmsg

   if rc == 43
    then do
        say sigl'  +++      'SourceLine(sigl)
        say 'REX0043: 'ErrorText(43)
    end
    else do
      if errmsg == '' then errmsg = 'REXX' || right(rc,4,'0') || ': 'ErrorText(rc)
      say errmsg
      if ( (rc \= 0) & ((cidInst \= '') & ( rc \= SPTReboot)) )
        then do
           exitmsg = MyGetMsg(SysGetMessage(MSG_INSTALL_UNSUCCESSFUL))
           say exitmsg
        end

      if symbol('logfile') == 'VAR'
        then do
           if symbol('exitmsg') == 'VAR'
             then do
               call LogIt errmsg
               call LogIt exitmsg
               say MyGetMsg(SysGetMessage(MSG_INSTALL_HY_HDR)) || ' ' || logfile
             end
        end
    end

   if symbol('oldPath') == 'VAR' then call value 'PATH' , oldPath, 'OS2ENVIRONMENT'
   exit rc

/******************************************************
* Safely write to logfile
*******************************************************/
LogIt: Procedure expose logfile

  parse arg message
  call lineout logfile, message
  call stream logfile, 'c', 'close'
  return

/******************************************************
* Remove SYSXXXX: from messages
*******************************************************/
MyGetMsg: Procedure
  parse arg message

  if pos('SYS', word(message, 1)) == 1
    then parse arg . message

  return message

/*****************************************************
* Print usage and exit
******************************************************/
Usage:

      msg = MyGetMsg(SysGetMessage(734,,srcName))
      cmd = 'parse value(msg) with msg '''srcName''' .'
      interpret cmd
      indent = copies(' ',30)
      say msg me || ' xxx [' || srcPath || '] [' || bootDrive || '] [/u]'
      say ''
      say '                          xxx:'
      say indent || '"NV"    -   NVIDIA NV4'
      say indent || '"GEN"   -   GENGRADD Generic SVGA'
      say indent || '"VGA"   -   VGAGRADD Generic VGA'
      say ''
      exit 1
