• Welcome to OS2World OLD-STATIC-BACKUP Forum.
 

News:

This is an old OS2World backup forum for reference only. IT IS READ ONLY!!!

If you need help with OS/2 - eComStation visit http://www.os2world.com/forum

Main Menu
Menu

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.

Show posts Menu

Messages - jep

#31
Hello,

I stay with 9.01 on the main machine though as is stay up... though it show some of the problems found in 10 as well.

A bit "over optimized" as a download can stop or you get logged off even if the (members only) site is open in one (or more) tab(s) but you actively surf another site for a while to find some info.

#32
Quote from: ydario on 2012.03.01, 19:51:22
works for me in that location... and I don't see why it can't work either.
error 2 means that it cannot locate D:\PROGRAMS\OO\ure\bin\sal3.dll; are you sure this file is in the correct place?

you don't need to reinstall, just copy all files to d:\programs\oo

for me it was "C:\Programs\OpenOffice" (note that I edited the last part to leave out the default for a more generic name)
Yes, I tried to deinstall, reinstall, fresh install, install...
before I deisntalled it and installed to C:\PROGRAMS\OpenOffice

//Jan-Erik
#33
Exactly, it's very good that there's a rpm/yum engine for installation that now can handle all *nix applications in a convenient way for the eCS platform that also can provide developers with a useful tool to pack files for installation.

Should eCS rely on several installers? ok.
How do you feel about several installer back end engines and one gui?

//Jan-Erik
#34
Hello,

From a user point of view I'm mostly interested in that it's easy to use and allow me to be in charge, how it does it behind the curtain is not that interesting. Do we have to have x number of installers, can't we get one that does the work and therefore keep track of things and coordinate it right?

It would be nice if it's an eCS aware procedure that handle eCS-applications and wps/som/rexx etc. and reuse parts of the knowledge aquired from the work with WarpIn. I'd prefer if it's an integrated part of the wps that install applications. Please do note that rexx is a part of eComStation, as well and the scripting language in eComStation.

Some demand that apperance of everything should be "sparse", other that things has to be done to improve visiblity, apperance and info.
There's no conflict between the two, but more info doesn't mean differently bright colored buttons and random flashing animations.

//Jan-Erik
#35
Hello,

Had exaclty the same problem...
I placed the HOME and the Programs folders on D: but OpenOffice didn't start after I tried to install it to D:\Programs.

Solution:
Install it to C:

e.g. C:\Programs\OpenOffice... that is.

//Jan-Erik
#36
Rexx / Re: Database engine written in rexx
2012.01.04, 12:42:57
Hello,

please do post it... the sooner the better.

Had to rewrite the rexx code myself compared to the one posted here as I found various aspects that would cause problems. ) ' & , etc. in filenames cause problems, also added possibility to output data to file out of a SELECT-string and thus create a new database.

Accidentally (quick) formatted the wrong drive (out of two identical ones) and Jan van Wijk has helped me to recover the files (See DFSee v11.0) and it can use the stored info .LONGNAME EA (Extended Attributes) that some of my other scripts set. The problem is/was that those doesn't contain path information. So I have to find out where those file was placed before with info stored in PostgreSQL databases on the same drive. I've written scripts that extract data and now try to merge the info into .rxdb files.


Quote from: RobertM on 2011.12.30, 00:18:40
I have some Rexx code written for RxSQL that simplifies a bunch of the calls... I can put it together into a zipfile or something if you think it might help you.

Basically (as one example), inserting a row (or multiple ones) requires one call: all connect, pointer, command prep, execute, drop pointer, close connection stuff is handled by the Rx_SQL_Insert Rexx function I wrote. Same goes for most of the other command sets generally used (update, delete, create, general command passing, etc).

//Jan-Erik
#37
Rexx / Re: Call another script
2012.01.04, 12:27:27
Thank you RobertM for the explenation.
I was thinking about it like a "plugin" one could load and use.
Quote from: RobertM on 2011.12.29, 21:35:35
And to Jep, where were you 10 years ago when I was first learning how to use Macrospace?!?!?!  ;)  ;D  :P
I started to try it out the day before XMAs, so you're about 10 years ahead of me :D

//Jan-Erik
#38
Rexx / Call another script
2011.12.24, 12:20:51
Hello,

This script use another script (see "Database engine written in rexx") through the use of SysAddRexxMacro available in Rexxutil that come with Object Rexx and is included with eComstation.
Please note that cut and paste may not work reliably for certain special characters, so please ensure to double check the code before usage.

This script also contain some functions you may want to try somewhere else.
rxProgress can handle up to 6 values for progress at once.
It can be quite handy if you want to show how large each processing step is and how much of that has been handled.
It only update the progress bar every second even though you may call it more often.

Notice the use of RIGHT( STREAM( file.i, 'C', 'QUERY SIZE' ), 10 ) to be able to order output according to numeric file size with SELECT ... ORDER BY FILESIZE in rxdb.cmd (see "Database engine written in rexx").

/*
* Filename: add2db.cmd
*   Author: JAN-ERIK
*  Created: Sat Dec 24 2011
*  Purpose: Script that use another script to add data to database (csv-like)
*  Changes:
*/

/* Load RexxUtil Library */
If RxFuncQuery('SysLoadFuncs') Then
Do
    Call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
    Call SysLoadFuncs
End

CALL SysCls
SAY ''
SAY ''
SAY ''
If RxFuncQuery('SysAddRexxMacro') Then
    RETURN 1

retval = SysAddRexxMacro( 'rxSQL','rxdb.cmd', 'B' )
IF ARG() = 0 THEN
DO
CALL CHAROUT , 'Specify drive to list and add to database: '
PARSE PULL answer
END
ELSE answer = ARG(1)

IF rxProcess( LEFT( answer, 1 )||':' ) THEN
    Call rxProgress 2, 1
RETURN 0

rxProcess: PROCEDURE EXPOSE  __meter.
    PARSE ARG path, progress, chunk
    IF progress = '' THEN progress = 0
    IF chunk = '' THEN chunk = 1
    rc = SysFileTree( path||'\*.*', 'folder', 'DO' )
    rc = SysFileTree( path||'\*.*', 'file', 'FO' )
    DO i = 1 TO file.0
        CALL rxBusy 1, file.i
        CALL rxProgress 2, progress + ( i - 1 ) / ( file.0 + folder.0 ) * chunk
        CALL rxSQL "INSERT INTO files (COMPUTER,PATH,NAME,DRIVE,FILESIZE) VALUES ('"||VALUE( 'HOSTNAME',, 'OS2ENVIRONMENT' )||"','"||FILESPEC( 'P', file.i )||"','"||FILESPEC( 'N', file.i )||"','"||FILESPEC( 'D', file.i )||"','"||RIGHT( STREAM( file.i, 'C', 'QUERY SIZE' ), 10 )||"')"
    END
    DO i = 1 TO folder.0
        CALL rxBusy 1, folder.i
        Call rxProgress 2, progress + ( i + file.0 - 1 ) / ( file.0 + folder.0 ) * chunk
        CALL rxProcess folder.i, progress + ( i + file.0 - 1 ) / ( file.0 + folder.0 ) * chunk, chunk / ( file.0 + folder.0 )
    END
RETURN 1

/* display_on_row, part  */
rxProgress: PROCEDURE EXPOSE  __meter.
/*    IF TRACE() <> 'O' THEN RETURN 0*/
    row = ARG(1)
    chr = '█▓▒░■█ '
    IF \DATATYPE( __meter.width, 'W' ) THEN
        PARSE VALUE SysTextScreenSize() WITH . __meter.width
    DO i = 2 TO MIN( ARG(), LENGTH( chr ) )
        j = i - 1
        IF \DATATYPE( ARG(i), 'N' ) THEN RETURN 0
        progress.j = FORMAT( ARG(i),,, 0 )
        IF LENGTH( FORMAT( 100 * progress.j,, 0, 0 ) ) > 3 THEN
            RETURN 0
    END
    progress.0 = j
    processed.0 = 0
    output = ''
    CALL SysStemSort 'progress'
    DO i = 1 TO MIN( progress.0, LENGTH( chr ) )
        j = i - 1
        processed.i = FORMAT( MIN( ( __meter.width - 4 ) * progress.i , __meter.width - 4 ),, 0, 0 )
        progress.i = FORMAT( 100 * progress.i, 3, 0, 0 )
       
        IF processed.i > processed.j THEN
            output = output||COPIES( SUBSTR( chr, i, 1 ), processed.i - processed.j )
    END
    i = i - 1
    output = output||COPIES( SUBSTR( chr, LENGTH( chr ), 1 ), __meter.width - 4 - processed.i )
    CALL rxOut ARG(1), output||RIGHT( progress.1||'%', 4 )
RETURN 0

/* display_on_row, text  */
rxBusy: PROCEDURE EXPOSE __meter.
/*    IF TRACE() <> 'O' THEN RETURN 0*/
    PARSE ARG row, txt   
    IF \DATATYPE( __meter.row.t_stamp , 'N' ) THEN
        __meter.row.t_stamp = TIME( 'S' )
    IF __meter.row.t_stamp + 1 < TIME( 'S' ) THEN
    DO
        SELECT
            WHEN __meter.counter = 1 THEN
                CALL rxOut row, '/ '||txt
            WHEN __meter.counter = 2 THEN
                CALL rxOut row, '- '||txt
            WHEN __meter.counter = 3  THEN
                CALL rxOut row, '\ '||txt
            OTHERWISE
            __meter.counter = 0
            CALL rxOut row, '| '||txt
        END
        __meter.counter = __meter.counter + 1
    END
RETURN 0

/* display_on_row, text  */
rxOut: PROCEDURE EXPOSE __meter.
/*    IF TRACE() <> 'O' THEN RETURN 0*/
    PARSE ARG row, txt
    IF \DATATYPE( __meter.row.t_stamp, 'W' ) THEN
        PARSE VALUE SysTextScreenSize() WITH . __meter.width
    isNum = DATATYPE( row, 'W' )
    IF isNum THEN
    DO
        IF DATATYPE( __meter.row.t_stamp, 'W' ) THEN
            IF __meter.row.t_stamp + 1 > TIME( 'S' ) THEN RETURN 0
        PARSE VALUE SysCurPos( row, 0 ) with prev_row prev_col
    END
    ELSE IF DATATYPE( __meter.row.t_stamp, 'W' ) THEN
        IF __meter.row.t_stamp + 1 > TIME( 'S' ) THEN RETURN 0
    SAY LEFT( txt, MAX( __meter.width, MIN( LENGTH( ARG(2) ), __meter.width ) ) )
    IF isNum THEN
    DO
        CALL SysCurPos prev_row, prev_col
        __meter.row.t_stamp = TIME( 'S' )
    END
    ELSE
        __meter.row.t_stamp = TIME( 'S' )
RETURN 0


Merry XMas from Sweden
//Jan-Erik
#39
Rexx / Database engine written in rexx
2011.12.24, 12:02:42
Hello,

I'm working quite alot with databases these days and therefore came up with the idea to write one on my own  ;)
So here's my initial version, that support group and sort* with the help of SysStemSort (available in the Object Rexx version of rexxutil included with eComStation)
Please feel free to try it out.

There are hand made functions at the end of the script that may be handy to use elsewhere as well.

Usage:
  Example for table "files" with some columns related to file info

  CREATE TABLE files COLUMNS (COMPUTER,DRIVE,PATH,NAME,FILESIZE,CRC32,MODIFIED)
  INSERT INTO files (DRIVE,PATH,NAME) VALUES ('J:','\Temp\','MyFile.txt')
  UPDATE files SET COMPUTER = 'eComStation PC' WHERE PATH = '\Temp\'
  SELECT * FROM files WHERE DRIVE = 'J:' GROUP BY COMPUTER ORDER BY PATH
  DELETE FROM files WHERE COMPUTER != 'eComStation PC'
  VACUUM TABLE files WHERE DRIVE != 'J:'


Notice!
The engine doesn't care about
duplicate data (so you may add the same info several times)
primary keys
or
relations between tables


You can leave out columns in SELECT and INSERT INTO ... and add them unorderd, the "engine" will take care of how to match the entered data to the table layout on disk, just as other database engines do.
  INSERT INTO files (PATH,DRIVE,NAME) VALUES ('\Temp\','J:','MyFile.txt')
and
  INSERT INTO files (DRIVE,PATH,NAME) VALUES ('J:','\Temp\','MyFile.txt')
in the example will both be saved to the table created by
  CREATE TABLE files COLUMNS (COMPUTER,DRIVE,PATH,NAME,FILESIZE,CRC32,MODIFIED)
as
"","J:","\Temp\","MyFile.txt","","",""


The engine contain code to handle strings that contain ' and , that would otherwise cause problems.
You may want to use != to exclude data:
rxdb SELECT * FROM files WHERE DRIVE != 'C:'
to exclude entries that contain C: in the column DRIVE as you can't use <> on the command line.


*SysStemSort sort data according to each characters ascii value.
Therefore, add numeric data formatted/padded with space or zeros in front if you want to sort by something like FILESIZE.
Example (non padding):
0
16
168
5
54
75
91
99
Example (space):
   0
   5
 16
 54
 75
 91
 99
168
which can be achieved with RIGHT( mynumber, 3 ) for numbers up to 999
/*
* Filename: rxdb.cmd
*   Author: JAN-ERIK LĂ„RKA
*  Created: Sat Dec 24 2011
*  Purpose: Database engine entirly written in REXX
*  Changes:
*/

/* Don't echo commands */
'@ECHO OFF'

/* place argument in variable */
sqlstr.input = ARG(1)

/* Add procedures to handle problems */
SIGNAL ON ERROR NAME SignalError
SIGNAL ON FAILURE NAME SignalFailure
SIGNAL ON HALT NAME SignalHalt
SIGNAL ON NOVALUE NAME SignalNoValue
SIGNAL ON SYNTAX NAME SignalSyntax
SIGNAL ON NOTREADY NAME SignalNotReady

/* Load RexxUtil Library */
IF RxFuncQuery('SysLoadFuncs') THEN
Do
   CALL RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
   CALL SysLoadFuncs
END
values = ''
columns = ''

/* An array with supported arguments */
sqlstr.1 = "'SELECT 'columns' FROM 'table' 'rest"
sqlstr.2 = "'INSERT INTO 'table' ('columns') VALUES ('rest"
sqlstr.3 = "'UPDATE 'table' SET 'rest"
sqlstr.4 = "'DELETE FROM 'table' 'rest"
sqlstr.5 = "'CREATE TABLE 'table' COLUMNS ('columns')'rest"
sqlstr.6 = "'VACUUM TABLE 'table' 'rest"
sqlstr.0 = 6

/* Check to see what argument has been entered */
DO sqlcase = 1 TO sqlstr.0
   IF WORD( sqlstr.input, 1 ) = STRIP( WORD( sqlstr.sqlcase, 1 ),, "'" ) THEN
   DO
       INTERPRET 'PARSE VALUE sqlstr.input WITH '||sqlstr.sqlcase
       /* Fix to handle the case where data may contain ) that would cause problems */
       IF sqlcase = 2 THEN
       DO
           values = WRDS( rest, ',', COUNTSTR( ',', columns ), ')' )
           rest = SUBSTR( rest, LENGTH( values ) + 2 )
       END
       LEAVE sqlcase
   END
END
/*  Show usage if argument didn't match those supported */
IF sqlcase > sqlstr.0 THEN SIGNAL VALUE "USAGE"

/* Create an array for the names of the trailing parameters */
sqlstr.1.1 = 'table'
sqlstr.1.2 = ''
sqlstr.1.3 = 'columns'
sqlstr.1.4 = 'table'
sqlstr.1.5 = ''
sqlstr.1.6 = 'table'

/* Create arrays for the optional additional arguments */
sqlvar.2 = 'conditions'
sqlvar.3 = 'group'
sqlvar.4 = 'order'
sqlvar.5 = '.'

sqlclause.2 = 'WHERE'
sqlclause.3 = 'GROUP BY'
sqlclause.4 = 'ORDER BY'
sqlclause.5 = 'DESC'
sqlclause.0 = 5

/* Check if the last word is DESC or D and modify sort order from the default Ascending */
IF SUBWRDS( rest, ',', -1 ) = 'DESC'  THEN
   sort = '"D"'
ELSE
   sort = ''

/* Check the optional arguments */
i = 1
DO j = sqlclause.0 TO 2 BY -1
   IF j > 1 & j < 5 THEN INTERPRET sqlvar.j' = ""'
   IF POS( sqlclause.j, rest ) > 0 THEN
   DO
       INTERPRET 'PARSE VALUE rest WITH rest "'||sqlclause.j||'" '||sqlvar.j
       IF sqlvar.j <> '.' THEN
           INTERPRET sqlvar.j||' = STRIP( VALUE( "'||sqlvar.j||'" ) )'
   END
END
/* Name the trailing parameters */
IF LENGTH( STRIP( rest ) ) > 0 THEN
   INTERPRET 'PARSE VALUE rest WITH '||sqlstr.1.sqlcase||';IF '||sqlstr.1.sqlcase||' <> "" THEN '||sqlstr.1.sqlcase||' = STRIP( VALUE( "'||sqlstr.1.sqlcase||'" ) )'

/* Combine groups and order as both specify how to order data */
IF ( LENGTH( STRIP( order ) ) > 0 ) THEN
DO
   order = order||','
   IF ( LENGTH( STRIP( group ) ) > 0 ) THEN
       order = ','||order
END
ELSE IF ( LENGTH( STRIP( group ) ) > 0 ) THEN
       group = group||','
group = STRIP( CHANGESTR( ',', group||order, '","' ), 'T', '"' )

/* Set file name extension of table */
table = table||'.rxdb'

/* Check if the table has been created */
IF STREAM( table, 'C', 'QUERY EXISTS' ) <> '' THEN
DO

   columns = STRIP( CHANGESTR( '"', columns, '' ) )
   colnames = LINEIN( table )
   cols = COUNTSTR( ',', colnames ) + 1
   
   IF sqlcase = 1 THEN /* SELECT FROM ... */
   DO
       parse_columns = CHANGESTR( "'", CHANGESTR( '"', colnames, '' ), '' )
       columns = CHANGESTR( '*', CHANGESTR( ',', columns, '","' ), colnames )
       select_direct = ( LENGTH( group ) = 0 )
       
       /* Modify condition(s) to look at the right "column" */
       DO j = 1 TO cols
           PARSE VALUE parse_columns WITH colname','parse_columns
           conditions = CHANGESTR( colname, conditions, 'STRIP( SUBWRD( input, '||j||', '||"'"||'","'||"'"||' ),, '||"'"||'"'||"' )" )
       END
       /* Modify the != command line argument to <> (One doesn't work on the command line while the other can't be interpreted) :-/ */
       conditions = CHANGESTR( '!=', conditions, '<>' )
       count = 0
       grps = COUNTSTR( ',', group )
       
       /* Go through each line in the database */
       DO WHILE LINES( table ) > 0
           input = LINEIN( table )
           IF LEFT( input, 1 ) = '*' | LENGTH( input ) = 0 THEN ITERATE
           IF LENGTH( conditions ) > 0 THEN
               INTERPRET 'result = ('||conditions||')'
           ELSE result = 1
           /* Does the condition match?! */
           IF result THEN
           DO
               count = count + 1
               INTERPRET 'PARSE VALUE input WITH '||STRIP( colnames,, '"' )||';sqlstr.count = '||STRIP( group||columns,, '"' )
               IF select_direct THEN SAY sqlstr.count
           END
       END
       /* We need go through this as well if the data has to be sorted */
       IF \select_direct THEN
       DO
           sqlstr.0 = count
           IF sqlstr.0 > 0 & LENGTH( order ) > 0 THEN
               Call SysStemSort 'sqlstr.', sort
           DO count = 1 TO sqlstr.0
               SAY SUBWRDS( sqlstr.count, ',', grps )
           END
       END
       CALL STREAM table, 'C', 'CLOSE'
   END
   ELSE IF sqlcase = 2 THEN /* INSERT INTO... */
   DO
       /* Set up the arguments with the right style */
       columns = CHANGESTR( '*', CHANGESTR( ',', columns, '","' ), colnames )
       /* Empty all variables (column names) to recieve data */
       INTERPRET 'PARSE VALUE "" WITH '||STRIP( colnames,, '"' )
       /* Special handling for ' and , that are crutial parts of the database file format */
       INTERPRET 'PARSE VALUE "'||CHANGESTR( D2C(1), CHANGESTR( ",", CHANGESTR( "'", STRIP( CHANGESTR( "','", values, D2C(1) ),, "'" ), D2C(2) ), D2C(3) ), ',' )||'" WITH '||columns||';temp = '||STRIP( colnames,, '"' )
       CALL STREAM table, 'C', 'SEEK <0'
       /* Write the added data to the database table file */
       CALL LINEOUT table, '"'||CHANGESTR( D2C(3), CHANGESTR( ',', CHANGESTR( D2C(2), temp, "'" ), '","' ), ',' )||'"'
       CALL STREAM table, 'C', 'CLOSE'
   END
   ELSE IF sqlcase = 3 | sqlcase = 4 THEN /* UPDATE ... and DELETE FORM ... */
   DO
       IF sqlcase = 3 THEN /* UPDATE ... */
       DO
           parse_columns = columns
           /* Replace with the input that point to a column name */
           DO k = 1 TO cols
               PARSE VALUE parse_columns WITH col'='val','parse_columns
               col = STRIP( col )
               val = STRIP( val )
               columns = CHANGESTR( col'='val, columns, 'input = CHANGEWRD( input, '||j||', ",", '||"'"||'"'||"'"||val||"'"||'"'||"'"||' )' )
           END
       END
       /* Go through the database table */
       DO WHILE LINES( table ) > 0
           input = LINEIN( table )
           IF LEFT( input, 1 ) = '*' | LENGTH( input ) = 0 THEN ITERATE
           IF LENGTH( conditions ) > 0 THEN            
               INTERPRET 'result = ('||conditions||')'
           ELSE result = 1
           /* Mark each matching entry as deleted */
           IF result THEN
           DO
               strpos = STREAM( table, 'C', 'SEEK -'||( LENGTH( input ) + 2 ) )
               CALL LINEOUT table, '*'||SUBSTR( input, 2 )
               /* Add the modified version last for UPDATE ... */
               IF i = 3 THEN /* UPDATE ... */
               DO
                   CALL STREAM table, 'C', 'SEEK <0'
                   INTERPRET columns
                   CALL LINEOUT table, input
                   CALL STREAM table, 'C', 'SEEK ='||( strpos + LENGTH( input ) )
               END
           END
       END
       CALL STREAM table, 'C', 'CLOSE'
       RETURN 0
   END
   ELSE IF sqlcase = 6 THEN /* VACUUM TABLE ... */
   DO
       /* Write the table names to a new temporary database table file */
       CALL LINEOUT table||'_tmp', colnames
       /* Write each non-deleted row the new temporary database table file */
       DO WHILE LINES( table ) > 0
           input = LINEIN( table )
           IF LEFT( input, 1 ) = '*' THEN ITERATE
           CALL LINEOUT table||'_tmp', input
       END
       CALL STREAM table||'_tmp', 'C', 'CLOSE'
       CALL STREAM table, 'C', 'CLOSE'
       /* Write all row back to the new database table file */
       IF SysFileDelete( table ) = 0 THEN
       DO WHILE LINES( table||'_tmp' ) > 0
           CALL LINEOUT table, LINEIN( table||'_tmp' )
       END
       CALL STREAM table||'_tmp', 'C', 'CLOSE'
       CALL STREAM table, 'C', 'CLOSE'
       CALL SysFileDelete table||'_tmp'
   END
   ELSE SIGNAL VALUE "TABLEALREADYEXISTS"
END
ELSE IF sqlcase = 5 THEN /* CREATE TABLE ... */
DO
   /* Create a file if not found */
   CALL LINEOUT table, '"'||CHANGESTR( ',', STRIP( columns,, '"' ), '","' )||'"'
   CALL STREAM table, 'C', 'CLOSE'
END
ELSE SIGNAL VALUE "TABLENOTFOUND"
RETURN 0

TableAlreadyExists:
   CALL LINEOUT 'STDERR', '[REXX SQL Engine] Table already exists, please specify a new table name or use the existing.'
   SAY ''
   CALL Usage
RETURN 7


TableNotFound:
   CALL LINEOUT 'STDERR', '[REXX SQL Engine] Table not found, create the table first'
   CALL LINEOUT 'STDERR', ''
   CALL Usage
RETURN 7

Usage:
   CALL LINEOUT 'STDERR', 'Usage:'
   CALL LINEOUT 'STDERR', '   Example for table "files" with some columns related to file info'
   CALL LINEOUT 'STDERR', ''
   CALL LINEOUT 'STDERR', '   CREATE TABLE files COLUMNS (COMPUTER,DRIVE,PATH,NAME,FILESIZE,CRC32,MODIFIED)'
   CALL LINEOUT 'STDERR', "   INSERT INTO files (DRIVE,PATH,NAME) VALUES ('J:','\Temp\','MyFile.txt')"
   CALL LINEOUT 'STDERR', "   UPDATE files SET COMPUTER = 'eComStation PC' WHERE PATH = '\Temp\'"
   CALL LINEOUT 'STDERR', "   SELECT * FROM files WHERE DRIVE = 'J:' GROUP BY COMPUTER ORDER BY PATH"
   CALL LINEOUT 'STDERR', "   DELETE FROM files WHERE COMPUTER != 'eComStation PC'"
   CALL LINEOUT 'STDERR', "   VACUUM TABLE files WHERE DRIVE != 'J:'"
   CALL LINEOUT 'STDERR', ''
RETURN 0
   
SignalError:
   SIGNAL OFF ERROR
   CALL LINEOUT 'STDERR', '[REXX SQL Engine] Error: Error processing command.'
   CALL LINEOUT 'STDERR', ''
RETURN 1
   
SignalHalt:
   SIGNAL OFF HALT
   CALL LINEOUT 'STDERR', '[REXX SQL Engine] Halt: Execution of the command has stopped.'
   CALL LINEOUT 'STDERR', ''
RETURN 2
   
SignalSyntax:
   SIGNAL OFF SYNTAX
   CALL LINEOUT 'STDERR', '[REXX SQL Engine] Syntax: The syntax of the command is incorrect.'
   CALL LINEOUT 'STDERR', ''
   CALL LINEOUT 'STDERR', ARG(1)||D2C(13)||D2C(10)||D2C(13)||D2C(10)||'should be on the form: '||SPACE( STRIP( TRANSLATE( sqlstr.sqlcase,, "'" ) ), 1 )||D2C(13)||D2C(10)||D2C(13)||D2C(10)||'where "rest" can be combined (in specified order) with:'
   DO i = 2 TO sqlclause.0 - 1
       CALL LINEOUT 'STDERR', sqlclause.i||' '||sqlvar.i
   END
   CALL LINEOUT 'STDERR', sqlclause.i||'     (to sort in descending order)'
   CALL LINEOUT 'STDERR', ''
   CALL STREAM table, 'C', 'CLOSE'
RETURN 3
   
SignalFailure:
   SIGNAL OFF FAILURE
   CALL LINEOUT 'STDERR', '[REXX SQL Engine] Failure: The system could not process the command.'
   CALL LINEOUT 'STDERR', ''    
RETURN 4
   
SignalNoValue:
   SIGNAL OFF NOVALUE
   CALL LINEOUT 'STDERR', "[REXX SQL Engine] NoValue: The variable "||CONDITION( 'D' )||" doesn't contain data."
   CALL LINEOUT 'STDERR', ''
   CALL Usage
RETURN 5
   
SignalNotReady:
   SIGNAL OFF NOTREADY
   CALL LINEOUT 'STDERR', '[REXX SQL Engine] Not Ready: Could not process the command.'
   CALL LINEOUT 'STDERR', ''
RETURN 6
   
/* Change word number x in haystack, delimited by "delimiter" to new word */    
CHANGEWRD: PROCEDURE /* haystack, wrdpos, <delimiter>, newwrd */
   PARSE ARG haystack, wrdpos, delimiter, newwrd
   IF delimiter = '' THEN delimiter = ' '
   retval = ''
   DO i = 2 TO wrdpos
       PARSE VALUE haystack WITH pre(delimiter)haystack
       retval = retval||pre||delimiter
   END
   PARSE VALUE haystack WITH pre(delimiter)haystack
RETURN retval||newwrd||delimiter||haystack
   
/* Count occurances of delimiter after the first occurance of needle */
WRDPOS: PROCEDURE /* needle, haystack<, delimiter> */
   PARSE ARG needle, haystack, delimiter
   IF POS( needle, haystack ) = 0 THEN RETURN 0
   PARSE VALUE haystack WITH pre(needle)post
   IF delimiter = '' THEN delimiter = ' '
RETURN COUNTSTR( delimiter, pre ) + 1

/* N:th word in haystack delimited by delimiter (space by delfault) */
SUBWRD: PROCEDURE /* haystack, wrdpos<, delimiter> */
   PARSE ARG haystack, wrdpos, delimiter
   IF delimiter = '' THEN delimiter = ' '
   DO i = 2 TO wrdpos
       PARSE VALUE haystack WITH .(delimiter)haystack
   END
   PARSE VALUE haystack WITH haystack(delimiter).
RETURN haystack
   
/* Number of word in haystack delimited by delimiter (space by delfault) starting at start word */
SUBWRDS: PROCEDURE /* haystack, delimiter<, start_wrd<, wrds>> */
   PARSE ARG haystack, delimiter, start_wrd, wrds
   start_pos = 0
   end_pos = 0
   IF start_wrd = '' THEN start_wrd = 1
   IF start_wrd = -1 THEN
       start_pos = LASTPOS( delimiter, haystack )
   ELSE IF start_wrd = 0 THEN
       start_pos = 1
   ELSE DO
       DO i = 1 TO start_wrd
           start_pos = POS( delimiter, haystack, start_pos + 1 )
           IF start_pos = 0 THEN RETURN ''
       END
   END
   IF DATATYPE( wrds, 'W' ) THEN
   DO
       end_pos = start_pos
       DO i = 1 TO wrds
           end_pos = POS( delimiter, haystack, end_pos + 1 )
           IF end_pos = 0 THEN LEAVE i
       END
   END
   IF start_pos > 0 THEN
   DO
       IF end_pos < 1 | wrds = '' | start_wrd < 0 THEN end_pos = LENGTH( haystack )
       haystack = SUBSTR( haystack, start_pos + 1, end_pos - start_pos - 1 )
   END
   ELSE RETURN ''
RETURN haystack
   
/* Up to characters in text (haystack) after the N:th number of occurances of delimiter */
WRDS: PROCEDURE /* haystack<, delimiter<, wrdpos<, tochar>>> */
   PARSE ARG haystack, delimiter, wrdpos, tochar
   IF delimiter = '' THEN delimiter = ' '
   IF wrdpos = '' THEN wrdpos = COUNTSTR( delimiter, haystack )
   strpos = POS( tochar, haystack, LENGTH( SUBWRDS( haystack, delimiter, 0, wrdpos ) ) + 1 ) - 1
   IF strpos > 0 THEN
       RETURN SUBSTR( haystack, 1, strpos )
RETURN haystack
   
/* Replace one string (needle) with another (newneedle) in text (haystack) */
CHANGESTR: PROCEDURE /* needle, haystack <, newneedle> */
   PARSE ARG needle, haystack, newneedle
   new_haystack = ''
   DO WHILE POS( needle, haystack ) > 0
       PARSE VALUE haystack WITH pre(needle)haystack
       new_haystack = new_haystack||pre||newneedle
   END
RETURN new_haystack||haystack

/* Count the number of occurances of needle in haystack from start pos to end pos (whole string by default) */
COUNTSTR: PROCEDURE /* needle, haystack< <, startpos>, endpos> */
   IF ARG() < 2 THEN RETURN -1
   IF DATATYPE( ARG(3), 'W' ) THEN
       next = ARG(3)
   ELSE
       next = 1
   needle = ARG(1)
   haystack = ARG(2)
   IF DATATYPE( ARG(4), 'W' ) THEN
       haystack = SUBSTR( haystack, next, ABS( ARG(4) - next ) )
   next = 1
   count = 0
   DO WHILE next > 0
       next = POS( needle, haystack, next )
       IF next > 0 THEN DO
           next = next + LENGTH( needle )
           count = count + 1
       END
   END
RETURN count


Merry XMas from Sweden
//Jan-Erik
#40
Hello,


Thank you for the links RobertM, I've been looking for links how and what to do to get JetDirect to be able to find my network HP printer. Hope to have the time during XMas to look at it. :)

//Jan-Erik
#41
Networking / Re: ftp passive mode?
2011.12.15, 14:37:48
NetDrive come with FTP and support for passive mode.
The nice thing is that it appear as a network drive.  :)

//Jan-Erik
#42
Rexx / Re: Firefox D&D install !!!
2011.12.06, 17:11:39
Quote from: sXwamp on 2011.12.06, 14:01:25
Thanks Robert and Jep,

This code above from Robert and modified code from Jep only deletes one file and ends.  I added a loop around the code to test it to see what happens. Both deletes all the files, but the last three files left are:

I can't see any additional loop? But the required addition by you is there
fDir ='Z:\Unzip\firefox-8.0.1.en-US.os2\firefox'

Quote from: sXwamp on 2011.12.06, 14:01:25
application.ini
blocklist.xml
chrome.manifest

Any tips or ideas what I'm going wrong ???
Do any of these files have the read only flag set (settings notebook)?!
If so, then you'll have to use e.g.
'attrib "'||filelist.A||' -r -a -s -h'

Another possible problem may be if there's any application that has opened those files.
Output the return code from SysFileDelete (error checking)
If rtc <> 0 THEN
 SAY 'Could not delete' filelist.A', error code:' rtc

Quote from: sXwamp on 2011.12.06, 14:01:25
There must be a logic error somewhere. I did have some progress messing around with it - the code below deletes all the file but the first item in the NoDel list - the other two get deleted.

The only thing I changed from Jeps code is below:


I changed:         rtc = SysFileDelete( filelist.B )    /* delete file */

to           :         rtc = SysFileDelete( filelist.A )    /* delete file */

My fault! Of course it should be filelist.A and the End instruction has to be moved before the SysFileDelete so that it do the check for all (3) items in list before it delete the file.

See my corrections and additions with attrib etc.

CALL RxFuncAdd 'SysFileTree', 'RexxUtil', 'SysFileTree'
CALL RxFuncAdd 'SysFileDelete', 'RexxUtil', 'SysFileDelete'
CALL RxFuncAdd 'SysRmDir', 'RexxUtil', 'SysRmDir'

fDir ='Z:\Unzip\firefox-8.0.1.en-US.os2\firefox'

/* List files and delete each of them */

/* Create Match list of do-not-deletes, upper case! */
   NoDel.1='FIREFOX!K.EXE'
   NoDel.2='FIREFOX.EXE'
   NoDel.3='FIREFOX.ICO'
   NoDel.0=3  /* Set stem array length */

/* Read directory and all sub-directories and create file list in stem array filelist, take care of possible trailing back slash */
/* We only care about the fully qualified path names and in subfolders as well, so use "O" option to drop dates, times, attribs, etc */
   rtc = SysFileTree( STRIP( fDir, 'T', '\' )||"\*", "filelist", "SFO" )  

/* Create worker loops */
   Do A = 1 to filelist.0    /* Loop through file list using count in stem base */
       'attrib "'||filelist.A||' -r -a -s -h' /* turn off read only, archive, s...omething */
       Do B = 1 to NoDel.0    /* Compare to each value in NoDel array */
           If Pos( NoDel.B, Translate( filelist.A ) ) > 0 Then   /* found a match - using upper case to ensure proper matching */
           Iterate A /* Jump to the next file in the list and don't process this one! */
       End /* Has to be placed before code that delete the file */
       rtc = SysFileDelete( filelist.A )    /* delete file */
       /* Add programming code here to check error codes if wanted - for instance cant delete because locked file */
       If rtc = 0 Then Say FileSpec( filelist.A, 'N' ) 'deleted'
       Else SAY 'Could not delete' filelist.A', error code:' rtc
   End

<snip>

//Jan-Erik
#43
Rexx / Re: Firefox D&D install !!!
2011.12.06, 12:58:49
Quote from: sXwamp on 2011.12.04, 05:43:42
Also, for the Rexx programming guru's out there, can someone tell me how to parse the name from 'firefox-8.0.1.en-US.os2' to 'Firefox-8.0.1' for the name of the installation directory.

PARSE VALUE FILESPEC( full_path_name, 'N' ) WITH ff_name'.en-'.

Quote from: sXwamp on 2011.12.04, 05:43:42
And I need a way to delete all the files and directories in a firefox directory, except 'firefox.exe', 'firefox!K.exe', and 'firefox.ico' using a Rexx script.

Greggory

A shortend version of the code RobertM provided.
/* List files and delete each of them */

/* Create Match list of do-not-deletes, upper case! */
   NoDel.1='FIREFOX.EXE'
   NoDel.2='FIREFOX!K.EXE'
   NoDel.3='FIREFOX.ICO'
   NoDel.0=3  /* Set stem array length */

/* Read directory and all sub-directories and create file list in stem array filelist, take care of possible trailing back slash */
/* We only care about the fully qualified path names and in subfolders as well, so use "O" option to drop dates, times, attribs, etc */
   rtc = SysFileTree( STRIP( fDir, 'T', '\' )||"\*", "filelist", "SFO" )  

/* Create worker loops */
   Do A = 1 to filelist.0    /* Loop through file list using count in stem base */
       Do B = 1 to NoDel.0    /* Compare to each value in NoDel array */
           If Pos( NoDel.B, Translate( filelist.A ) ) > 0 Then   /* found a match - using upper case to ensure proper matching */
           Iterate A /* Jump to the next file in the list and don't process this one! */
       End
       rtc = SysFileDelete( filelist.A /* corrected from B to A */ )    /* delete file */
       /* Add programming code here to check error codes if wanted - for instance cant delete because locked file */
/*        If rtc = 0 Then Say FileSpec( filelist.A, 'N' ) 'deleted' */
   End


Another way to do this:
           If Pos( NoDel.B, Translate( filelist.A ) ) > 0 Then   /* found a match - using upper case to ensure proper matching */

is to write
           If NoDel.B = Translate( FileSpec( filelist.A, 'N' ) ) Then
which will match files with the whole file name (no path) so that we don't get a positive match with
nofirefox.exe that we'd get with Pos( ... )

Compare this example:
filelist.A = 'C:\path\Firefox-8.0.1\nofirefox.exe'

Pos( NoDel.B, Translate( filelist.A ) ) > 0 ---> POS( FIREFOX.EXE, C:\PATH\FIREFOX-8.0.1\NOFIREFOX.EXE ) >0 that is 24 > 0 which equals TRUE
while the comparison
NoDel.B = Translate( FileSpec( filelist.A, 'N' ) ) ---> FIREFOX.EXE = NOFIREFOX.EXE equals FALSE



Each archive I've seen contain the folder "firefox", "thunderbird" etc. depending on content so you could probably use unzip32.dll directly in rexx to find out what package you're actually handling and unzip files accordingly. I found unzip32.dll useful once I tried it, but the documentation in Tips & Tricks is a must.
You could probably replace "firefox" in the array NoDel.1 to 3 with names from the path in the .zip-file (list with unzip32.dll). That way you could use one script to install Firefox, Thunderbird and Seamonkey. :)

//Jan-Erik
#44

HTML sounds nice, but not until the "browser" (firefox) and the "browser engine" (gecko + ? ) has been separated and Kompozer/Thunderbird/Firefox/Seamonkey/BlueGriffon/HelpViewer just can load and share the same "engine" to render the page in a similar fashion to the old ibm web browser dll (Object Desktop Help + ???) and the chrome component within QT4 in Arora.
#45
Applications / Re: AVxCAT - ClamAVGUI
2011.10.09, 20:00:40
Hello Remy,

your tools are very useful and I especially like and use the capabilities of AVxCAT to edit video clips.

I'm not either throughout happy with "do it the Linux way" (duplicate the same code in several places and versions) instead of improving the OS/2-eCS-way-of-doing-things or share code, run by several apps in parallell, but it do allow us to get several apps.

The lack of rexx awarnes is annoying, but understandable.
That's why I propose to add rexx functions in dlls so one can use them in OS/2-eCS applications as well.

//Jan-Erik
Bomb away.