Unix style "tail -f" written in VBS. *APPLIED*

This section contains scripts that hMailServer has contributed with. hMailServer 5 is needed to use these.
Post Reply
User avatar
SorenR
Senior user
Senior user
Posts: 3709
Joined: 2006-08-21 15:38
Location: Denmark

Unix style "tail -f" written in VBS. *APPLIED*

Post by SorenR » 2019-06-26 13:19

Proof-of-Concept code here:
https://www.hmailserver.com/forum/viewt ... 67#p212967

Practical use and further adaptation of code in this thread. Thanks.
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

User avatar
SorenR
Senior user
Senior user
Posts: 3709
Joined: 2006-08-21 15:38
Location: Denmark

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by SorenR » 2019-06-27 00:16

Minor changes.

Code: Select all

Option Explicit

'******************************************************************************************************************************
'********** Configuration                                                                                            **********
'******************************************************************************************************************************
'
'   COM authentication
'
Private Const ADMIN = "Administrator"
Private Const PASSWORD = "VerySecretPassword"
'
'   Misc. settings
'
Private Const intInterval = "2" '   Event trigger interval in seconds.
Private Const strComputer = "." '   Nodename/Computer name
Private Const FOR_READING = 1

'******************************************************************************************************************************
'********** Functions                                                                                                **********
'******************************************************************************************************************************

Function tailFile(strFileName)
    Dim intCurrLine, intNewNumLines, strReadLine, strRegEx, arrReadLine
    Dim oFSO, oFile
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFile = oFSO.OpenTextFile(strFileName, FOR_READING)
    intNewNumLines = 0
    intCurrLine = 0
    Do Until oFile.AtEndOfStream
        intCurrLine = intCurrLine + 1
        If intCurrLine <= intLastRunLineinFile Then
            oFile.skipline
        Else
            strReadLine = oFile.ReadLine
            '
            '    THIS IS WHERE THE FUN BEGINS ==>
            '
            WScript.echo strReadLine
            strRegEx = "(Unknown user)|(Origin Banned)|(mechanism not supported)|(Authentication failed)"
            If Lookup(strRegEx, strReadLine) Then
                With CreateObject("hMailServer.Message")
                    .AddRecipient "Postmaster", "postmaster@acme.inc"
                    .FromAddress = "postmaster@acme.inc"
                    .HeaderValue("To") = Chr(34) & "Postmaster" & Chr(34) & " <postmaster@acme.inc>"
                    .HeaderValue("From") = Chr(34) & "Postmaster" & Chr(34) & " <postmaster@acme.inc>"
                    .Subject = "log_tail.vbs found something"
                    .Body = strReadLine
                    .Save
                End With
            End If
            '
            '    ==> THIS IS WHERE THE FUN ENDS
            '
            intNewNumLines = intNewNumLines + 1
        End If
    Loop
    If intCurrLine < intLastRunLineinFile Then
        '   The number of lines on this scan was less than the last run so resetting the num lines in file
        intLastRunLineinFile = intCurrLine
    Else
        intLastRunLineinFile = intLastRunLineinFile + intNewNumLines
    End If
    oFile.close
    Set oFile = Nothing
    Set oFSO = Nothing
End Function

Function get_NumLinesInFile(strFileName)
    Dim intTotalNumLines
    Dim oFSO, oFile
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFile = oFSO.OpenTextFile(strFileName, FOR_READING)
    intTotalNumLines = 0
    Do Until oFile.AtEndOfStream
        oFile.skipline
        intTotalNumLines = intTotalNumLines + 1
    Loop
    oFile.close
    Set oFile = Nothing
    Set oFSO = Nothing
    get_NumLinesInFile = intTotalNumLines
End Function

Function get_DefaultLogFileName(stdDrive, strFolder)
    Dim oLog, i, arrArgsLine
    Set oLog = CreateObject("hMailServer.Logging")
    get_DefaultLogFileName = oLog.CurrentDefaultLog
    Set oLog = Nothing
    arrArgsLine = Split(get_DefaultLogFileName, "\")
    strDrive = arrArgsLine(0)
    If UBound(arrArgsLine) > 1 Then
        For i = 1 To UBound(arrArgsLine)-1
            strFolder = strFolder & "\\" & arrArgsLine(i)
        Next
        strFolder = strFolder & "\\"
    End If
End Function

Function Lookup(strRegEx, strMatch) : Lookup = False
   If strRegEx = "" Then Exit Function
   With CreateObject("VBScript.RegExp")
      .Pattern = strRegEx
      .Global = False
      .MultiLine = True
      .IgnoreCase = True
      If .Test(strMatch) Then Lookup = True
   End With
End Function

Function oLookup(strRegEx, strMatch, bGlobal)
   If strRegEx = "" Then strRegEx = StrReverse(strMatch)
   With CreateObject("VBScript.RegExp")
      .Pattern = strRegEx
      .Global = bGlobal
      .MultiLine = True
      .IgnoreCase = True
      Set oLookup = .Execute(strMatch)
   End With
End Function

'******************************************************************************************************************************
'********** Main Code                                                                                                **********
'******************************************************************************************************************************

Dim oApp : Set oApp = CreateObject("hMailServer.Application")
Call oApp.Authenticate(ADMIN, PASSWORD)
Dim EventLog : Set EventLog = CreateObject("hMailServer.EventLog")

Dim strLongFileName, strDrive, strFolder, strQuery, intLastRunLineinFile, colEvents
Dim oWMIService, oEvent, oTargetInst
'
'   Read logfile
'
strLongFileName = get_DefaultLogFileName(strDrive, strFolder)
intLastRunLineinFile = get_NumLinesInFile(strLongFileName)
'
'   Build interface to WMI
'
strQuery = "Select * From __InstanceOperationEvent Within " & intInterval & _
           " Where Targetinstance Isa 'CIM_DataFile' And TargetInstance.Drive='" & strDrive & _
           "' And TargetInstance.Path='" & strFolder & "'"
Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colEvents = oWMIService.ExecNotificationQuery(strQuery)
'
'   Event management
'
Do
    Set oEvent = colEvents.NextEvent()
    Set oTargetInst = oEvent.TargetInstance
    Select Case oEvent.Path_.Class
        Case "__InstanceDeletionEvent"
            If 0 = StrComp(oTargetInst.Name, strLongFileName, 1) Then
                WScript.echo oTargetInst.Name & " has been deleted. Exiting."
                WScript.quit
            End If
        Case "__InstanceModificationEvent"
            If 0 = StrComp(oTargetInst.Name, strLongFileName, 1) Then
                tailFile(oTargetInst.Name)
            End If
        Case "__InstanceCreationEvent"
            If 0 = StrComp(Left(oTargetInst.Name, 12), Left(strLongFileName, 12), 1) Then
                WScript.echo oTargetInst.Name & " has been created. Loading new logfile."
                strLongFileName = oTargetInst.Name
                intLastRunLineinFile = 0
            End If
    End Select
Loop
WScript.quit
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

User avatar
SorenR
Senior user
Senior user
Posts: 3709
Joined: 2006-08-21 15:38
Location: Denmark

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by SorenR » 2019-06-27 17:46

Fixed problem motoring logfiles. If an error log was created the code would follow the error log and not the regular log.

Code: Select all

Option Explicit

'******************************************************************************************************************************
'********** Configuration                                                                                            **********
'******************************************************************************************************************************
'
'   COM authentication
'
Private Const ADMIN = "Administrator"
Private Const PASSWORD = "VerySecretPassword"
'
'   Misc. settings
'
Private Const intInterval = "2" '   Event trigger interval in seconds.
Private Const strComputer = "." '   Nodename/Computer name
Private Const FOR_READING = 1

'******************************************************************************************************************************
'********** Functions                                                                                                **********
'******************************************************************************************************************************

Function tailFile(strFileName)
    Dim intCurrLine, intNewNumLines, strReadLine, strRegEx, arrReadLine
    Dim oFSO, oFile
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFile = oFSO.OpenTextFile(strFileName, FOR_READING)
    intNewNumLines = 0
    intCurrLine = 0
    Do Until oFile.AtEndOfStream
        intCurrLine = intCurrLine + 1
        If intCurrLine <= intLastRunLineinFile Then
            oFile.skipline
        Else
            strReadLine = oFile.ReadLine
            '
            '    THIS IS WHERE THE FUN BEGINS ==>
            '
            WScript.echo strReadLine
            strRegEx = "(Unknown user)|(Origin Banned)|(mechanism not supported)|(Authentication failed)"
            If Lookup(strRegEx, strReadLine) Then
                With CreateObject("hMailServer.Message")
                    .AddRecipient "Postmaster", "postmaster@acme.inc"
                    .FromAddress = "postmaster@acme.inc"
                    .HeaderValue("To") = Chr(34) & "Postmaster" & Chr(34) & " <postmaster@acme.inc>"
                    .HeaderValue("From") = Chr(34) & "Postmaster" & Chr(34) & " <postmaster@acme.inc>"
                    .Subject = "hm_tail.vbs found something"
                    .Body = strReadLine
                    .Save
                End With
            End If
            '
            '    ==> THIS IS WHERE THE FUN ENDS
            '
            intNewNumLines = intNewNumLines + 1
        End If
    Loop
    If intCurrLine < intLastRunLineinFile Then
        '   The number of lines on this scan was less than the last run so resetting the num lines in file
        intLastRunLineinFile = intCurrLine
    Else
        intLastRunLineinFile = intLastRunLineinFile + intNewNumLines
    End If
    oFile.close
    Set oFile = Nothing
    Set oFSO = Nothing
End Function

Function get_NumLinesInFile(strFileName)
    Dim intTotalNumLines
    Dim oFSO, oFile
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFile = oFSO.OpenTextFile(strFileName, FOR_READING)
    intTotalNumLines = 0
    Do Until oFile.AtEndOfStream
        oFile.skipline
        intTotalNumLines = intTotalNumLines + 1
    Loop
    oFile.close
    Set oFile = Nothing
    Set oFSO = Nothing
    get_NumLinesInFile = intTotalNumLines
End Function

Function get_DefaultLogFileName(stdDrive, strFolder)
    Dim oLog, i, arrArgsLine
    Set oLog = CreateObject("hMailServer.Logging")
    get_DefaultLogFileName = oLog.CurrentDefaultLog
    Set oLog = Nothing
    arrArgsLine = Split(get_DefaultLogFileName, "\")
    strDrive = arrArgsLine(0)
    If UBound(arrArgsLine) > 1 Then
        For i = 1 To UBound(arrArgsLine)-1
            strFolder = strFolder & "\\" & arrArgsLine(i)
        Next
        strFolder = strFolder & "\\"
    End If
End Function

Function get_FileName(strFileName)
    Dim oFSO, oFile
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFile = oFSO.GetFile(strFileName)
    get_FileName = oFSO.GetFileName(oFile)
    Set oFile = Nothing
    Set oFSO = Nothing
End Function

Function Lookup(strRegEx, strMatch) : Lookup = False
   If strRegEx = "" Then Exit Function
   With CreateObject("VBScript.RegExp")
      .Pattern = strRegEx
      .Global = False
      .MultiLine = True
      .IgnoreCase = True
      If .Test(strMatch) Then Lookup = True
   End With
End Function

Function oLookup(strRegEx, strMatch, bGlobal)
   If strRegEx = "" Then strRegEx = StrReverse(strMatch)
   With CreateObject("VBScript.RegExp")
      .Pattern = strRegEx
      .Global = bGlobal
      .MultiLine = True
      .IgnoreCase = True
      Set oLookup = .Execute(strMatch)
   End With
End Function

'******************************************************************************************************************************
'********** Main Code                                                                                                **********
'******************************************************************************************************************************

Dim oApp : Set oApp = CreateObject("hMailServer.Application")
Call oApp.Authenticate(ADMIN, PASSWORD)
Dim EventLog : Set EventLog = CreateObject("hMailServer.EventLog")

Dim strLongFileName, strDrive, strFolder, strQuery, intLastRunLineinFile, colEvents
Dim oWMIService, oEvent, oTargetInst
'
'   Read logfile
'
strLongFileName = get_DefaultLogFileName(strDrive, strFolder)
intLastRunLineinFile = get_NumLinesInFile(strLongFileName)
'
'   Build interface to WMI
'
strQuery = "Select * From __InstanceOperationEvent Within " & intInterval & _
           " Where Targetinstance Isa 'CIM_DataFile' And TargetInstance.Drive='" & strDrive & _
           "' And TargetInstance.Path='" & strFolder & "'"
Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colEvents = oWMIService.ExecNotificationQuery(strQuery)
'
'   Event management
'
Do
    Set oEvent = colEvents.NextEvent()
    Set oTargetInst = oEvent.TargetInstance
    Select Case oEvent.Path_.Class
        Case "__InstanceDeletionEvent"
            If 0 = StrComp(oTargetInst.Name, strLongFileName, 1) Then
                WScript.echo oTargetInst.Name & " has been deleted. Exiting."
                WScript.quit
            End If
        Case "__InstanceModificationEvent"
            If 0 = StrComp(oTargetInst.Name, strLongFileName, 1) Then
                tailFile(oTargetInst.Name)
            End If
        Case "__InstanceCreationEvent"
            If 0 = StrComp(Left(get_FileName(oTargetInst.Name), 12), Left(get_FileName(strLongFileName), 12), 1) Then
                WScript.echo oTargetInst.Name & " has been created. Loading new logfile."
                strLongFileName = oTargetInst.Name
                intLastRunLineinFile = 0
            End If
    End Select
Loop
WScript.quit
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 2015
Joined: 2017-09-12 17:57

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by palinka » 2019-06-27 18:08

Trying to understand how this works. What passes "strFileName"? A trigger? Loads at startup? Scheduled task? I don't get that part. :?:

palinka
Senior user
Senior user
Posts: 2015
Joined: 2017-09-12 17:57

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by palinka » 2019-06-27 18:49

I just came up with a clever use case for this. I just noticed my mom autobanned herself from too many password tries. I'd like to be notified when that happens again, which will definitely happen again soon. :mrgreen:

User avatar
SorenR
Senior user
Senior user
Posts: 3709
Joined: 2006-08-21 15:38
Location: Denmark

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by SorenR » 2019-06-27 21:16

palinka wrote:
2019-06-27 18:08
Trying to understand how this works. What passes "strFileName"? A trigger? Loads at startup? Scheduled task? I don't get that part. :?:
It's quite simple. It's sort of like creating a "stored procedure" on a database table. If you change, add or delete data in the table you trigger the procedure. 8)

This will tell WMI to monitor a specific folder:

Code: Select all

Select * From __InstanceOperationEvent Within 2
   Where Targetinstance Isa 'CIM_DataFile' And TargetInstance.Drive='C:'
   And TargetInstance.Path='\hmailserver\logs'
This will configure WMI:

Code: Select all

Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colEvents = oWMIService.ExecNotificationQuery(strQuery)
This is the trigger that WMI activate in case of an event:

Code: Select all

Set oEvent = colEvents.NextEvent()
This is simply to decode which event occured:

Code: Select all

Set oTargetInst = oEvent.TargetInstance
Select Case oEvent.Path_.Class
oTargetInst.Name is the name (full path) of the file triggering the event:

Left column on this page lists the events that can be monitored..
https://docs.microsoft.com/en-us/window ... etionevent

And... strFileName is not really used :mrgreen:

I'm currently testing a version where SnowShoe, LashBack and Out-of-Area logins are banned. All based on hmailserver_<date>.log with TCPIP logging activated. The option in hMailServer to keep logfiles open have no affect on the functionality.

I found that I need a function in Eventhandlers.vbs to check IF an IPAddress has been banned somewhere between TCPIP Connect and the event OnClientConnect/OnHELO. Banning an ongoing connection will NOT disconnect it automatically.
Attachments
tail.jpg
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

User avatar
RvdH
Senior user
Senior user
Posts: 1089
Joined: 2008-06-27 14:42
Location: Netherlands

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by RvdH » 2019-06-28 14:42

I have ran this for some time...got e few mails, would be nice to have the previous line (or previous few lines) included in the mail as well, now i still have to lookup that line in the logfile myself :)
CIDR to RegEx: d-fault.nl/CIDRtoRegEx
DNS Lookup: d-fault.nl/DNSTools
DNSBL Lookup: d-fault.nl/DNSBLLookup
GEOIP Lookup: d-fault.nl/GeoipLookup

User avatar
SorenR
Senior user
Senior user
Posts: 3709
Joined: 2006-08-21 15:38
Location: Denmark

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by SorenR » 2019-06-28 15:21

RvdH wrote:
2019-06-28 14:42
I have ran this for some time...got e few mails, would be nice to have the previous line (or previous few lines) included in the mail as well, now i still have to lookup that line in the logfile myself :)
You'll just have to figure out how to make a 5 line floating buffer :mrgreen:

One application I can see for this is looking for SnowShoe/LashBack/GeoIP blocking to update a firewall in real-time - or perhaps for statistical purposes. The advantage is you can change it all you want, start/stop it all day long and even if it fails it will NOT affect hMailServer.

I've been playing with those three to AutoBan but TCPIP will register when a banned IP connect so it generates a lot of traffic :roll:
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

User avatar
RvdH
Senior user
Senior user
Posts: 1089
Joined: 2008-06-27 14:42
Location: Netherlands

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by RvdH » 2019-06-28 20:38

SorenR wrote:
2019-06-28 15:21
You'll just have to figure out how to make a 5 line floating buffer :mrgreen:
Something like this? :wink:
https://stackoverflow.com/questions/341 ... 6#34187866
CIDR to RegEx: d-fault.nl/CIDRtoRegEx
DNS Lookup: d-fault.nl/DNSTools
DNSBL Lookup: d-fault.nl/DNSBLLookup
GEOIP Lookup: d-fault.nl/GeoipLookup

User avatar
SorenR
Senior user
Senior user
Posts: 3709
Joined: 2006-08-21 15:38
Location: Denmark

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by SorenR » 2019-06-28 22:31

RvdH wrote:
2019-06-28 20:38
SorenR wrote:
2019-06-28 15:21
You'll just have to figure out how to make a 5 line floating buffer :mrgreen:
Something like this? :wink:
https://stackoverflow.com/questions/341 ... 6#34187866
or https://gallery.technet.microsoft.com/s ... 1749f42f21
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

User avatar
SorenR
Senior user
Senior user
Posts: 3709
Joined: 2006-08-21 15:38
Location: Denmark

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by SorenR » 2019-06-29 00:02

Now with a 10 line Ring Buffer in case the last 10 lines are needed.

Code: Select all

Option Explicit

'******************************************************************************************************************************
'********** Configuration                                                                                            **********
'******************************************************************************************************************************
'
'   COM authentication
'
Private Const ADMIN = "Administrator"
Private Const PASSWORD = "Secret-Secret-Secret"
'
'   Misc. settings
'
Private Const intInterval = "2" '   Event trigger interval in seconds.
Private Const strComputer = "." '   Nodename/Computer name
Private Const FOR_READING = 1
Private Const RING_COUNT  = 10

'******************************************************************************************************************************
'********** Classes                                                                                                  **********
'******************************************************************************************************************************

Class ringBuffer
    Private buffer
    Private indexNext
    Private size

    Public Sub Class_Initialize
        resize 1   
    End Sub
    '
    'RESIZE THE BUFFER, OLD DATA IS LOST
    '
    Public Sub resize(numElements)
        size = Int(numElements)
        If size < 1 Then size = 1
        ReDim buffer(size-1)
        indexNext = 0
    End Sub
    '
    'ADD AN ELEMENT TO RING BUFFER OVERWRITING OLD DATA
    '
    Public Function add(element)
        buffer(indexNext) = element
        indexNext = wrapIndex(indexNext + 1)
    End Function
    '
    'GET PREVIOUS ELEMENT WITH DISTANCE i FROM NEWEST ELEMENT
    '
    Public Function getPrev(i)
        getPrev = buffer( wrapIndex(indexNext-1-i) )
    End Function
    '
    'MAKES AN INDEX TO RING BUFFER FROM 0 TO BUFFER SIZE-1
    'if index is outside the ring buffer,
    'then it will wrap it around so it goes inside the buffer
    '
    Public Function wrapIndex(i)
        If i >= size Then
            wrapIndex = i Mod size
        ElseIf i < 0 Then
            wrapIndex = (i + size * (Int(1 + Abs(i/size)))) Mod size
        Else
            wrapIndex = i
        End If
    End Function
    '
    'BECAUSE...
    '
    Public Sub testWrapIndex(indexLow, indexHigh)
        Dim s, i
        s = "size" & vbTab & Size & vbCrLf & "i" & vbTab & "wrapped" & vbCrLf
        For i = indexLow To indexHigh
            s = s & i & vbTab & wrapIndex(i) & vbCrLf
        Next
        WScript.echo s
    End Sub
End Class 

'******************************************************************************************************************************
'********** Functions                                                                                                **********
'******************************************************************************************************************************

Function tailFile(strFileName)
    Dim i, intCurrLine, intNewNumLines, strBody, strRegEx, arrReadLine
    Dim oFSO, oFile
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFile = oFSO.OpenTextFile(strFileName, FOR_READING)
    intNewNumLines = 0
    intCurrLine = 0
    Do Until oFile.AtEndOfStream
        intCurrLine = intCurrLine + 1
        If intCurrLine <= intLastRunLineinFile Then
            oFile.skipline
        Else
            oRing.add(oFile.ReadLine)
            '
            '    THIS IS WHERE THE FUN BEGINS ==>
            '
            WScript.echo oRing.getPrev(0)

            strRegEx = "(Unknown user)|(Origin Banned)|(mechanism not supported)|(Authentication failed)"
            If Lookup(strRegEx, oRing.getPrev(0)) Then

                strBody = ""
                For i = RING_COUNT-1 To 0 Step -1
                    strBody = strBody & vbCrLf & oRing.getPrev(i)
                Next

                With CreateObject("hMailServer.Message")
                    .AddRecipient "Postmaster", "postmaster@acme.inc"
                    .FromAddress = "postmaster@acme.inc"
                    .HeaderValue("To") = Chr(34) & "Postmaster" & Chr(34) & " <postmaster@acme.inc>"
                    .HeaderValue("From") = Chr(34) & "Postmaster" & Chr(34) & " <postmaster@acme.inc>"
                    .Subject = "hm_tail.vbs found something"
                    .Body = strBody
                    .Save
                End With

            End If
            '
            '    ==> THIS IS WHERE THE FUN ENDS
            '
            intNewNumLines = intNewNumLines + 1
        End If
    Loop
    If intCurrLine < intLastRunLineinFile Then
        '   The number of lines on this scan was less than the last run so resetting the num lines in file
        intLastRunLineinFile = intCurrLine
    Else
        intLastRunLineinFile = intLastRunLineinFile + intNewNumLines
    End If
    oFile.close
    Set oFile = Nothing
    Set oFSO = Nothing
End Function

Function get_NumLinesInFile(strFileName)
    Dim intTotalNumLines
    Dim oFSO, oFile
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFile = oFSO.OpenTextFile(strFileName, FOR_READING)
    intTotalNumLines = 0
    Do Until oFile.AtEndOfStream
        oFile.skipline
        intTotalNumLines = intTotalNumLines + 1
    Loop
    oFile.close
    Set oFile = Nothing
    Set oFSO = Nothing
    get_NumLinesInFile = intTotalNumLines
End Function

'
'    ByRef is used to update the global variables.
'
Function get_DefaultLogFileName(ByRef stdDrive, ByRef strFolder)
    Dim oLog, i, arrArgsLine
    Set oLog = CreateObject("hMailServer.Logging")
    get_DefaultLogFileName = oLog.CurrentDefaultLog
    Set oLog = Nothing
    arrArgsLine = Split(get_DefaultLogFileName, "\")
    strDrive = arrArgsLine(0)
    If UBound(arrArgsLine) > 1 Then
        For i = 1 To UBound(arrArgsLine)-1
            strFolder = strFolder & "\\" & arrArgsLine(i)
        Next
        strFolder = strFolder & "\\"
    End If
End Function

Function get_FileName(strFileName)
    Dim oFSO, oFile
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFile = oFSO.GetFile(strFileName)
    get_FileName = oFSO.GetFileName(oFile)
    Set oFile = Nothing
    Set oFSO = Nothing
End Function

Function Lookup(strRegEx, strMatch) : Lookup = False
   If strRegEx = "" Then Exit Function
   With CreateObject("VBScript.RegExp")
      .Pattern = strRegEx
      .Global = False
      .MultiLine = True
      .IgnoreCase = True
      If .Test(strMatch) Then Lookup = True
   End With
End Function

Function oLookup(strRegEx, strMatch, bGlobal)
   If strRegEx = "" Then strRegEx = StrReverse(strMatch)
   With CreateObject("VBScript.RegExp")
      .Pattern = strRegEx
      .Global = bGlobal
      .MultiLine = True
      .IgnoreCase = True
      Set oLookup = .Execute(strMatch)
   End With
End Function

'******************************************************************************************************************************
'********** Main Code                                                                                                **********
'******************************************************************************************************************************

Dim oApp : Set oApp = CreateObject("hMailServer.Application")
Call oApp.Authenticate(ADMIN, PASSWORD)
Dim EventLog : Set EventLog = CreateObject("hMailServer.EventLog")

Dim strLongFileName, strDrive, strFolder, strQuery, intLastRunLineinFile, colEvents
Dim oWMIService, oEvent, oTargetInst, oRing

strLongFileName = get_DefaultLogFileName(strDrive, strFolder)
intLastRunLineinFile = get_NumLinesInFile(strLongFileName)

strQuery = "Select * From __InstanceOperationEvent Within " & intInterval & _
           " Where Targetinstance Isa 'CIM_DataFile' And TargetInstance.Drive='" & strDrive & _
           "' And TargetInstance.Path='" & strFolder & "'"
Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colEvents = oWMIService.ExecNotificationQuery(strQuery)

Set oRing = New ringBuffer
oRing.resize RING_COUNT

Do
    Set oEvent = colEvents.NextEvent()
    Set oTargetInst = oEvent.TargetInstance
    Select Case oEvent.Path_.Class
        Case "__InstanceDeletionEvent"
            If 0 = StrComp(oTargetInst.Name, strLongFileName, 1) Then
                WScript.echo oTargetInst.Name & " has been deleted. Exiting."
                WScript.quit
            End If
        Case "__InstanceModificationEvent"
            If 0 = StrComp(oTargetInst.Name, strLongFileName, 1) Then
                tailFile(oTargetInst.Name)
            End If
        Case "__InstanceCreationEvent"
            If 0 = StrComp(Left(get_FileName(oTargetInst.Name), 12), Left(get_FileName(strLongFileName), 12), 1) Then
                WScript.echo oTargetInst.Name & " has been created. Loading new logfile."
                strLongFileName = oTargetInst.Name
                intLastRunLineinFile = 0
            End If
    End Select
Loop

WScript.quit
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 2015
Joined: 2017-09-12 17:57

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by palinka » 2019-06-29 00:35

SorenR wrote:
2019-06-27 21:16
It's quite simple.
Uh huh... :roll:







:mrgreen:

User avatar
SorenR
Senior user
Senior user
Posts: 3709
Joined: 2006-08-21 15:38
Location: Denmark

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by SorenR » 2019-06-29 10:50

palinka wrote:
2019-06-29 00:35
SorenR wrote:
2019-06-27 21:16
It's quite simple.
Uh huh... :roll:







:mrgreen:
Image
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 2015
Joined: 2017-09-12 17:57

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by palinka » 2019-06-29 12:09

Exactly! :mrgreen:

LOL

User avatar
RvdH
Senior user
Senior user
Posts: 1089
Joined: 2008-06-27 14:42
Location: Netherlands

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by RvdH » 2019-06-29 13:55

I already implemented my found solution, it was off sometimes, eg: mails containing way more lines as the supposed 5
your seem to work much better, thx! :mrgreen:
CIDR to RegEx: d-fault.nl/CIDRtoRegEx
DNS Lookup: d-fault.nl/DNSTools
DNSBL Lookup: d-fault.nl/DNSBLLookup
GEOIP Lookup: d-fault.nl/GeoipLookup

User avatar
RvdH
Senior user
Senior user
Posts: 1089
Joined: 2008-06-27 14:42
Location: Netherlands

Re: Unix style "tail -f" written in VBS. *APPLIED*

Post by RvdH » 2019-07-11 10:01

I have added some auto-ban functions inside hm_tail.vbs, i'll like it! :mrgreen:

Make sure you replace {backup-mx-ip} and {domain-to-be-blocked} variables

Code: Select all

dim intUnique : intUnique = 0
' Find Unique Indentifier
strRegEx = "^(?:\S+\s){2}(\S+)"
Set Matches = oLookup(strRegEx, oRing.getPrev(1), true)
If Matches.Count > 0 Then intUnique = Matches(0).Submatches(0)
Set Matches = Nothing
' find domains to block 
strRegEx = "(\<.+\@.*(?:{domain-to-be-blocked}).+\>)"
If lookup(strRegEx, oRing.getPrev(1)) then
	Dim strIp : strIp = ""
	Dim strEmailAddress : strEmailAddress = ""
	Dim Matches
' Find ip
	strRegEx = "\b((?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\b"
	Set Matches = oLookup(strRegEx, oRing.getPrev(1), false)
	If Matches.Count > 0 Then strIp = Matches(0).Value
	Set Matches = Nothing
' Find Emailaddress
	strRegEx = "\b(\w+([\-\+\.\']\w+)*\@\w+([\-\.]\w+)*\.\w+([\-\.]\w+)*)\b"
	Set Matches = oLookup(strRegEx, oRing.getPrev(1), false)
	If Matches.Count > 0 Then strEmailAddress = Matches(0).Value
	Set Matches = Nothing
	If (strIp <> "" And strEmailAddress <> "" And lookup("\b(" & intUnique & ")\b", oRing.getPrev(0))) then
		strRegEx = "^({backup-mx-ip})$"
' Filter out backup MX's
		If Not Lookup(strRegEx, strIp) Then
			Call AutoBan(strIp, strEmailAddress, 1, "ww")
		End If
	End If
End If

If lookup("\b(" & intUnique & ")\b", oRing.getPrev(0)) then
	With CreateObject("hMailServer.Message")
		
		.....
		
		.Subject = "hm_tail.vbs found something (" & intUnique & ")"
		.Body = strBody
		.Save
	End With
End If
CIDR to RegEx: d-fault.nl/CIDRtoRegEx
DNS Lookup: d-fault.nl/DNSTools
DNSBL Lookup: d-fault.nl/DNSBLLookup
GEOIP Lookup: d-fault.nl/GeoipLookup

Post Reply