qubes-session-autostart 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/python3
  2. # -*- coding: utf-8 -*-
  3. #
  4. # The Qubes OS Project, http://www.qubes-os.org
  5. #
  6. # Copyright (C) 2015-2019 Marek Marczykowski-Górecki
  7. # <marmarek@invisiblethingslab.com>
  8. #
  9. # This program is free software; you can redistribute it and/or
  10. # modify it under the terms of the GNU General Public License
  11. # as published by the Free Software Foundation; either version 2
  12. # of the License, or (at your option) any later version.
  13. #
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. # GNU General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License
  20. # along with this program; if not, write to the Free Software
  21. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. #
  23. #
  24. import sys
  25. from xdg.DesktopEntry import DesktopEntry
  26. from qubesagent.xdg import launch
  27. import xdg.BaseDirectory
  28. import os
  29. QUBES_XDG_CONFIG_DROPINS = '/etc/qubes/autostart'
  30. def open_desktop_entry_and_dropins(filename):
  31. desktop_entry = DesktopEntry(filename)
  32. dropins_dir = os.path.join(QUBES_XDG_CONFIG_DROPINS,
  33. os.path.basename(filename) + '.d')
  34. if os.path.isdir(dropins_dir):
  35. for dropin in sorted(os.listdir(dropins_dir)):
  36. dropin_content = DesktopEntry(os.path.join(dropins_dir, dropin))
  37. desktop_entry.content.update(dropin_content.content)
  38. return desktop_entry
  39. def entry_should_be_started(entry, environments):
  40. """
  41. :type entry: DesktopEntry
  42. """
  43. if entry.getHidden():
  44. return False
  45. if entry.getOnlyShowIn():
  46. return bool(set(entry.getOnlyShowIn()).intersection(environments))
  47. if entry.getNotShowIn():
  48. return not bool(set(entry.getNotShowIn()).intersection(environments))
  49. return True
  50. def process_autostart(environments):
  51. # handle only "most important" entry
  52. processed_entries = {}
  53. for path in xdg.BaseDirectory.load_config_paths('autostart'):
  54. for entry_name in os.listdir(path):
  55. if entry_name in processed_entries:
  56. continue
  57. # make the entry as processed, even if not actually started
  58. processed_entries[entry_name] = True
  59. try:
  60. entry_path = os.path.join(path, entry_name)
  61. # files in $HOME have higher priority than dropins
  62. if not path.startswith(xdg.BaseDirectory.xdg_config_home):
  63. entry = open_desktop_entry_and_dropins(entry_path)
  64. else:
  65. entry = DesktopEntry(entry_path)
  66. if entry_should_be_started(entry, environments):
  67. launch(entry_path, wait=False)
  68. except Exception as e:
  69. print("Failed to process '{}': {}".format(
  70. entry_name, str(e)),
  71. file=sys.stderr
  72. )
  73. def main():
  74. process_autostart(sys.argv[1:])
  75. if __name__ == '__main__':
  76. main()