PageRenderTime 83ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/platform/mac/prey-trigger.py

https://github.com/LongRider/prey
Python | 134 lines | 83 code | 24 blank | 27 comment | 15 complexity | c3451029e2279a8f52a4e3002b3322f2 MD5 | raw file
  1. #!/usr/bin/python2.5
  2. # encoding: utf-8
  3. #######################################################
  4. # Prey Mac Network Trigger - (c) 2011 Fork Ltd.
  5. # Written by Tomas Pollak <tomas@forkhq.com>
  6. # Based on the SysConfig section of crankd.py
  7. # Licensed under the GPLv3
  8. #######################################################
  9. # import signal
  10. import os
  11. import sys
  12. # import logging
  13. import subprocess
  14. from datetime import datetime, timedelta
  15. from PyObjCTools import AppHelper
  16. from SystemConfiguration import \
  17. SCDynamicStoreCreate, \
  18. SCDynamicStoreCreateRunLoopSource, \
  19. SCDynamicStoreSetNotificationKeys
  20. from Cocoa import \
  21. CFAbsoluteTimeGetCurrent, \
  22. CFRunLoopAddSource, \
  23. CFRunLoopGetCurrent, \
  24. CFRunLoopAddTimer, \
  25. CFRunLoopTimerCreate, \
  26. NSRunLoop, \
  27. kCFRunLoopCommonModes
  28. min_interval = 2 # minutes
  29. log_file = "/var/log/prey.log"
  30. prey_command = "/usr/share/prey/prey.sh"
  31. try:
  32. log_output = open(log_file, 'wb')
  33. except IOError:
  34. print "No write access to log file: " + log_file + ". Prey log will go to /dev/null!"
  35. log_output = open('/dev/null', 'w')
  36. #######################
  37. # helpers
  38. #######################
  39. def connected():
  40. return interface_connected('en0') or interface_connected('en1')
  41. def interface_connected(interface):
  42. return subprocess.call(["ipconfig", "getifaddr", interface]) == 0
  43. def log(message):
  44. try:
  45. if sys.argv[1] == '--debug':
  46. shout(message)
  47. except IndexError, e:
  48. pass
  49. # only for testing purposes
  50. def shout(message):
  51. os.popen("osascript -e 'say \"" + message + "\"' using Zarvox")
  52. def run_prey():
  53. global run_at
  54. two_minutes = timedelta(minutes=min_interval)
  55. now = datetime.now()
  56. log("Should we run Prey?")
  57. if (run_at is None) or (now - run_at > two_minutes):
  58. log("Running Prey!")
  59. try:
  60. subprocess.Popen(prey_command, stdout=log_output, stderr=subprocess.STDOUT)
  61. run_at = datetime.now()
  62. os.wait()
  63. except OSError, e:
  64. print "\nWait a second! Seems we couldn't find Prey at " + prey_command
  65. print e
  66. sys.exit(1)
  67. #######################
  68. # event handlers
  69. #######################
  70. def network_state_changed(*args):
  71. log("Network change detected")
  72. if connected():
  73. run_prey()
  74. def timer_callback(*args):
  75. """Handles the timer events which we use simply to have the runloop run regularly. Currently this logs a timestamp for debugging purposes"""
  76. # logging.debug("timer callback at %s" % datetime.now())
  77. #######################
  78. # main
  79. #######################
  80. if __name__ == '__main__':
  81. log("Initializing")
  82. run_at = None
  83. if connected():
  84. run_prey()
  85. sc_keys = [
  86. 'State:/Network/Global/IPv4',
  87. 'State:/Network/Global/IPv6'
  88. ]
  89. store = SCDynamicStoreCreate(None, "global-network-change", network_state_changed, None)
  90. SCDynamicStoreSetNotificationKeys(store, None, sc_keys)
  91. CFRunLoopAddSource(
  92. # NSRunLoop.currentRunLoop().getCFRunLoop(),
  93. CFRunLoopGetCurrent(),
  94. SCDynamicStoreCreateRunLoopSource(None, store, 0),
  95. kCFRunLoopCommonModes
  96. )
  97. # signal.signal(signal.SIGHUP, partial(quit, "SIGHUP received"))
  98. # NOTE: This timer is basically a kludge around the fact that we can't reliably get
  99. # signals or Control-C inside a runloop. This wakes us up often enough to
  100. # appear tolerably responsive:
  101. CFRunLoopAddTimer(
  102. NSRunLoop.currentRunLoop().getCFRunLoop(),
  103. CFRunLoopTimerCreate(None, CFAbsoluteTimeGetCurrent(), 2.0, 0, 0, timer_callback, None),
  104. kCFRunLoopCommonModes
  105. )
  106. try:
  107. AppHelper.runConsoleEventLoop(installInterrupt=True)
  108. except KeyboardInterrupt:
  109. print "KeyboardInterrupt received, exiting"
  110. sys.exit(0)