/*
 *      INSTWGT.CMD - Wireless LAN Monitor Installation - Netlabs WLAN Project 2003-2008
 *
 *      Syntax: INSTWGT
 *
 *      This program installs the Wireless LAN Monitor as a XCenter Widget.
 *      This requires either XWorkplace or the OEM-Version EWorkplace
 *      (contained in eComStation V1.1. or better) installed.
 *
 */
/* The first comment is used as online help text */
/*****************Module Header *******************************
*
* Module Name: install.cmd
*
* Wireless LAN Status GUI library bubble help module
*
* Copyright (c) WLan Project 2003
*
* $Id: instwgt.cmd 1155 2018-09-20 18:33:44Z andib $
*
* ===========================================================================
*
* This file is part of the WLan Project and is free software.  You can
* redistribute it and/or modify it under the terms of the GNU Library General
* Public License as published by the Free Software Foundation, in version 2
* as it comes in the "COPYING.LIB" file of the WLan Project CVS tree.
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
* License for more details.
*
****************************************************************************/

 SIGNAL ON HALT

 TitleLine = STRIP(SUBSTR(SourceLine(2), 3));
 PARSE VAR TitleLine CmdName'.CMD 'Info
 Title     = CmdName Info

 env          = 'OS2ENVIRONMENT';
 TRUE         = (1 = 1);
 FALSE        = (0 = 1);
 CrLf         = '0d0a'x;
 Redirection  = '> NUL 2>&1';
 '@ECHO OFF'

 /* OS/2 Error codes */
 ERROR.NO_ERROR           =   0;
 ERROR.INVALID_FUNCTION   =   1;
 ERROR.FILE_NOT_FOUND     =   2;
 ERROR.PATH_NOT_FOUND     =   3;
 ERROR.ACCESS_DENIED      =   5;
 ERROR.NOT_ENOUGH_MEMORY  =   8;
 ERROR.INVALID_FORMAT     =  11;
 ERROR.INVALID_DATA       =  13;
 ERROR.NO_MORE_FILES      =  18;
 ERROR.WRITE_FAULT        =  29;
 ERROR.READ_FAULT         =  30;
 ERROR.GEN_FAILURE        =  31;
 ERROR.SHARING_VIOLATION  =  32;
 ERROR.INVALID_PARAMETER  =  87;
 ERROR.ENVVAR_NOT_FOUND   = 203;

 GlobalVars = 'Title CmdName CrLf env TRUE FALSE Redirection ERROR.';
 SAY;

 /* eventually show help */
 ARG Parm .
 IF (POS('?', Parm) > 0) THEN
 DO
    rc = ShowHelp();
    EXIT(ERROR.INVALID_PARAMETER);
 END;

 call RxFuncAdd    'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
 call SysLoadFuncs

 /* dafault values */
 GlobalVars = GlobalVars 'CallDir AppName';
 rc = ERROR.NO_ERROR;
 CallDir  = GetCallDir();

 AppName = 'Wireless LAN Monitor';

 DO UNTIL (TRUE)

    SAY Title;
    SAY;

    /* check for XWorkplace installation */
    CALL CHAROUT, '- checking XWorkplace/EWorkplace installation ... ';
    PARSE VALUE SysIni( , 'XWorkplace', 'XFolderPath') WITH XwpPath'0'x;
    IF (XwpPath == 'ERROR:') THEN
    DO
       SAY 'not found!';
       SAY '- XCenter Widget cannot be installed';
       rc =  ERROR.PATH_NOT_FOUND;
    END;
    ELSE
    DO
       XwpPluginPath = XwpPath'\plugins\xcenter';
       SAY 'Ok.';

       /* install XWorkplace xCenter widget */
       rc = InstallWidget( XwpPluginPath);
       IF (rc \= ERROR.NO_ERROR) THEN
          LEAVE;

       /* check cached TCP/IP binding information */
       rc = CheckBindings();
       IF (rc \= ERROR.NO_ERROR) THEN
          LEAVE;
    END;

 END;

 EXIT( rc);

/* ------------------------------------------------------------------------- */
HALT:
 SAY 'Abbruch durch Benutzer.';
 EXIT(ERROR.GEN_FAILURE);

/* ------------------------------------------------------------------------- */
ShowHelp: PROCEDURE EXPOSE (GlobalVars)

 /* show title */
 SAY Title;
 SAY;

 PARSE SOURCE . . ThisFile

 /* skip header */
 DO i = 1 TO 3
    rc = LINEIN(ThisFile);
 END;

 /* show help text */
 ThisLine = LINEIN(Thisfile);
 DO WHILE (ThisLine \= ' */')
    SAY SUBSTR(ThisLine, 7);
    ThisLine = LINEIN(Thisfile);
 END;

 /* close file */
 rc = LINEOUT(Thisfile);

 RETURN('');

/* ------------------------------------------------------------------------- */
GetCalldir: PROCEDURE
PARSE SOURCE . . CallName
 CallDir = FILESPEC('Drive', CallName)||FILESPEC('Path', CallName);
 RETURN(LEFT(CallDir, LENGTH(CallDir) - 1));

/* ------------------------------------------------------------------------- */
GetDrivePath: PROCEDURE
 PARSE ARG FileName

 FullPath = FILESPEC('D', FileName)||FILESPEC('P', FileName);
 IF (FullPath \= '') THEN
    RETURN(LEFT(FullPath, LENGTH(FullPath) - 1));
 ELSE
    RETURN('');

/* ------------------------------------------------------------------------- */
FileExist: PROCEDURE
 PARSE ARG FileName

 RETURN(STREAM(Filename, 'C', 'QUERY EXISTS') > '');

/* ------------------------------------------------------------------------- */
MakePath: PROCEDURE EXPOSE (GlobalVars)
 PARSE ARG PathName;

 PARSE SOURCE . . CallName
 FileName = SUBSTR( CallName, LASTPOS( '\', CallName) + 1);
 'XCOPY' CallName PathName'\' Redirection;
 rcx = SysFileDelete( PathName'\'FileName);
 RETURN( rc);

/* ========================================================================= */
GetHlpFile: PROCEDURE
 PARSE ARG Path, Stem, Language;

 Language = STRIP( Language);
 IF (Language = '') THEN
    Language   = GetSystemLanguage();

 RETURN( Path'\'Stem''Language'.hlp');

/* ========================================================================= */
GetSystemLanguage: PROCEDURE EXPOSE (GlobalVars)

 ValidLanguageChars = '0GF';
 ValidLanguageIds   = 'eng deu fra';
 SystemLanguage     = 'eng'; /* default */

 DO 1
    /* open Syslevel file and read language char */
    PARSE VALUE TRANSLATE( VALUE( 'PATH',,'OS2ENVIRONMENT')) WITH '\OS2;' -2 BootDrive +2;
    SyslevelFile = BootDrive'\OS2\INSTALL\SYSLEVEL.OS2';
    IF (STREAM( SyslevelFile, 'C', 'OPEN READ') \= 'READY:') THEN
       LEAVE;
    LanguageChar = CHARIN( SyslevelFile, X2D(37), 1);
    rcx = STREAM( SyslevelFile, 'C', 'CLOSE');

    /* translate into three letter ISO language code */
    LanguagePos = POS( LanguageChar, ValidLanguageChars);
    IF ((LanguagePos > 0) & (LanguagePos <= WORDS( ValidLanguageIds))) THEN
       SystemLanguage = WORD( ValidLanguageIds, LanguagePos);
 END;

 RETURN( SystemLanguage);

/* ========================================================================= */
CopyDir: PROCEDURE EXPOSE (GlobalVars)
PARSE ARG SourceDir, TargetDir, ExcludeList;

 rc = ERROR.NO_ERROR;
 ErrantFile = '';

 DO 1
    /* get all files */
    rc = SysFileTree( SourceDir'\*', 'File.', 'FOS');
    IF (rc \= 0) THEN
    DO
       SAY 'internal error in SysFileTree ! Reboot the system and try again !';
       EXIT(99);
    END;

    /* no files found */
    IF (File.0 = 0) THEN
    DO
       rc = ERROR.FILE_NOT_FOUND;
       LEAVE;
    END;

    DO i = 1 TO File.0
       /* determine filenames */
       SourceFile = File.i;
       SubPath    = SUBSTR( File.i, LENGTH( SourceDir) + 2);
       TargetFile = TargetDir'\'SubPath;
       FinalTargetDir  = GetDrivePath( TargetFile);
       ErrantFile = SubPath;

       /* don't copy files of exclude list */
       CheckList = ExcludeList;
       fSkipFile = FALSE;
       DO WHILE (CheckList \= '')
          PARSE VAR CheckList ThisExclude CheckList;
          IF (POS( TRANSLATE( '\'ThisExclude), TRANSLATE(SourceFile)) > 0) THEN
          DO
             fSkipFile = TRUE;
             LEAVE;
          END;
       END;
       IF (fSkipFile) THEN
          ITERATE;

       SAY '  -' SubPath

       /* try to delete the file - this results in a more       */
       /* comprehensive rc than the rc of a failed COPY command */
       /* 20140222 AB try to unlock first. Unlock.exe comes with recent eCS anyway */
       '@unlock' TargetFile '>NUL 2>&1';
       rc = SysFileDelete( TargetFile);
       SELECT
          /* file deleted, COPY will succeed */
          WHEN (rc = ERROR.NO_ERROR) THEN NOP;

          /* file not found, COPY will succeed */
          WHEN (rc = ERROR.FILE_NOT_FOUND) THEN NOP;

          /* path not found, directory does not exist */
          WHEN (rc = ERROR.PATH_NOT_FOUND) THEN
             rcx = MakePath( FinalTargetDir);

          /* access problems - abort */
          WHEN (rc = ERROR.ACCESS_DENIED) THEN LEAVE;
          WHEN (rc = ERROR.SHARING_VIOLATION) THEN LEAVE;

          /* leave on unknown problems as well */
          OTHERWISE LEAVE;
       END;

       /* copy the file */
       'COPY' SourceFile  TargetFile '>NUL 2>&1';
       IF (rc \= ERROR.NO_ERROR) THEN
          LEAVE;

       ErrantFile = '';
    END;

 END;

 RETURN( STRIP( rc ErrantFile));

/* ========================================================================= */
InstallWidget: PROCEDURE EXPOSE (GlobalVars)
 PARSE ARG XwpPluginPath;

 rc = ERROR.NO_ERROR;
 Indent = '  ';

 WpaSuppKillCmd = 'CALL xcenter\xwlan\xwlprf.exe /KillSup' Redirection;

 DO 1
    /* stop WPA supplicant instances */
    '' WpaSuppKillCmd;
    IF (rc = 0) THEN
       SAY '- stop runing instances of WPA supplicant';
    DO WHILE (rc = 0)
       rcx = SysSleep( 1);
       '' WpaSuppKillCmd;
    END;


    /* copying complete xcenter subdirectory */
    SAY '- copying Wireless LAN Monitor XCenter Widget components';
    rc = CopyDir( CallDir'\xcenter', XwpPluginPath, 'WLANSTAT.EXE');
    rc = CopyDir( CallDir'\xcenter', XwpPluginPath, 'WLANSTAT.XQS');
    PARSE VAR rc rc ErrantFile;
    SAY;
    SELECT
       WHEN (rc == ERROR.NO_ERROR) THEN
       DO
          SAY 'Installation complete!';
          SAY 'Stop and restart all XCenter instances to access the new widget.';
       END;

       WHEN (rc == ERROR.SHARING_VIOLATION) THEN
       DO
          SAY Indent CmdName': error: sharing violation, cannot copy file' ErrantFile;
          FileExt = TRANSLATE( SUBSTR( ErrantFile, LASTPOS( '.', ErrantFile) + 1));
          SELECT
             WHEN ( WORDPOS( FileExt, 'DLL NLS') > 0) THEN
             DO
                SAY Indent 'Stop all XCenter instances and try again.';
                SAY Indent 'If the error persists, restart the desktop and try again.';
             END;

             WHEN ( WORDPOS( FileExt, 'HLP') > 0) THEN
                SAY Indent 'Restart the desktop and try again.';

             WHEN ( WORDPOS( FileExt, 'INF') > 0) THEN
                SAY Indent 'Close all help windows and try again.';

             OTHERWISE NOP;
          END;
          SAY;
       END;

       WHEN (rc == ERROR.FILE_NOT_FOUND) THEN
          SAY Indent CmdName': error: no files to install, package maybe corrupt.';

       WHEN (rc == ERROR.INVALID_FUNCTION) THEN
          SAY Indent CmdName': error: cannot copy file.';

       WHEN (rc = ERROR.ACCESS_DENIED) THEN
          SAY Indent CmdName': error: cannot copy file (write protected).';

       OTHERWISE
          SAY Indent CmdName': unknown error rc='rc;
    END;

    /* delete files of old versions */
    rc = SysFileDelete( XwpPluginPath'\wlanstat.exe');
    rc = SysFileDelete( XwpPluginPath'\wlanstat.xqs');
    rc = SysFileDelete( XwpPluginPath'\xwlprf.exe');
    rc = SysFileDelete( XwpPluginPath'\xwlprf.xqs');
    rc = SysFileDelete( XwpPluginPath'\dimtest.exe');
    rc = SysFileDelete( XwpPluginPath'\dimtest.xqs');

 END;

 RETURN( rc);

/* ========================================================================= */
CheckBindings: PROCEDURE EXPOSE (GlobalVars)

 rc = ERROR.NO_ERROR;

 XwlCheckExec = CallDir'\xcenter\xwlprf.exe';
 XwlCheckOpts = '/C /V /N';

 DO 1
    /* check for executable */
    IF (\FileExist( XwlCheckExec)) THEN
       LEAVE;

    'CALL' XwlCheckExec XwlCheckOpts Redirection;
    IF (rc \= ERROR.NO_ERROR) THEN
    DO
       SAY;
       SAY 'Warning:';
       SAY 'The TCP/IP binding information previously stored by Wireless LAN Monitor'
       SAY 'and used for GenPrism style drivers on your system may be outdated. In case'
       SAY 'that the Wireless LAN Monitor is unable to configure the TCP/IP interface'
       SAY 'corresponding to the active Wireless LAN device, please restart your system !!!'
       SAY;
       'CALL' XwlCheckExec XwlCheckOpts;
    END;

 END;

 RETURN( rc);

