qclipd 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #!/usr/bin/python2.6
  2. #
  3. # The Qubes OS Project, http://www.qubes-os.org
  4. #
  5. # Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
  6. #
  7. # This program is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU General Public License
  9. # as published by the Free Software Foundation; either version 2
  10. # of the License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. #
  21. #
  22. import os
  23. import daemon
  24. from pyinotify import WatchManager, Notifier, ThreadedNotifier, EventsCodes, ProcessEvent
  25. import dbus
  26. from qubes.qubes import QubesDaemonPidfile
  27. qubes_clipboard_info_file = "/var/run/qubes/qubes_clipboard.bin.source"
  28. def watch_qubes_clipboard():
  29. def tray_notify(str, timeout = 3000):
  30. notify_object.Notify("Qubes", 0, "dialog-information", "", str, [], [], timeout, dbus_interface="org.freedesktop.Notifications")
  31. notify_object = dbus.SessionBus().get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
  32. wm = WatchManager()
  33. mask = EventsCodes.OP_FLAGS.get('IN_CLOSE_WRITE')
  34. if not os.path.exists (qubes_clipboard_info_file):
  35. file = open (qubes_clipboard_info_file, 'w')
  36. file.close()
  37. class ClipboardWatcher(ProcessEvent):
  38. def process_IN_CLOSE_WRITE (self, event):
  39. src_info_file = open (qubes_clipboard_info_file, 'r')
  40. src_vmname = src_info_file.readline().strip('\n')
  41. if src_vmname == "":
  42. tray_notify ("Qubes Clipboard has been copied to the VM and wiped.\n"\
  43. "<small>Trigger a paste operation (e.g. Ctrl-v) to insert it into an application.</small>" )
  44. else:
  45. print src_vmname
  46. tray_notify ("Qubes Clipboard fetched from VM: <b>'{0}'</b>\n"\
  47. "<small>Press Ctrl-Shift-v to copy this clipboard onto dest VM's clipboard.</small>".format(src_vmname))
  48. src_info_file.close()
  49. notifier = Notifier(wm, ClipboardWatcher())
  50. wdd = wm.add_watch(qubes_clipboard_info_file, mask)
  51. while True:
  52. notifier.process_events()
  53. if notifier.check_events():
  54. notifier.read_events()
  55. def main():
  56. lock = QubesDaemonPidfile ("qclipd")
  57. if lock.pidfile_exists():
  58. if lock.pidfile_is_stale():
  59. lock.remove_pidfile()
  60. print "Removed stale pidfile (has the previous daemon instance crashed?)."
  61. else:
  62. exit (0)
  63. context = daemon.DaemonContext(
  64. working_directory = "/var/run/qubes",
  65. pidfile = lock)
  66. with context:
  67. watch_qubes_clipboard()
  68. main()