Adrian Nier Code

Back to overview

Discover bonjour services

Last modification: Thursday, June 11, 2009 04:07 pm

Finds all services of the specified type on the local network and returns their host's name.

Required parameters
Parameter 1 (string)
The service type to discover (http://www.dns-sd.org/ServiceTypes.html)

Parameter 2 (float)
The time in seconds the discovery is allowed to take.
 

Function Calls

-- Find AFP servers
discoverBonjourServices("afpovertcp", 0.5)

-- Find SSH servers
discoverBonjourServices("ssh", 0.5)

-- Find Macs you could connect to with Server Admin
discoverBonjourServices("servermgr", 0.5)

Implementation

on discoverBonjourServices(_serviceType, _scantime)
   -- Service types can be looked up at: http://www.dns-sd.org/ServiceTypes.html
   
   script DiscoverBonjourServices_Extras
      
      on sortList(_list)
         
         set _prvDlmt to text item delimiters
         set text item delimiters to ASCII character 10
         set _string to _list as string
         set text item delimiters to _prvDlmt
         
         try
            set _sortedString to do shell script "echo " & quoted form of _string & " | sort"
         on error
            return _list
         end try
         
         set _prvDlmt to text item delimiters
         set text item delimiters to ASCII character 13
         set _sortedList to text items of _sortedString
         set text item delimiters to _prvDlmt
         
         return _sortedList
         
      end sortList
      
      on hostnamesFromDiscoveryResults(_results, _serviceType)
         set _hostnames to {}
         set _prvDlmt to text item delimiters
         set text item delimiters to ("_" & _serviceType & "._tcp.")
         repeat with _i from 1 to count of _results
            try
               set _hostname to text item 2 of (item _i of _results)
               set end of _hostnames to stripWhitespace(_hostname)
            end try
         end repeat
         set text item delimiters to _prvDlmt
         return _hostnames
      end hostnamesFromDiscoveryResults
      
      on filterDuplicateString(_strings)
         set _uniqueStrings to {}
         repeat with _i from 1 to count of _strings
            if (item _i of _strings) is not in _uniqueStrings then
               set end of _uniqueStrings to (item _i of _strings)
            end if
         end repeat
         
         return _uniqueStrings
      end filterDuplicateString
      
      on stripWhitespace(_string)
         
         set _charCount to count of characters of _string
         
         -- Exit early if there's no string to process
         if _charCount is 0 then return ""
         
         -- Determine the first character that is not whitespace
         repeat with _startChar from 1 to _charCount
            if (ASCII number (character _startChar of _string)) > 32 then exit repeat
         end repeat
         
         -- Determine the last characters that is not whitespace
         set _endChar to _charCount
         repeat
            if (ASCII number (character _endChar of _string)) > 32 then exit repeat
            set _endChar to _endChar - 1
            if _endChar is 0 then exit repeat
         end repeat
         
         -- Get the substring
         set _prvDlmt to text item delimiters
         set text item delimiters to ""
         set _string to characters _startChar thru _endChar of _string as string
         set text item delimiters to _prvDlmt
         
         return _string
         
      end stripWhitespace
      
      on runDiscoveryScript(_serviceType, _scantime)
         try
            -- Start the script
            set _script to {"#!/bin/bash"}
            
            -- Use the mDNS tool to discover services
            set end of _script to "/usr/bin/mDNS -B _" & _serviceType & "._tcp local &"
            
            -- Keep track of the process id for the mDNS tool
            set end of _script to "mDNSpid=$!"
            
            -- Wait a little for mDNS to discover services
            set end of _script to "sleep " & (_scantime as string)
            
            -- Quit the mDNS tool
            set end of _script to "kill -HUP $mDNSpid"
            
            -- Compose the script
            set _script to combineList(_script, ASCII character 10)
            
            -- Run the script
            set _result to do shell script _script
            
            -- Get the actual results without the header
            set _results to paragraphs 4 thru -1 of _result
            
            return _results
         on error _eMsg number _eNum
            return {}
         end try
      end runDiscoveryScript
      
      on combineList(_list, _delimiter)
         set _prvDlmt to text item delimiters
         set text item delimiters to _delimiter
         set _list to _list as string
         set text item delimiters to _prvDlmt
         
         return _list
      end combineList
   end script
   
   tell DiscoverBonjourServices_Extras
      set _results to runDiscoveryScript(_serviceType, _scantime)
      set _hostnames to hostnamesFromDiscoveryResults(_results, _serviceType)
      set _hostnames to filterDuplicateString(_hostnames)
      set _hostnames to sortList(_hostnames)
   end tell
   
   return _hostnames
   
end discoverBonjourServices