Adrian Nier Code

Back to overview

Check open port

Last modification: Thursday, June 11, 2009 01:13 pm

Tries to check if a network port is open, respecting a specified timeout interval.

Required parameters
Parameter 1 (string)
A string that represents the network address (IP address or URL) to check the port at.
Parameter 2 (integer)
The port to check as integer value.
Parameter 3 (integer)
An integer defining the timeout interval.

Implementation

on checkOpenPort(_address, _port, _timeout)
   
   script CheckOpenPort_Extras
      
      on pathForTemporaryFile(_folderName)
         
         (*
 Generates a unique path for a file in the
 current user's temporary items folder.
 Takes a single argument that can be set
 to the name of a subfolder or false to
 create no subfolder.
 *)

         
         -- Create timestamp
         set _date to current date
         set _month to month of _date as integer
         set _day to day of _date
         set _year to year of _date as string
         
         set _time to (time of _date)
         set _hour to _time div 60 div 60
         set _minute to (_time div 60) - (_hour * 60)
         set _second to _time - (_minute * 60) - (_hour * 60 * 60)
         
         if _month is less than 10 then set _month to "0" & _month
         if _day is less than 10 then set _day to "0" & _day
         set _yearShort to characters -2 thru -1 of _year
         
         if _hour is less than 10 then set _hour to "0" & _hour
         if _minute is less than 10 then set _minute to "0" & _minute
         if _second is less than 10 then set _second to "0" & _second
         
         set _prvDlmt to AppleScript's text item delimiters
         set AppleScript's text item delimiters to ""
         set _timeStamp to ((_year & "-" & _month & "-" & _day & "_" & _hour & "-" & _minute & "-" & _second) as string)
         set AppleScript's text item delimiters to _prvDlmt
         
         -- Generate pseudorandom numbers
         set _rand1 to (round (random number from 100 to 999)) as string
         set _rand2 to (round (random number from 100 to 999)) as string
         set _rand3 to (round (random number from 100 to 999)) as string
         set _rand4 to (round (random number from 100 to 999)) as string
         set _randomString to _rand1 & "-" & _rand2 & "-" & _rand3 & "-" & _rand4
         
         -- Create file name
         set _fileName to ((_timeStamp & "_" & _randomString) as string)
         
         -- Get the path to the parent folder
         set _temporaryFolderPath to path to temporary items folder from user domain as string
         if _folderName is false then
            set _parentFolderPath to _temporaryFolderPath
         else
            set _parentFolderPath to _temporaryFolderPath & _folderName & ":"
            tell application "System Events" to if (exists folder _parentFolderPath) is false then make new folder at the end of folders of folder _temporaryFolderPath with properties {name:_folderName}
         end if
         
         -- Make sure the file does not exist
         set _rNumber to 1
         
         repeat
            if _rNumber is 1 then
               set _tempFilePath to _parentFolderPath & _fileName
            else
               set _tempFilePath to _parentFolderPath & _fileName & "_" & (_rNumber as string)
            end if
            
            tell application "System Events" to if (exists file _tempFilePath) is false then exit repeat
            set _rNumber to _rNumber + 1
         end repeat
         
         return _tempFilePath
         
      end pathForTemporaryFile
      
      
   end script
   
   
   -- Quote the address
   set _addressQ to quoted form of _address
   set _portQ to quoted form of (_port as string)
   
   -- Get the path to a unique temporary file as a quoted posix path (QPP)
   tell CheckOpenPort_Extras to set _strokeFilePath to pathForTemporaryFile("CheckOpenPort")
   set _strokeFileQPP to quoted form of (POSIX path of _strokeFilePath)
   
   -- Reset cache
   do shell script "dscacheutil -flushcache"
   
   -- Run stroke tool
   set _strokeToolQPP to quoted form of "/Applications/Utilities/Network Utility.app/Contents/Resources/stroke"
   set _pid to do shell script _strokeToolQPP & " " & _addressQ & " " & _portQ & " " & _portQ & " > " & _strokeFileQPP & " 2>&1 & echo $!"
   
   -- Make sure the _pid is an integer
   try
      set _pid to _pid as integer
   on error
      set _pid to false
   end try
   
   -- Check for result
   set _timeTaken to 0.0
   repeat
      try
         set _strokeResult to do shell script "/bin/cat " & _strokeFileQPP
      on error
         set _strokeResult to ""
      end try
      
      if _strokeResult is not "" then
         if _strokeResult contains "Open TCP Port" or _strokeResult contains "Open UDP Port" then
            
            -- Clean up
            try
               if _pid is not false then do shell script "kill " & (_pid as string)
            end try
            do shell script "/bin/rm -f " & _strokeFileQPP
            
            -- Return positive result
            return true
         end if
      end if
      
      delay 0.1
      set _timeTaken to _timeTaken + 0.1
      if _timeTaken is greater than or equal to _timeout then exit repeat
   end repeat
   
   -- Clean up
   try
      if _pid is not false then do shell script "kill " & (_pid as string)
   end try
   do shell script "/bin/rm -f " & _strokeFileQPP
   
   -- Return negative result
   return false
   
end checkOpenPort