/*
 *      IFMON.CMD - V1.00 C.Langanke 2009
 *
 *      Syntax: IFMON
 *
 *      ifmon starts a command window and displays a TCP/IP interface
 *      monitor. Every second, ifconfig and netstat are called to
 *      determine all initialized TCP/IP interfaces and established network
 *      routes. If more than 5 host routes are included, they are filtered
 *      out to provide a better feedback on the network routes.
 *
 *      To improve performance, and if a RAM disk can be found found by the
 *      labels VFDISK or RAMFS, the required executables are copied to a
 *      the RAM disk, and executed from there,
 *
 *	20141026 AB		added skipping for to long output
 */

 SIGNAL ON HALT
 '@ECHO OFF';

 Redirection = '>NUL 2>&1';
 CrLf        = '0d0a'x;

 GlobalVars      = 'CrLf ExeRxQueue WindowLines';

 /* configure here */
 RefreshInterval         = 1;
 WIndowTitle             = 'TCP/IP Interface Monitor';
 WindowCols              = 96
 WindowLines             = 65;
 ListValidRamDriveLabels = 'VFDISK RAMFS';

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

 DO 1
    /* check if we need to launch another window */
    PARSE ARG Parms;
    IF (WORDPOS( 'SHOW', Parms) = 0) THEN
    DO
       PARSE SOURCE . . CmdName;
       'START /F /MAX "'WIndowTitle'" CMD.EXE /C mode co'WindowCols','WindowLines '^& ' CmdName ' SHOW';
       LEAVE;
    END;

    /* get the executables */
    ExeIfconfig = SysSearchPath( 'PATH', 'ifconfig.exe');
    ExeNetstat  = SysSearchPath( 'PATH', 'netstat.exe');
    ExeRxQueue  = SysSearchPath( 'PATH', 'rxqueue.exe');

    /* check for VFDISK RAM drive */
    RamDrive = '';
    DriveList = SysDriveMap( 'C:', 'USED');
    DO WHILE (DriveList \= '')
       PARSE VAR DriveList ThisDrive DriveList;
       PARSE VALUE SysDriveInfo( ThisDrive) WITH . . . ThisLabel;
       ThisLabel = STRIP( ThisLabel);
       IF (WORDPOS( ThisLabel, ListValidRamDriveLabels) > 0) THEN
          RamDrive = ThisDrive;
    END;
    /* copy executables to RAM drive */
    IF (RamDrive \= '') THEN
    DO
       'COPY' ExeIfconfig RamDrive Redirection;
       'COPY' ExeNetstat RamDrive Redirection;
       'COPY' ExeRxQueue  RamDrive Redirection;
       ExeIfconfig = RamDrive'\'FILESPEC( 'N', ExeIfconfig);
       ExeNetstat = RamDrive'\'FILESPEC( 'N', ExeNetstat);
       ExeRxQueue = RamDrive'\'FILESPEC( 'N', ExeRxQueue);
    END;

    /* loop the status */
    LastStatus = '';
    DO WHILE (1)

	   LineCount = 0;
       Status = '';
       DO i = 0 TO 9
          Status = Status''GetOutput( ExeIfconfig 'lan'i, 'netmask');
       END;
       Status = Status''CrLf;

       NetstatStatus = GetOutput( ExeNetstat '-r');
       NetstatStatus = CollapseHotRoutes( NetstatStatus);
       Status = Status''NetstatStatus;

       IF (LastStatus <> Status) THEN
       DO
          rcx = SysCls();
          SAY Status
          LastStatus = Status;
       END;
       rcx = SysSleep( RefreshInterval);
    END;
 END;

HALT:
 RETURN( 0);

/* --------- */
GetOutput: PROCEDURE EXPOSE (GlobalVars)
 PARSE ARG Command, ReqSubstring;

 CrLf = '0d0a'x;

 QueueName = RXQUEUE( 'CREATE');
 rc        = RXQUEUE( 'SET', QueueName);

 Command ' 2>NUL |' ExeRxQueue  QueueName;

 LineCount = 0;
 HaveSkipped = 0;
 Output = '';
 DO WHILE (QUEUED() > 0)
    PARSE PULL Line;
    LineCount = LineCount + 1;
    IF ( LineCount < WindowLines - 10 ) THEN Output = Output''Line''CrLf;
    ELSE 
    	DO
    	IF ( HaveSkipped = 0 )	THEN Output = Output'skipped...'CrLf;
    	HaveSkipped = 1;
    	END;
 END;

 rc = RXQUEUE( 'DELETE', QueueName);
 rc = RXQUEUE( 'SET', 'SESSION');

 IF (ReqSubstring <> '') THEN
 DO
    IF (POS( ReqSubstring, Output) = 0) THEN
       Output = '';
 END;

 RETURN( Output);

/* --------- */
CollapseHotRoutes: PROCEDURE EXPOSE (GlobalVars)
 PARSE ARG Status;

 ClientRouteCountMax = 5;

 ClientRouteCount = 0;
 DefaultGateway   = '';

 OldStatus = Status;
 NewStatus = '';

 DO WHILE (Status \= '')
    PARSE VAR Status ThisLine(CrLf)Status;
    PARSE VAR ThisLine RtDestination RtRouter RtNetmask RtMetric RtFlagsRtIntrf;

    /* check for default route */
    IF (ThisLine \= '') THEN
    DO
       IF (RtDestination = 'default') THEN
          DefaultGateway = STRIP( RtRouter);
       ELSE
       DO
          /* check hostroutes using the default gateway */
          IF ((RtRouter = DefaultGateway) & (POS( 'H', RtFlags) > 0)) THEN
          DO
             ClientRouteCount = ClientRouteCount + 1;
             ThisLine = '';
          END;
       END;
    END;
    IF (ThisLine \= '') THEN
       NewStatus = NewStatus''CrLf''ThisLine;
 END;

 /* check if collapsed output is req, */
 IF (ClientRouteCount > ClientRouteCountMax) THEN
    NewStatus = NewStatus''CrLf''CrLf''ClientRouteCount 'host routes over'DefaultGateway;
 ELSE
    NewStatus = OldStatus;

 RETURN( NewStatus);
