Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Jan-Erik Lärka

Pages: [1] 2
1
Programming / Android SDK with classic rexx
« on: September 16, 2019, 11:23:07 pm »
This is a script that create a program object that you can use to list and download Android SDK.
It download the current Android SDK and libraries as I write this.
Prerequisite: java and android-sdk_r24.4.1-windows.zip (as previously found through) unpacked to a folder
  • Just run the script by double clicking on it.
  • It search your computer for the unpacked sdk, copy itself and files it need and create a program object (if possible).
  • Double click on the program object and type "update sdk --filter 3,2,1" and follow the instructions.
    repeat the procedure with the packages you want to download, use "list sdk" to list available packages.
The script add "--no-ui --no-https" as it doesn't work otherwise.
Please also note that I don't know if you can actually develop something with the downloaded files, that is up to you to find out.
It was intended to act as a subsystem for development with NetRexx to create apps for Android, but I didn't persue it further since there are so few examples and information on how to actually code NetRexx apps and deploy them on Android.
Code: [Select]
/*
 * Filename: android.cmd
 *   Author: JanErik
 *  Created: Sun Sep 11 2016
 *  Purpose: Install SDK for Android in OS/2
 *  Changes: Mon Sep 16 2019 Changes to program object and startup configuration.
 *  Require: Zip SDK (such as android-sdk_r24.4.1-windows.zip), downloads updates live.
 */

'@echo off'
'@mode 80,102'
'@cls'

/* Set up prog to be the path of this script, including following symlinks,
   and set up progdir to be the fully-qualified pathname of its directory. */
PARSE SOURCE . . prog
PARSE ARG params

IF LENGTH( STRIP( params ) ) = 0 THEN
   params = '-h'

/* Grab current directory before we change it */
work_dir = DIRECTORY()

/* Change current directory and drive to where the script is, to avoid
 issues with directories containing whitespaces. */
PARSE VALUE REVERSE( prog ) WITH fname'\'this
this = REVERSE( this )
CALL DIRECTORY this

/* Load RexxUtil Library */
IF RxFuncQuery('SysLoadFuncs') THEN
DO
   CALL RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
   CALL SysLoadFuncs
END

env = 'ENVIRONMENT'
/* Check we have a valid Java.exe in the path.*/
IF VALUE( 'JAVA_HOME',, env ) = '' THEN
DO
   CALL SysGetEA this, 'JAVA_HOME', 'java_path'
   IF STREAM( java_path'\JAVA.EXE', 'C', 'QUERY EXISTS' ) = "" THEN
      java_path = ''
   IF LENGTH( java_path ) < 2 THEN DO
      PARSE UPPER VALUE rxFind( 'JAVA.EXE', ' -version', 'VERSION "1.' ) WITH java_path'\BIN'
      IF LENGTH( java_path ) = 0 THEN
      DO
         CALL LINEOUT 'STDERR', 'JAVA engine not found'
         RETURN 1
      END
      CALL SysPutEA this, 'JAVA_HOME', java_path
   END
END
ELSE java_path = VALUE( 'JAVA_HOME',, env )

CALL SysGetEA this, 'ANDROID_PATH', 'android_path'
IF STREAM( android_path'\android.bat', 'C', 'QUERY EXISTS' ) = "" THEN
   android_path = ''
IF LENGTH( android_path ) < 2 THEN DO
   PARSE VALUE rxFind( 'android.bat' ) WITH android_path
   IF LENGTH( android_path ) = 0 THEN
   DO
      CALL LINEOUT 'STDERR', 'Android SDK not found'
      RETURN 2
   END
   CALL SysPutEA this, 'ANDROID_PATH', android_path
END
ext = 'cmd ico png'
DO i = 1 TO 3
   IF STREAM( android_path'\android.'SUBWORD( ext, i, 1 ), 'C', 'QUERY EXISTS' ) = '' THEN
      IF SysCopyObject( this'\android.'SUBWORD( ext, i, 1 ), android_path ) = 1 THEN
         CALL LINEOUT 'STDERR', 'Copied android.'SUBWORD( ext, i, 1 )' to "'android_path'"'
END
IF TRANSLATE( android_path ) <> TRANSLATE( this ) THEN
DO
   this = android_path
   work_dir = android_path
END

objID = 'ANDROID'
android_name = 'Android'
android_wps = 'Android SDK'
IF wpsObjectExist( '<WP_'objID'>' ) = 0 THEN
DO
   setupstring = 'OBJECTID=<WP_'objID'>;NOAUTOCLOSE=YES;EXENAME='this'\android.cmd;PARAMETERS=[Specify parameter (list sdk --filter 1)];ICONFILE='this'\'android_name'.ico;'
   IF SysCreateObject( 'WPProgram', android_wps, '<WP_DEVFLDR>', setupstring, 'U' ) <> 1 THEN
      CALL SysCreateObject 'WPProgram', android_wps, '<WP_DESKTOP>', setupstring, 'U'
   CALL rxAddBigIcon this'\'android_name'.png', '<WP_'objID'>'
END

jar_path = 'lib\sdkmanager.jar;lib\swtmenubar.jar'

/* Set SWT.Jar path based on current architecture (x86 or x86_64)*/
CALL DIRECTORY this
swt_path = ''
DO WHILE LENGTH( swt_path ) = 0
   DO WHILE QUEUED() > 0; PARSE PULL; END
   '@'java_path'\bin\java.exe -jar lib\archquery.jar|rxqueue'
   PARSE PULL swt_path
END

MkTempCopy:
    /* Copy android.bat and its required libs to a temp dir.
       This avoids locking the tool dir in case the user is trying to update it.*/

   tmp_dir = VALUE( 'TEMP',,'ENVIRONMENT' )'\temp-android-tool'
   cpy = swt_path'\* common.jar commons-codec* commons-compress* commons-logging dvlib.jag gson* guava* httpclient* httpcore* httpmime* layoutlib-api.jar org-eclipse-* sdk* swtmenubar.jar'
   DO i = 1 TO WORDS( cpy )
      cpyfile = 'lib\'SUBWORD( cpy, i, 1 )
      IF POS( '*', cpyfile ) > 0 THEN
      DO
         CALL SysFileTree this'\'cpyfile, 'file.', 'SFO'
         DO j = 1 TO file.0
            CALL rxCpyFile this, file.j, tmp_dir
         END
      END
      ELSE CALL rxCpyFile this, this'\'cpyfile, tmp_dir
   END

   /* jar_path and swt_path are relative to PWD so we don't need to adjust them, just change dirs.*/
   tools_dir = android_path
   CALL DIRECTORY tmp_dir

EndTempCopy:

   /* The global ANDROID_SWT always override the SWT.Jar path */
   IF VALUE( 'ANDROID_SWT',,'ENVIRONMENT' ) <> '' THEN
      swt_path = VALUE( 'ANDROID_SWT',,'ENVIRONMENT' )
   ELSE
      swt_path = this'\lib\'swt_path
   IF DIRECTORY( swt_path ) = '' THEN
   DO
      CALL LINEOUT 'STDERR', 'ERROR: SWT folder "'swt_path'" does not exist.'
      CALL LINEOUT 'STDERR', 'Please set ANDROID_SWT to point to the folder containing swt.jar for your platform.'
      RETURN 2
   END

SetPath:
/* Finally exec the java program and end here.
 REMOTE_DEBUG=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000*/
   IF 0 = POS( TRANSLATE( java_path ), TRANSLATE( VALUE( 'PATH',,'ENVIRONMENT' ) ) ) THEN
      CALL VALUE 'PATH', java_path'\bin;'||STRIP( VALUE( 'PATH',,'ENVIRONMENT' ),, ';' ), 'ENVIRONMENT'
   IF 0 = POS( TRANSLATE( tools_path ), TRANSLATE( VALUE( 'PATH',,'ENVIRONMENT' ) ) ) THEN
      CALL VALUE 'PATH', tools_path'\lib;'||STRIP( VALUE( 'PATH',,'ENVIRONMENT' ),, ';' ), 'ENVIRONMENT'
   CALL DIRECTORY tools_dir
   '@java "-Dcom.android.sdkmanager.toolsdir='tools_dir'" "-Dcom.android.sdkmanager.workdir='work_dir'" -classpath "'jar_path';'swt_path'\swt.jar" com.android.sdkmanager.Main 'params' --no-ui --no-https'
   CALL DIRECTORY work_dir
RETURN rc
   
rxCpyFile: PROCEDURE
   PARSE VALUE REVERSE( SUBSTR( ARG(2), LENGTH( ARG(1) ) + 1 ) ) WITH fname'\'fpath
   fpath = REVERSE( fpath )
   rc = rxMkDir( ARG(3)fpath )
   IF rc = 0 & STREAM( ARG(3)fpath'\'REVERSE( fname ), 'C', 'QUERY EXISTS' ) = '' THEN
      rc = SysCopyObject( ARG(2), ARG(3)fpath )
RETURN rc
   
rxChk: PROCEDURE
   DO WHILE QUEUED() > 0; PARSE PULL; END;
   '@'||ARG(1)||ARG(2)||' 2>>&1 | RXQUEUE'
   DO WHILE QUEUED() > 0
      IF POS( TRANSLATE( ARG(3) ), TRANSLATE( LINEIN( 'QUEUE:' ) ) ) > 0 THEN
         IF LENGTH( ARG(4) ) > 0 THEN RETURN ARG(4)
   END
RETURN ''
   
rxFind: PROCEDURE EXPOSE !_msg_!.
   env = 'ENVIRONMENT'
   PARSE VALUE REVERSE( SysSearchPath( 'PATH', ARG(1) ) ) WITH fname'\'fpath
   fpath = REVERSE( fpath )
   fname = REVERSE( fname )
   IF ARG() > 1 & LENGTH( fpath ) > 0 THEN
      fspec = rxChk( fpath'\'fname, ARG(2), ARG(3), fpath )
   ELSE IF STREAM( fpath'\'fname, 'C', 'QUERY EXISTS' ) <> '' THEN
      fspec = fpath
   ELSE fspec = ''
   IF LENGTH( fspec ) > 0 THEN RETURN fspec
   CALL LINEOUT 'STDERR', VALUE( 'PROGRAMS',, env )
   IF POS( '*', ARG(1) ) = 0 THEN fname = '*'ARG(1)
   ELSE fname = ARG(1)
   CALL SysFileTree VALUE( 'PROGRAMS',, env )'\'fname, 'file.', 'SFO'
   DO i = 1 TO file.0
      PARSE VALUE REVERSE( file.i ) WITH .'\'fspec
      IF ARG() > 1 THEN
         fspec = rxChk( file.i, ARG(2), ARG(3), REVERSE( fspec ) )
      ELSE
         fspec = REVERSE( fspec )
      IF LENGTH( fspec ) > 0 THEN RETURN fspec
   END
   drives = SysDriveMap( 'C:', 'USED' )
   DO j = 1 TO WORDS( drives )
      CALL LINEOUT 'STDERR', SUBWORD( drives, j, 1 )
      CALL SysFileTree SUBWORD( drives, j, 1 )||'\'fname, 'file.', 'SFO'
      DO i = 1 TO file.0
         PARSE VALUE REVERSE( file.i ) WITH .'\'fspec
         IF ARG() > 1 THEN
            fspec = rxChk( file.i, ARG(2), ARG(3), REVERSE( fspec ) )
         ELSE
            fspec = REVERSE( fspec )
         IF LENGTH( fspec ) > 0 THEN RETURN fspec
      END
   END
RETURN ''   
   
rxMkDir: PROCEDURE
    rc = ( DIRECTORY( ARG(1) ) = '' )
    IF rc = 1 THEN
        IF \rxMkDir( STRIP( FILESPEC( 'D', ARG(1) )FILESPEC( 'P', ARG(1) ), 'T', '\' ) ) THEN
           rc = SysMkDir( ARG(1) )
Return rc
   
rxAddBigIcon: PROCEDURE EXPOSE !_msg_!. java_path
    crlf = D2C(13)D2C(10)
    bigicons_dir = VALUE( 'BIGICONS',, 'ENVIRONMENT' )
    bigicon = FILESPEC( 'N', ARG(1) )
    objid = ARG(2)
    IF LENGTH( bigicons_dir ) > 0 THEN
    DO
        IF STREAM( ( bigicons_dir'\'bigicon ), 'C','QUERY EXISTS') = '' THEN
           IF SysCopyObject( ARG(1), bigicons_dir ) = 0 THEN
              RETURN 1
        IF STREAM( bigicons_dir'\bigicons.txt', 'C', 'QUERY EXIST' ) <> '' THEN
        DO
            f_size = STREAM( bigicons_dir'\bigicons.txt', 'C', 'QUERY SIZE' )
            IF f_size > 0 THEN
            DO
                input = CHARIN( bigicons_dir'\bigicons.txt', 1, f_size )
                CALL STREAM bigicons_dir'\bigicons.txt', 'C', 'CLOSE'
                PARSE UPPER VALUE input WITH pre'"'(bigicon)'"'post
                IF LENGTH( post ) > 0 THEN RETURN 2
                PARSE UPPER VALUE input WITH pre'"'(objid)'"'post
                IF LENGTH( post ) > 0 THEN RETURN 3
                PARSE VALUE input WITH pre'[OBJECTID]'mid(crlf)(crlf)'['post
                input = pre'[OBJECTID]'STRIP( STRIP( mid, 'T', D2C(10) ), 'T', D2C(13) )||crlf||LEFT( '"'objid'"', 28 )'"'bigicon'"'crlf||crlf'['post
                CALL SysFileDelete bigicons_dir'\bigicons.txt'
                CALL CHAROUT bigicons_dir'\bigicons.txt', input
                CALL STREAM bigicons_dir'\bigicons.txt', 'C', 'CLOSE'
            END
            ELSE RETURN 4
        END
    END
RETURN 0

/* Code borrowed from REXX Tips & Tricks v3.60 */
wpsObjectExist: PROCEDURE /* parameter: '<new_wps_object_id>', return: 1 exist, 0 doesn't exist, 43 error */
  PARSE ARG objID
  rc = 43               /* init return/error code 43 = routine not found */
  SIGNAL ON SYNTAX NAME ObjectExistError

  IF SUBSTR( objID, 2, 1 ) <> ":" THEN
      IF LEFT( objID, 1 ) <> "<" & RIGHT( objID, 1 ) <> ">" THEN
          objID = "<" || objID || ">"

  /* create the object and see if it fail */
  tempRC = SysCreateObject( "WPFolder", "TestObject", "<WP_NOWHERE>", "OBJECTID=" || objID || ";", "FAIL" )

  IF tempRC = 1 THEN
  DO
    CALL SysDestroyObject objID
    rc = 0
  END
  ELSE
    rc = 1

ObjectExistError:

RETURN rc

2
Programming / Mac Address in Classic Rexx
« on: September 15, 2019, 07:43:43 am »
This code can list all my machines on the network (and send a wake upp call if they listen).
It doesn't however give me the hostname of the router/dhcp-server. Ideas how to?
 
Code: [Select]
/*
 * Filename: macaddr.cmd
 *   Author: JAN-ERIK
 *  Created: Mon Sep 10 2012
 *  Purpose: Retrieve MAC Address
 *  Changes: 2019-07-25, Added support for Router
 *           2019-09-14, Updated support for localhost
 *           2019-09-15, OS2ENVIRONMENT -> ENVIRONMENT
 */
stem = 'host.'
IF 0 < ARG() THEN
   count = rxGetMacAddr( ARG(1) )
ELSE
   count = rxGetMacAddr()
DO i = 1 TO count
    /*magic.cmd*/
    /*Wake on Lan in REXX*/
    /*MAC = '11:22:33:44:55:66';*/
    MAC = host.i.macaddr
    SAY host.i.name||':' host.i.ipaddr||':' MAC;
    X = TRANSLATE( 'abcdefghijkl', host.i.macaddr, 'ab:cd:ef:gh:ij:kl' )
    call RxFuncAdd 'SockLoadFuncs', 'rxsock', 'SockLoadFuncs';
    call SockLoadFuncs( '*' );
    SCT = SockSocket( 'AF_INET', 'SOCK_DGRAM', 'IPPROTO_UDP' );
    RC = SockSetSockOpt( SCT, 'SOL_SOCKET', 'SO_BROADCAST', '1' );
    RC = SockIOCtl( SCT, 'FIONBIO', '0' );
    adr.!family = 'AF_INET';
    /*adr.!addr   = '255.255.255.255';*/
    adr.!addr   = host.i.ipaddr
    adr.!port   = 9;
    S = COPIES( D2C(255) ,6 );
    T = COPIES( X ,16);
    G = COPIES( D2C(0) ,6 );
    RC = SockConnect( SCT, "adr.!" );
    STG = S||T||G;
    SAY STG
    RC = SockSend( SCT, STG );
    call SockSoClose SCT;
END
RETURN 0

rxGetMacAddr: PROCEDURE EXPOSE (stem) /*<COMPUTERNAME>*/
    isStem = ( RIGHT( stem, 1 )  = '.' )
    stemval = STRIP( stem, 'T', '.' )
    retval = 0
    i = 1
    /* No parameters given, list all computers */
    IF ARG() = 0 THEN
    DO
        DO WHILE QUEUED() > 0; PARSE PULL; END;
        /* Computers on network */
        '@NET VIEW 2>&1|RXQUEUE'
        DO WHILE QUEUED() > 0
            PARSE UPPER VALUE LINEIN( 'QUEUE:' ) WITH '\\'computer.i' '.
            /* Add computer to list */
            IF LENGTH( computer.i ) > 0 THEN i = i + 1
        END
        computer.0 = i - 1
    END
    ELSE DO
        /* Search for a specific computer */
        computer.0 = 1
        computer.1 = TRANSLATE( ARG(1) )
    END
    j = 0
    DO WHILE QUEUED() > 0; PARSE PULL; END;
    DO i = 1 TO computer.0
       IF computer.i = VALUE( 'HOSTNAME',, 'ENVIRONMENT' ) THEN
       DO
          '@NETSTAT -a 2>&1|RXQUEUE'
          DO WHILE QUEUED() > 0
             PARSE UPPER VALUE LINEIN( 'QUEUE:' ) WITH 'ADDR 'ipnum' INTERFACE' .
             ipnum = STRIP( ipnum )
             IF ipnum <> '127.0.0.1' & ipnum <> '0.0.0.0' & ipnum <> '' THEN
                LEAVE
          END
          DO WHILE QUEUED() > 0; PARSE PULL; END;
          '@NETSTAT -n 2>&1|RXQUEUE'
          DO WHILE QUEUED() > 0
             PARSE UPPER VALUE LINEIN( 'QUEUE:' ) WITH 'PHYSICAL ADDRESS' machex 'MTU' .
             machex = STRIP( machex )
             IF machex <> 0 & LENGTH( machex ) = 12 & LENGTH( ipnum ) > 7 THEN
             DO
                j = j + 1
                machex = TRANSLATE( 'ab:cd:ef:gh:ij:kl', machex, 'abcdefghijkl', ':' )
                IF isStem THEN
                   INTERPRET stemval'.j.name = computer.i;'||stemval'.j.macaddr = TRANSLATE( machex, "0", " " );'||stemval'.j.ipaddr = ipnum;'||stemval'.0 = j; retval = j'
                ELSE
                   retval = retval||computer.i||' '||TRANSLATE( machex, "0", " " )||' '||ipnum||D2C(13)||D2C(10)
             END
          END
       END
       ELSE DO
          '@PING '||TRANSLATE( computer.i )||' 1 1 2>&1|RXQUEUE'
          DO WHILE QUEUED() > 0; PARSE PULL; END;
          '@ARP '||TRANSLATE( computer.i )||' 2>&1|RXQUEUE'
          DO WHILE QUEUED() > 0
             PARSE UPPER VALUE SUBWORD( LINEIN( 'QUEUE:' ), 2 ) WITH machex +17 ipnum .
             IF LENGTH( machex ) = 17 & LENGTH( ipnum ) > 7 THEN
             DO
                j = j + 1
                IF isStem THEN
                   INTERPRET stemval'.j.name = computer.i;'||stemval'.j.macaddr = TRANSLATE( machex, "0", " " );'||stemval'.j.ipaddr = ipnum;'||stemval'.0 = j; retval = j'
                ELSE
                   retval = retval||computer.i||' '||TRANSLATE( machex, "0", " " )||' '||ipnum||D2C(13)||D2C(10)
             END
          END
       END
    END
    IF 1 < computer.0 THEN
    DO
        DO WHILE QUEUED() > 0; PARSE PULL; END;
        '@ARP -a 2>&1|RXQUEUE'
        DO WHILE QUEUED() > 0
           arp = LINEIN( 'QUEUE:' )
           IF 0 < POS( ':', arp ) & 3 < WORDS( arp ) THEN
           DO
              PARSE UPPER VALUE arp WITH iface +13 macad +17 ipadd rest
              DO i = 1 To VALUE( stemval'.0' )
                 /* Add computer to list */
                 IF TRANSLATE( macad, "0", " " ) = VALUE( stemval'.i.macaddr' ) THEN LEAVE i
              END
              IF VALUE( stemval'.0' ) < i THEN
              DO
                 IF isStem THEN
                    INTERPRET stemval'.i.name = STRIP( iface );'||stemval'.i.macaddr = TRANSLATE( macad, "0", " " );'||stemval'.i.ipaddr = STRIP( ipadd );'||stemval'.0 = i;retval = i'
                 ELSE
                    retval = retval||STRIP( iface )||' '||TRANSLATE( macad, "0", " " )||' '||ipadd||D2C(13)||D2C(10)
              END
           END
        END
    END
RETURN retval

3
Programming / List path to ObjectID's in plain rexx
« on: September 11, 2019, 10:50:05 pm »
This script take the object ID that point to a program object such as '<WP_CLIPV>' or a folder such as '<MMPM2_FOLDER>' and return path information.
  • It can list the file path to the object, path to the application (for WPProgram) and the path to the object with names as seen visually on the desktop.
  • The code use rexx and rexxutils without the need for wptools.
  • Haven't tried, but it's possible to add information about startup folder and parameters for WPProgram objects.
  • The script cache information during the first call so that consecutive calls return faster.
  • Use fastini to shorten the initial startup delay more.

You may want to optimize/shorten the script  ;)

Code: [Select]
/*
 * Filename: WPSObj.cmd
 *   Author: JanErik
 *  Created: Sat Aug  3 2019
 *  Purpose: Script to list Paths and Object names of Object ID's with rexx
 *  Changes:
 */
CALL rxFuncAdd "SysIni", "REXXUTIL", "SysIni"

objids = 'WP_NOWHERE NOOBJECT WP_CHESS WP_GAMES WP_TOOLS WP_SEEK XWP_FONTFOLDER WP_3DCAD MAH_FOLDER MAH_EXE'
DO i = 1 TO WORDS( objids )
   hID = RxObjIDPath( '<'||SUBWORD( objids, i, 1 )||'>' )
   SAY hID '"'!_PWH_!.hID.appPath'" ->' !_PWH_!.hID.fPath '"'!_PWH_!.hID.fName'"' '<-'||!_PWH_!.hID.isDir||'->' !_PWH_!.hID.oPath '"'!_PWH_!.hID.oName'"'
END
RETURN 0

RxObjIDPath: PROCEDURE EXPOSE !_PWH_!.
   PARSE ARG objID, refresh
   IF \DATATYPE( !_PWH_!.0, 'W' ) | refresh = 1 THEN
   DO
      /* Determine the currently active handles */
      hApp = SysIni( 'SYSTEM', 'PM_Workplace:ActiveHandles', 'HandlesAppName' )
      IF hApp = 'ERROR:' THEN
         hApp = 'PM_Workplace:Handles0'
      block = ''
      CALL SysIni 'SYSTEM', hApp, 'All:', 'blocks.'
      DO i = 1 To blocks.0
         block = block||SysIni( 'SYSTEM', hApp, blocks.i )
      END
      DROP blocks.
      DROP hApp
      !_PWH_!. = ''
      !_count_! = 0
      PARSE VALUE block WITH 5 block
      DO WHILE 0 < LENGTH( block )
         PARSE VALUE block WITH !_name_! 5 block
         SELECT
            WHEN !_name_! = 'DRIV' THEN
               PARSE VALUE block WITH 20 block
            WHEN !_name_! = 'NODE' THEN
            DO
               PARSE VALUE block WITH 3 !_oID_! 5 !_pID_! 7 25 !_isDir_! 27 !_fnSize_! 29 block
               !_oID_! = C2RX( !_oID_! )
               !_PWH_!.!_oID_!.isDir = C2X2D( !_isDir_! )
               !_PWH_!.!_oID_!.fID = C2RX( !_pID_! )
               !_PWH_!.!_oID_!.fPath = ''
               !_fnSize_! = C2X2D( !_fnSize_! )
               !_PWH_!.!_oID_!.fName = LEFT( block, !_fnSize_! )
               !_count_! = !_count_! + 1
               !_PWH_!.0 = !_count_!
               block = SUBSTR( block, !_fnSize_! + 2 )
            END
            OTHERWISE NOP
         END
      END
      IF SysIni( 'USER', 'PM_Abstract:FldrContent', 'All:', 'blocks.' ) <> 'ERROR:' THEN
      DO i = 1 TO blocks.0
         !_children_! = SysIni( 'USER', 'PM_Abstract:FldrContent', blocks.i )
         block = blocks.i
         IF !_PWH_!.block.isDir <> 1 THEN
            !_PWH_!.block.isDir = 1
         DO WHILE 0 < LENGTH( !_children_! )
            PARSE VALUE !_children_! WITH !_child_! 3 5 !_children_!
            !_child_! = C2RX( !_child_! )
            IF !_PWH_!.!_child_!.fID = '' THEN
               !_PWH_!.!_child_!.fID = block
         END
      END
      DROP blocks.
      DROP block
      DROP !_child_!
      DROP !_children_!
   END
   IF 0 < LENGTH( STRIP( objID ) ) THEN
   DO
      !_findID_! = C2RX( LEFT( SysIni( 'USER', 'PM_Workplace:Location', objID ), 2 ) )
      !_PWH_!.!_findID_!.oPath = RxObjPath( !_findID_! )
      RETURN !_findID_!
   END
RETURN 0
   
RxObjPath: PROCEDURE EXPOSE !_PWH_!.
   PARSE ARG findID
   !_path_! = ''
   !_PWH_!.findID.appPath = ''
   PARSE VALUE SysIni( 'USER', 'PM_Abstract:Objects', STRIP( findID, 'L', '0' ) ) WITH . 'WPProgramRef' +19 !_findID_! +2 'WPAbstract' +15 !_objSize_! +2 !_objName_! 'WPObject'
   IF !_findID_! <> '' THEN
   DO
      !_findID_! = C2RX( !_findID_! )
      IF 0 < LENGTH( !_objSize_! ) THEN
         !_PWH_!.findID.oName = LEFT( !_objName_!, C2X2D( !_objSize_! ) - 1 )
      IF !_PWH_!.!_findID_!.isDir <> 1 THEN
      DO
         !_PWH_!.findID.fName = !_PWH_!.findID.oName
         DO WHILE 0 < !_PWH_!.!_findID_!.fID
            !_path_! = '\'||!_PWH_!.!_findID_!.fName||!_path_!
            !_findID_! = !_PWH_!.!_findID_!.fID
         END
         !_path_! = !_PWH_!.!_findID_!.fName||!_path_!
         !_PWH_!.findID.appPath = !_path_!
      END
      !_findID_! = !_PWH_!.findID.fID
   END
   ELSE IF !_PWH_!.!_findID_!.isDir <> 1 THEN
      !_findID_! = !_PWH_!.findID.fID
   ELSE
      !_findID_! = findID
   !_path_! = ''
   DO WHILE 0 < !_PWH_!.!_findID_!.fID
      !_path_! = '\'||!_PWH_!.!_findID_!.fName||!_path_!
      !_findID_! = !_PWH_!.!_findID_!.fID
   END
   !_path_! = !_PWH_!.!_findID_!.fName||!_path_!
   !_PWH_!.findID.fPath = !_path_!
   !_path_! = !_path_!||'\'||!_PWH_!.findID.fName
   !_findID_! = findID
   DO WHILE 0 < !_PWH_!.!_findID_!.fID
      PARSE VALUE REVERSE( !_path_! ) WITH !_name_!'\'!_path_!
      !_name_! = REVERSE( !_name_! )
      !_path_! = REVERSE( !_path_! )
      IF SysGetEA( !_path_!||'\'||!_name_!, '.LONGNAME', 'EAValue' ) = 0 & EAValue <> '' THEN
      DO
         PARSE VAR EAValue EAType +2 EALength +2 EAValue
         IF EAType = 'FDFF'x THEN
            !_PWH_!.!_findID_!.oName = STRIP( EAValue, 'T', '00'x )
      END
      ELSE
         !_PWH_!.!_findID_!.oName = !_name_!
      !_findID_! = !_PWH_!.!_findID_!.fID
   END
   !_path_! = ''
   !_findID_! = !_PWH_!.findID.fID
   DO WHILE 0 < !_PWH_!.!_findID_!.fID
      !_path_! = '\'||!_PWH_!.!_findID_!.oName||!_path_!
      !_findID_! = !_PWH_!.!_findID_!.fID
   END
   !_path_! = !_PWH_!.!_findID_!.fName||!_path_!
RETURN !_path_!

XREV: PROCEDURE
   !_hex_! = STRIP( ARG( 1 ) )
   !_exp_! = ''
   IF \DATATYPE( !_hex_!, 'X' ) THEN RETURN !_exp_!
   DO i = 1 TO LENGTH( !_hex_! ) BY 4
      !_exp_! = STRIP( TRANSLATE( '1234', RIGHT( '0000'||STRIP( SUBSTR( !_hex_!, i, 4 ) ), 4 ), '3412' ) )||!_exp_!
   END
RETURN !_exp_!

C2RX: PROCEDURE
RETURN XREV( C2X( ARG(1) ) )

C2X2D: PROCEDURE
   chrs = ARG(1)
   retval = ''
   DO i = 1 TO LENGTH( chrs ) BY 2
      retval = retval||X2D( C2RX( SUBSTR( chrs, i, 2 ) ) )
   END
RETURN retval

//Jan-Erik

4
Programming / GetLANIPs in Rexx
« on: August 19, 2019, 07:10:45 pm »
This code detect available IP-numbers in the LAN...
Code: [Select]
...
   !_host_!.0 = 0
   CALL RxGetLANIP
   DO !_i_! = 1 TO !_host_!.0
      !_host_!.!_addr = !_host_!.!_i_!.!_addr
      CALL SockGetHostByAddr !_host_!.!_addr, '!_host_!.!_'
      PARSE VALUE RxClamDScan( 'zVERSION' ) WITH ...
... and yes, it's possible to use a rexx only procedure to scan files with a clam server using the newer calling method starting with the letter z.
Code: [Select]
RxGetLANIP: PROCEDURE EXPOSE !_host_!.
   !_lan_! = RXQUEUE( 'Create', 'GETLANIP' )
   CALL RXQUEUE 'Set', !_lan_!
   DO WHILE QUEUED() > 0; PARSE PULL; END;
   '@ping 255.255.255.255 56 1 2>>&1|RXQUEUE '!_lan_!
   !_i_! = 1
   DO WHILE QUEUED() > 0
      PARSE VALUE LINEIN( 'QUEUE:' ) WITH '64' . . !_host_!.!_i_!.!_addr':'.
      !_dot_! = POS( '.', !_host_!.!_i_!.!_addr )
      IF 0 < !_i_! THEN
      DO !_j_! = 2 TO 3
         !_dot_! = POS( '.', !_host_!.!_i_!.!_addr, !_dot_! + 1 )
         IF 0 = !_dot_! THEN !_j_! = 4
      END
      IF 0 < !_dot_! THEN !_i_! = !_i_! + 1
   END
   !_host_!.0 = !_i_! - 1
RETURN

Regards,
//Jan-Erik

5
Programming / OW, JNI (GCC built java 1.6) and parameters
« on: March 28, 2019, 06:20:23 am »
Hello,
I've now looked into how to use java 1.6 and with the help of the answer to the issue I posted quite some time ago, now managed to turn off floating point instructions.
Would appreciate if you can tell me how to also overcome the problem to feed the java code with one or more parameter(s).

LoadLib has been tested to dynamically load and use the dll for SQLite3 and Cairo, both the OW and GCC builds (the gcc builds installed with current ANPM) without recompile in between. The example code I used with SQLite3 and Cairo loaded with parameter "false" as they don't need the floating point fix. :-)
Try with OW as you like, but don't blame me if you run into problems.


Ohh, anyone that would like to help me to write code in vxrexx for this?
A gui to use java in the background etc.

Code: [Select]
#define INCL_DOS
#define INCL_DOSMODULEMGR
#define INCL_DOSMISC
#define INCL_DOSERRORS
#include <os2.h>
#include <stdio.h>
#include <ctype.h>
#include <jni.h>
#include <stdlib.h>
#include <iostream>
#include "LoadLib.hpp"

LoadLib *javm;
ULONG rc;

JNIEnv* create_vm() {
    javm = new LoadLib( "client\\jvm" );//, ".", false ); //when used with sqlite3 and cairo
    if( javm->rc == NO_ERROR ) {
        JavaVM* jvm;
        JNIEnv* env;

        JavaVMOption options[] = {
            { "-Xmx512m", NULL },
            { "-XX:+TraceClassLoading", NULL },//To see the origin of the problem class
            { "-Djava.class.path=.", NULL },  //D:\\Programs\\vxrexx\\projects\\ODBCADMN\\j4o";
            { "-Djava.library.path=.", NULL },// set native library path
            { "-Djava.compiler=NONE", NULL }, // disable JIT
            { "-verbose:gc", NULL },          // print gc messages
            { "-verbose:jni", NULL },         // print JNI-related messages
            { "-verbose:class", NULL }        // print class loading messages
        };

        JavaVMInitArgs args;
        args.version = JNI_VERSION_1_6;
        args.nOptions = sizeof( options ) / sizeof( JavaVMOption );
        args.options = options;
        args.ignoreUnrecognized = JNI_FALSE;

        InitFunc( javm->hmod, jint, JNI_CreateJavaVM, ( JavaVM **p_vm, void **p_env, void *vm_args ) );
        jint jrc = JNI_CreateJavaVM( &jvm, (void**)&env, &args );
//#ifdef __WATCOMC__
        if( jrc != JNI_OK )
            cerr << "Problems loading JVM" << endl;
        else
            cout << "JVM has been loaded sucessfully" << endl;
//#endif
        delete options;
        return env;
    }
    return NULL;
}

void invoke_class( JNIEnv* env ) {
  cout << "invoke class" << endl;

  jclass helloWorldClass;
  jmethodID mainMethod;
  jobjectArray applicationArgs;
  jstring applicationArg0;

  cout << "FindClass HelloWorld" << endl;
  helloWorldClass = env->FindClass( "HelloWorld" );

  cout << "main helloWorld" << endl;
  mainMethod = env->GetStaticMethodID( helloWorldClass, "main", "([Ljava/lang/String;)V" );

  cout << "New Args" << endl;
  applicationArgs = env->NewObjectArray( 1, env->FindClass( "java/lang/String" ), NULL );
  cout << "New UTF String to test parameters" << endl;
  applicationArg0 = env->NewStringUTF( "testparam" );
  cout << "Args" << endl;
  env->SetObjectArrayElement( applicationArgs, 0, applicationArg0 ); //KABOOM! Unless commented out. :-(

  cout << "void main" << endl;
  env->CallStaticVoidMethod( helloWorldClass, mainMethod, applicationArgs);
}

int main( int argc, char **argv ) {
    JNIEnv* env = create_vm();
    if( env )
        invoke_class( env );
    else
        return 1;
  return 0;
}

6
Programming / Capture window that extend beyond the active desktop
« on: August 11, 2018, 08:50:30 am »
Hello,

I've written a .dll to capture and resize images and it work as expected.
I've now created an application that use it, and I consider it finished, but it can draw a window that is larger than the screen/desktop.
The problem is that parts of the window that extend beyond the edge of the desktop doesn't get filled with what the window contain, just a black background.
PMView seem to have a solution for it... to flip between the XPager pages that the window extend to, to capture and assemble the parts.
Isn't there a neater solution?
How can it be done either way?

Jan-Erik

7
Applications / PM app ClamDScan
« on: January 05, 2018, 07:52:37 pm »
It is mulithreaded* and use clamdscan to scan for various threats.

Use clamd on another machine if set up in the clamd.conf file.

Add it to Folder actions (XWP) and you can right click on a folder and scan the whole folder structure.

It tell you what file it has processed (percent and first number) and how many more files this and previous thread that has finished contain* and the total number of files to process in this folder/drive.

ETA: 5h is the Estimated Time of Arrival calculated on the number of files processed and the number of files left to process, not their sizes.

​You can also notice the subtle shine that pass over the progress bar. Add a copy of the DLL in the libpath so it can load and use the progress bar images.

It create a folder on the desktop called "Alert" with the files it find that contain
Malware Trojan Worm Downloader etc.
It attach the Icons it find based on the type name of the threat so one can design ones own icons and place them in the folder next to the executable.

It also add a comment to the file of what type of threat it has detected and set the association type to the same, thus somewhat reduce the ease to double-click-open the file.

*It use multi threading to speed up processing.
It first list files in the current folder and add those so it can start to scan almost right away (if the current folder doesn't contain many files). Then it hand over to up to 5 additional threads (if there are 5 or more sub folders present) to list the files there. As each thread finish, the progress bar and title bar information adjust itself to the information while it scan queued files.

8
Programming / htonl in REXX
« on: December 19, 2017, 07:19:59 pm »
The socket call translates a long integer from host-byte order to network-byte order.

Syntax
htonl( a )

Parameters
a
integer (whole) number to be converted to/from network-byte order (on little endian systems).

Description
htonl(...) call convert an host-byte order integer to internet network-byte order.
htonl(...) call also convert an internet network-byte order integer to host-byte order.

The internet network requires addresses and ports in network standard-byte order.
Use the htonl(...) call to convert the host integer representation of addresses and ports to internet network-byte order.

Returns
The translated integer

Example:
SAY htonl( 16384 )  //4194304
SAY htonl( 4194304 )  //16384

Code:
Code: [Select]
htonl: PROCEDURE
   hex = D2X( ARG( 1 ) )
   exp = ''
   DO i = 1 TO LENGTH( hex ) BY 8
      exp =  STRIP( TRANSLATE( '12345678', RIGHT( STRIP( SUBSTR( hex, i, 8 ) ), 8, '0' ), '78563412' ) )||exp
   END
RETURN X2D( exp )

ClamAV use it for zINSTREAM
Other applications that communicate over the network

Regards,
//Jan-Erik

9
Utilities / problems with sh.exe
« on: June 11, 2017, 10:13:43 pm »
I've successfully installed PostgreSQL in the past.
One has to use initdb.exe and the various executables to create databases, add tables, data and functions etc.
I decided to try once more, but now stumble on messages that sh.exe can't do this and that.
I've tried to rename ash, bash, dash to sh but the problem remain.
What has been changed and why? Fix?

Issue #164
initdb.exe from PostgreSQL apparently use sh.exe internally to initialize a new database structure.

Command line: initdb -E UTF8 -D D:/NLSTeam
Has worked in the past, but not now with installed libraries up to date according to ANPM.

Version: PostgreSQL 8.2.5 b2
Output:
sh.exe: 1: cannot create nul:: Directory nonexistent
fgets failure: No such file or directory
The program "postgres" is needed by initdb but was not found in the
same directory as "D:/Programs/postgres/bin/initdb".
Check your installation.
Couldn't initalize database

Version: PostgreSQL 9.1.7
Output:
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale sv_SE.IBM-850.
could not determine encoding for locale "sv_SE.IBM-850": codeset is "IBM-850"
could not determine encoding for locale "sv_SE.IBM-850": codeset is "IBM-850"
The default text search configuration will be set to "swedish".

creating directory D:/NLSTeam ... ok
creating subdirectories ... ok
selecting default max_connections ... sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
10
selecting default shared_buffers ... sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
sh.exe: 1: cannot open nul:: No such file
sh.exe: 1: D:Programspgsqlbinpostgres.exe: not found
400kB
creating configuration files ... ok
creating template1 database in D:/NLSTeam/base/1 ... sh.exe: 1: D:Programspgsqlb
inpostgres.exe: not found
child process exited with exit code 127
initdb: removing data directory "D:/NLSTeam"
SYS1808:
The process has stopped. The software diagnostic
code (exception code) is 0005.
Couldn't initalize database

10
Applications / JAVA and https not possible
« on: September 04, 2016, 10:11:51 pm »
I'm trying to use java in OpenJDK6 to fetch packages for me, but it refuse since the cacert miss information.
How can I overcome this in OS/2 - eCS?
What do I have to do and how? (Step-by-step)

Code: [Select]
SDK Manager repository: manifest cache cleared.
Refresh Sources:
  Fetching https://dl.google.com/android/repository/addons_list-2.xml
  Failed to fetch URL https://dl.google.com/android/repository/addons_list-2.xml
, reason: peer not authenticated
  Fetched Add-ons List successfully
  Refresh Sources
  Fetching URL: https://dl.google.com/android/repository/repository-11.xml
  Failed to fetch URL https://dl.google.com/android/repository/repository-11.xml
, reason: SSLPeerUnverified peer not authenticated

11
Programming / NetRexx
« on: September 03, 2016, 06:55:20 pm »
I've tried to use NetRexx as it offer you to write
code in (some-kind-of-) Rexx that can be compiled
into JAVA byte code. It's apparently even possible
to use it to write apps for android...

I just had to rewrite the included script to better suit how
OpenJDK 6 in OS/2 work. Please do help me to verify
that the script behave well and handle various scenarios
properly.

You can even drop a folder and it should try to compile all
.nrx-files within (if the resulting command line length
doesn't exceed 1024 characters).

Place "NetRexxKing.png" and "NetRexxKing.ico" in the
NetRexx  folder. Place the script NRxC.cmd in the NetRexx \bin
- folder before you run it and let it create a program object
in the development folder or on the desktop.

Code: [Select]
/* Translate and compile a NetRexx program             */
/*                                                     */
/* use as:  NRxC hello [file2]...                      */
/*                                                     */
/*   which will use the NetRexx translator to          */
/*   translate hello.nrx to hello.java                 */
/*   then will use javac to compile hello.java         */
/*                                                     */
/* OPTIONS keywords may be added (with a -) before or  */
/* after the file specification, along with the extra  */
/* flags known to NetRexxC (such as -keep).   For      */
/* example:                                            */
/*                                                     */
/*    NRxC -keep -format -comments hello               */
/*                                                     */
/* Invoke with no parameters for a full list of flags. */
/*                                                     */
/* To run the class after compilation, specify -run as */
/* an option word.  Each file will be run in turn.     */
/*                                                     */
/*    NRxC -run hello                                  */
/*                                                     */
/* Multiple programs may be specified; in this case    */
/* they are all run (if requested) after all compiles. */
/*                                                     */
/* ----------                                          */
/* 1996.09.02 -- handle Warnings from NetRexxC (rc=1)  */
/* 1996.12.14 -- use COM.ibm.netrexx.process           */
/* 1998.05.25 -- pass NETREXX_JAVA setting to java.exe */
/* 2011.09.01 -- use org.netrexx.process               */
/* 2011.09.01 -- remove -xms4M                         */
/* 2016.08.30 -- Complete rewrite                      */

PARSE UPPER ARG uargs
PARSE ARG args

netrx.run = ( WORDPOS( '-RUN', uargs ) > 0 )
netrx.noc = ( WORDPOS( '-NOCOMPILE', uargs ) > 0 )
IF netrx.run THEN
DO
   PARSE VALUE uargs WITH pre'-RUN'post
   args = LEFT( args, LENGTH( pre ) )RIGHT( args, LENGTH( post ) )
END

PARSE SOURCE system . this
old_dir = DIRECTORY()

SELECT
   WHEN system = 'OS/2' THEN
   DO
      '@ECHO OFF'
      env = 'OS2ENVIRONMENT'

      /* Load RexxUtil Library */
      IF RxFuncQuery('SysLoadFuncs') THEN
      DO
         CALL RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
         CALL SysLoadFuncs
      END
     
      CALL SysGetEA this, 'JAVA_PATH', 'java_path'
      IF LENGTH( java_path ) < 2 THEN DO
         PARSE UPPER VALUE rxFind( 'JAVA.EXE', ' -version', 'VERSION "1.' ) WITH java_path'\BIN'
         IF LENGTH( java_path ) = 0 THEN
         DO
            CALL LINEOUT 'STDERR', 'JAVA engine not found'
            RETURN 1
         END
         CALL SysPutEA this, 'JAVA_PATH', java_path
      END
     
      CALL SysGetEA this, 'NETRX_PATH', 'netrx_path'
      IF LENGTH( netrx_path ) < 2 THEN DO
         PARSE UPPER VALUE rxFind( 'NetRexxC.jar' ) WITH netrx_path'\LIB'
         IF LENGTH( netrx_path ) = 0 THEN
         DO
            CALL LINEOUT 'STDERR', 'NetRexx not found'
            RETURN 2
         END
         CALL SysPutEA this, 'NETRX_PATH', netrx_path
      END
      objID = 'NRXC'
      netrx_name = 'NetRexxKing'
      IF wpsObjectExist( '<WP_'objID'>' ) = 0 THEN
      DO
         setupstring = 'OBJECTID=<WP_'objID'>;EXENAME='this';PARAMETERS=[Type "-run" (without quotes) to run compiled script] %**P\%**F;ASSOCFILTER=*.nrx;ICONFILE='netrx_path'\'netrx_name'.ico;'
         IF SysCreateObject( 'WPProgram', 'NetRexx Compiler / Run', '<WP_DEVFLDR>', setupstring, 'U' ) <> 1 THEN
            CALL SysCreateObject 'WPProgram', 'NetRexx Compiler / Run', '<WP_DESKTOP>', setupstring, 'U'
         CALL rxAddBigIcon netrx_path'\'netrx_name'.png', '<WP_'objID'>'
      END
      IF netrx.noc THEN
         CALL VALUE 'PATH', VALUE( 'PATH',, env )'.;'java_path'\bin;'java_path'\lib;'netrx_path'\runlib', env
      ELSE
         CALL VALUE 'PATH', VALUE( 'PATH',, env )'.;'java_path'\bin;'java_path'\lib;'netrx_path'\lib', env

      DO WHILE QUEUED() > 0
         PARSE PULL
      END
     
      /* Add option -norestart for OS/2s 1.0.2+ java.exe, for better display */
      old_trace = TRACE( 'O' )
      '@JAVA -version 2>&1|RXQUEUE'
      CALL TRACE old_trace
      PARSE PULL '1.' JVer ' '
      PARSE VALUE JVer WITH JVer'_'.
      javaopts = ''
      IF JVer >= 6.0 THEN
         CALL VALUE 'CLASSPATH', netrx_path'\lib\NetRexxF.jar;'netrx_path'\lib\NetRexxC.jar;', env
      ELSE IF JVer >= 0.2 THEN javaopts = '-norestart'
      ELSE javaopts = '-noasyncgc'
     
      /* Add any options from NETREXX_JAVA environment variable */
      javaopts = javaopts VALUE( 'NETREXX_JAVA',, env )
   END
   OTHERWISE
   /* Add any options from NETREXX_JAVA environment variable */
   javaopts = VALUE( 'NETREXX_JAVA',, 'ENVIRONMENT' )
END

CALL rxARGs

'@JAVA -version'
IF netrx.noc THEN
   '@JAVA ' javaopts '-jar 'netrx_path'\lib\NetRexxF.jar -exec' args
ELSE
DO
   CALL LINEOUT 'STDERR', 'Compiling...'
   '@JAVA ' javaopts 'org.netrexx.process.NetRexxC' STRIP( iargs filec )
END   

IF ( rc <= 1 & netrx.run ) | ( netrx.noc & rc <> 0 ) THEN
DO
   CALL rxARGs
   DO WHILE LENGTH( files ) > 0
      PARSE VALUE files WITH f_name'.class' files
      CALL LINEOUT 'STDERR', 'Running' f_name '...'
      '@JAVA 'f_name
      IF rc <> 0 THEN PARSE PULL
   END
END
CALL DIRECTORY old_dir
RETURN rc

rxARGs:
   inargs = args
   iargs = ''
   files = ''
   filec = ''
   DO FOREVER
      PARSE VAR inargs file inargs
      IF file = '' THEN LEAVE
      IF LEFT( file, 1 ) = '-' THEN
      DO
         iargs = iargs file
         ITERATE
      END
      dir = DIRECTORY( file )
      IF POS( '*', file ) > 0 | STREAM( file, 'C', 'QUERY EXISTS' ) <> '' | dir <> ''  THEN
      DO
         IF dir <> '' THEN
            file = file'\*.nrx'
         CALL SysFileTree file, 'filename.', 'FO'
         DO i = 1 TO filename.0
            filec = filec filename.i
            PARSE VALUE REVERSE( filename.i ) WITH ext'.'fname'\'path
            fname = REVERSE( fname )
            IF STREAM( fname'.class','C', 'QUERY EXISTS' ) <> '' THEN
            DO
               files = STRIP( files fname'.class' )
               CALL DIRECTORY path
            END
         END
      END
   END
RETURN

rxChk: PROCEDURE
   DO WHILE QUEUED() > 0; PARSE PULL; END;
   '@'||ARG(1)||ARG(2)||' 2>>&1 | RXQUEUE'
   DO WHILE QUEUED() > 0
      IF POS( TRANSLATE( ARG(3) ), TRANSLATE( LINEIN( 'QUEUE:' ) ) ) > 0 THEN
         IF LENGTH( ARG(4) ) > 0 THEN RETURN ARG(4)
   END
RETURN ''

rxFind: PROCEDURE EXPOSE !_msg_!.
   PARSE VALUE REVERSE( SysSearchPath( 'PATH', ARG(1) ) ) WITH .'\'fpath
   fpath = REVERSE( fpath )
   IF ARG() > 1 & LENGTH( fpath ) > 0 THEN
      fspec = rxChk( fpath'\'ARG(1), ARG(2), ARG(3), fpath )
   ELSE IF STREAM( fpath'\'ARG(1), 'C', 'QUERY EXISTS' ) <> '' THEN
      fspec = fpath
   ELSE fspec = ''
   IF LENGTH( fspec ) > 0 THEN RETURN fspec
   CALL LINEOUT 'STDERR', VALUE( 'PROGRAMS',,'OS2ENVIRONMENT' )
   CALL SysFileTree VALUE( 'PROGRAMS',,'OS2ENVIRONMENT' )||'\*'||ARG(1), 'file.', 'SFO'
   DO i = 1 TO file.0
      PARSE VALUE REVERSE( file.i ) WITH .'\'fspec
      IF ARG() > 1 THEN
         fspec = rxChk( file.i, ARG(2), ARG(3), REVERSE( fspec ) )
      ELSE
         fspec = REVERSE( fspec )
      IF LENGTH( fspec ) > 0 THEN RETURN fspec
   END
   drives = SysDriveMap( 'C:', 'USED' )
   DO j = 1 TO WORDS( drives )
      CALL LINEOUT 'STDERR', SUBWORD( drives, j, 1 )
      CALL SysFileTree SUBWORD( drives, j, 1 )||'\*'||ARG(1), 'file.', 'SFO'
      DO i = 1 TO file.0
         PARSE VALUE REVERSE( file.i ) WITH .'\'fspec
         IF ARG() > 1 THEN
            fspec = rxChk( file.i, ARG(2), ARG(3), REVERSE( fspec ) )
         ELSE
            fspec = REVERSE( fspec )
         IF LENGTH( fspec ) > 0 THEN RETURN fspec
      END
   END
RETURN ''
   
rxAddBigIcon: PROCEDURE EXPOSE !_msg_!. java_path
    crlf = D2C(13)D2C(10)
    bigicons_dir = VALUE( 'BIGICONS',, 'OS2ENVIRONMENT' )
    bigicon = FILESPEC( 'N', ARG(1) )
    objid = ARG(2)
    IF LENGTH( bigicons_dir ) > 0 THEN
    DO
        IF STREAM( ( bigicons_dir'\'bigicon ), 'C','QUERY EXISTS') = '' THEN
           IF SysCopyObject( ARG(1), bigicons_dir ) = 0 THEN
              RETURN 1
        IF STREAM( bigicons_dir'\bigicons.txt', 'C', 'QUERY EXIST' ) <> '' THEN
        DO
            f_size = STREAM( bigicons_dir'\bigicons.txt', 'C', 'QUERY SIZE' )
            IF f_size > 0 THEN
            DO
                input = CHARIN( bigicons_dir'\bigicons.txt', 1, f_size )
                CALL STREAM bigicons_dir'\bigicons.txt', 'C', 'CLOSE'
                PARSE UPPER VALUE input WITH pre'"'(bigicon)'"'post
                IF LENGTH( post ) > 0 THEN RETURN 2
                PARSE UPPER VALUE input WITH pre'"'(objid)'"'post
                IF LENGTH( post ) > 0 THEN RETURN 3
                PARSE VALUE input WITH pre'[OBJECTID]'mid(crlf)(crlf)'['post
                input = pre'[OBJECTID]'STRIP( STRIP( mid, 'T', D2C(10) ), 'T', D2C(13) )||crlf||LEFT( '"'objid'"', 28 )'"'bigicon'"'crlf||crlf'['post
                CALL SysFileDelete bigicons_dir'\bigicons.txt'
                CALL CHAROUT bigicons_dir'\bigicons.txt', input
                CALL STREAM bigicons_dir'\bigicons.txt', 'C', 'CLOSE'
            END
            ELSE RETURN 4
        END
    END
RETURN 0

/* Code borrowed from REXX Tips & Tricks v3.60 */
wpsObjectExist: PROCEDURE /* parameter: '<new_wps_object_id>', return: 1 exist, 0 doesn't exist, 43 error */
  PARSE ARG objID
  rc = 43               /* init return/error code 43 = routine not found */
  SIGNAL ON SYNTAX NAME ObjectExistError

  IF SUBSTR( objID, 2, 1 ) <> ":" THEN
      IF LEFT( objID, 1 ) <> "<" & RIGHT( objID, 1 ) <> ">" THEN
          objID = "<" || objID || ">"

  /* create the object and see if it fail */
  tempRC = SysCreateObject( "WPFolder", "TestObject", "<WP_NOWHERE>", "OBJECTID=" || objID || ";", "FAIL" )

  IF tempRC = 1 THEN
  DO
    CALL SysDestroyObject objID
    rc = 0
  END
  ELSE
    rc = 1

ObjectExistError:

RETURN rc

12
Applications / XWorkplace enhancements
« on: August 04, 2016, 05:50:49 pm »
Hello,

Would like to ask for a feature enhancement to XWorkplace, "large icon support" (such as 32x32 and 40x40 pixels) in XCenter, but can't register nor add it to the new tracker.

Regards
//Jan-Erik Lärka

13
Applications / OpenOffice Base and ODBC
« on: January 10, 2016, 02:32:51 pm »
The read1st.txt state:
Quote
- Base module supports dBase, MySQL, ODBC databases.
  HSQLDB not tested (requires Java).
I've used OpenOffice 3.2 with PostgreSQL 8.x (now 9.x) on eCS but had to patch odbc.dll in unixODBC 0.10.
I can't make it work with Apache OpenOffice 4.1.2 (nor 4.1.1).
I can connect with ODBC

Does Apache OpenOffice need something more/else?

14
Programming / Desktop Weather
« on: September 01, 2015, 08:29:04 pm »
Hello,

I've created a rexx script that should show you the current weather.
It has been designed to be used with PNG Desktop as it update the image (icon) and desktop text to describe the current weather and temperature.

The script download png images from the net and use a Smart Guide to guide you through different possible settings you may tweak.

Please do note that you shouldn't make to drastic changes nor to many images (icon) on the desktop as it should be rewritten to handle such situations better. Stop the script in the startup folder and restart it to update the desktop image icon right away. The program object in the startup folder handle updates and you have to delete it by hand if you want to get rid of the desktop image (icon) as well or it will try to recreate it all over again.  ;)

15
Applications / QT frontend to unixodbc
« on: August 28, 2015, 11:00:32 pm »
Where can one ask if someone can build a QT app?

unixodbc (http://www.unixodbc.org/) has been separated into the "engine" and the "driver manager" where the later use QT4 as gui. The engine has been ported to OS/2 - eCS, but where do we ask for someone to build the qt4 gui for it?

//Jan-Erik

Pages: [1] 2