qubes-session-autostart 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. try:
  55. entries = os.listdir(path)
  56. except Exception as e:
  57. print(
  58. "Failed to process path '{}': {}".format(path, str(e)),
  59. file=sys.stderr
  60. )
  61. continue
  62. for entry_name in entries:
  63. if entry_name in processed_entries:
  64. continue
  65. # make the entry as processed, even if not actually started
  66. processed_entries[entry_name] = True
  67. try:
  68. entry_path = os.path.join(path, entry_name)
  69. # files in $HOME have higher priority than dropins
  70. if not path.startswith(xdg.BaseDirectory.xdg_config_home):
  71. entry = open_desktop_entry_and_dropins(entry_path)
  72. else:
  73. entry = DesktopEntry(entry_path)
  74. if entry_should_be_started(entry, environments):
  75. launch(entry_path, wait=False)
  76. except Exception as e:
  77. print("Failed to process '{}': {}".format(
  78. entry_name, str(e)),
  79. file=sys.stderr
  80. )
  81. def main():
  82. process_autostart(sys.argv[1:])
  83. if __name__ == '__main__':
  84. main()