OS2 World Community Forum
OS/2, eCS & ArcaOS - Technical => Programming => Topic started by: Jan-Erik Lärka 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?
/*
* 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
-
'@NET VIEW 2>&1|RXQUEUE'
VALUE( 'HOSTNAME',, 'OS2ENVIRONMENT' )
Two remarks not related to the question: not checking that NET exists can result in a RTFM SYS1041 error (no network, no argument) during an evaluation.
'ENVIRONMENT', please. Unless an author believes that supporting Microsoft OS/2 1.0 is more important than portable and shorter Rexx code. Both will work, but more Rexxes will support this without the superfluous 'OS2' prefix.
-
The documentation should be updated as the word must indicate that no deviation from that was/is allowed in OS/2. I've altered the code anyhow.
From OS/2 Procedures Language 2/REXX Reference
To use VALUE to manipulate OS/2 environment variables, selector must be the string 'OS2ENVIRONMENT' or an expression so evaluated. In this case, the variable name need not be a valid REXX symbol. When VALUE is used to set or change the value of an environment variable, the new value is retained after the REXX procedure ends.
-
rxGetMacAddr()
Do you not need to load support for this? I get absolutely nothing from running the program. Using TRACE ALL, it just falls through to the return.
-
It use the output of commands such as arp, net view, netstat etc. that's part of IBM File and Print.
It should be possible to adapt it to Samba server as well in the future when Samba can run right away after installation.
Add the line
call trace '?i'
in the beginning of the code and run it.
Press Enter to continue and look at the output and you should see what it says.
Set the line to
call trace 'i'
and thus leave out the ? (question mark) in the beginning of the code and run it with
macaddr>output.txt
Then it output every row it execute without asking for confirmation.
The you can read the file output.txt and see where it fail.
-
The you can read the file output.txt and see where it fail.
No I can't. Output.txt is completely blank.
It appears that the problem is that this is for the antique IBM File, and Print client. Sorry, but you didn't say that. Let us know when it works with SAMBA, I can't even imagine why anybody is still using File and print Client. SAMBA has problems, but not as many as File and Print Client.
-
IBM File and Print Client is reliable and integrate well with the system.
Samba trash the database and can't recover if one has to force a reboot.
A reliable fix for that and it may be possible to switch.
-
I can't even imagine why anybody is still using File and print Client.
Cause it simply works and it is a lot faster than any other solution when used with many files. That's the reason why I'm still running it beside samba and ftp.
-
I can't even imagine why anybody is still using File and print Client.
Cause it simply works and it is a lot faster than any other solution when used with many files. That's the reason why I'm still running it beside samba and ftp.
I quit using File and print Client, years ago, when I started using files that are larger than 2 GB. Another reason why I abandoned it, was that windows won't work with it any more (probably Linux too). When I was testing it (many years ago), I found that the speed difference was hardly measurable, in fact SAMBA was probably slightly faster.
If File and print Client works, for you, and you are willing to accept the security risks, use it. It is not for me, any more.
Don't get me wrong, SAMBA has it's problems, but File and print Client hasn't worked, for me, for many years.
On the other hand, my favorite file transfer program is RSync. It is fast, super reliable, handles large files, and it is very efficient. It also works on the local system, as well as across the network, or even the internet.
-
Samba (nmblookup.exe) apparently doesn't list the machines own mac address other than 00-00-0...
-
It should now run and only rely on the installed TCP/IP package.
2019 Oct 11, Now use TCPIP HOST command
/*
* 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, Added support for localhost
* 2019-09-15, OS2ENVIRONMENT -> ENVIRONMENT
* 2019-10-11, Now use TCPIP HOST command
*/
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 = 0
/* No parameters given, list all computers */
IF ARG() = 0 THEN
DO
DO WHILE QUEUED() > 0; PARSE PULL; END;
'@PING 255.255.255.255 56 1 2>&1|RXQUEUE'
DO WHILE QUEUED() > 0
PARSE UPPER VALUE REVERSE( LINEIN( 'QUEUE:' ) ) WITH ' :'ipnumber.i' '.
ipnumber.i = STRIP( REVERSE( ipnumber.i ) )
IF 7 < LENGTH( ipnumber.i ) THEN
i = i + 1
ipnumber.0 = i - 1
END
ipnumber.i = VALUE( 'HOSTNAME',, 'ENVIRONMENT' )
ipnumber.0 = i
j = 1
DO i = 1 TO ipnumber.0
'@HOST' ipnumber.i '2>&1|RXQUEUE'
DO WHILE QUEUED() > 0
PARSE UPPER VALUE LINEIN( 'QUEUE:' ) WITH ipnumber.j' = 'hostname.j
END
hostname.0 = j
IF 0 < LENGTH( hostname.j ) THEN
j = j + 1
END
j = j - 1
ipnumber.j = STRIP( hostname.j )
hostname.j = VALUE( 'HOSTNAME',, 'ENVIRONMENT' )
END
ELSE DO
/* Search for a specific computer */
hostname.0 = 1
hostname.1 = TRANSLATE( ARG(1) )
END
j = 0
DO WHILE QUEUED() > 0; PARSE PULL; END;
DO i = 1 TO hostname.0
IF i = hostname.0 THEN
'@NETSTAT -n 2>&1|RXQUEUE'
ELSE DO
'@PING '||TRANSLATE( hostname.i )||' 1 1 2>&1|RXQUEUE'
DO WHILE QUEUED() > 0; PARSE PULL; END;
'@ARP '||TRANSLATE( hostname.i )||' 2>&1|RXQUEUE'
END
DO WHILE QUEUED() > 0
PARSE UPPER VALUE SUBWORD( LINEIN( 'QUEUE:' ), 2 + ( i = hostname.0 ) ) WITH machex +17 ipnum .
IF ( LENGTH( machex ) = 17 & LENGTH( ipnum ) > 7 ) | ( i = hostname.0 & LENGTH( STRIP( machex ) ) = 12 & machex <> 0 ) THEN
DO
pass = 0
IF i = hostname.0 THEN
DO
IF DATATYPE( STRIP( machex ), 'X' ) THEN
DO
hostname.i = STRIP( hostname.i )
ipnum = ipnumber.i
machex = TRANSLATE( 'ab:cd:ef:gh:ij:kl', STRIP( machex ), 'abcdefghijkl' )
pass = 1
END
END
ELSE pass = 1
IF pass THEN
DO
j = j + 1
IF isStem THEN
INTERPRET stemval'.j.name = hostname.i;'||stemval'.j.macaddr = TRANSLATE( machex, "0", " " );'||stemval'.j.ipaddr = ipnum;'||stemval'.0 = j; retval = j'
ELSE
retval = retval||hostname.i||' '||TRANSLATE( STRIP( machex ), "0", " " )||' '||ipnum||D2C(13)||D2C(10)
END
END
END
END
IF 1 < hostname.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