This file is indexed.

/usr/lib/python2.7/dist-packages/x2go/pulseaudio.py is in python-x2go 0.5.0.1-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# -*- coding: utf-8 -*-

# Copyright (C) 2010-2014 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
#
# Python X2Go is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Python X2Go is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Other contributors:
#       none so far

"""\
X2GoPulseAudio class - a Pulseaudio daemon guardian thread.

"""

__NAME__ = 'x2gopulseaudio-pylib'

from defaults import X2GOCLIENT_OS as _X2GOCLIENT_OS
if _X2GOCLIENT_OS == 'Windows':
    import win32process
    import win32con
    import win32event

# modules
import os
import sys
import threading
import gevent
import copy
import socket

from defaults import LOCAL_HOME as _LOCAL_HOME

# Python X2Go modules
import log

import exceptions
class OSNotSupportedException(exceptions.StandardError): pass
""" Exception denoting that this operating system is not supported. """

class X2GoPulseAudio(threading.Thread):
    """
    This class controls the Pulse Audio daemon.
    """

    def __init__(self, path=None, client_instance=None, logger=None, loglevel=log.loglevel_DEFAULT):
        """\
        Initialize a Pulse Audio daemon instance.

        @param path: full path to pulseaudio.exe
        @type path: C{str}
        @param client_instance: the calling L{X2GoClient} instance
        @type client_instance: L{X2GoClient} instance
        @param logger: you can pass an L{X2GoLogger} object to the L{X2GoClientXConfig} constructor
        @type logger: C{obj}
        @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
            constructed with the given loglevel
        @type loglevel: C{int}

        @raise OSNotSupportedException: on non-Windows platforms Python X2Go presumes that pulseaudio is already launched

        """
        if _X2GOCLIENT_OS not in ("Windows"):
            raise OSNotSupportedException('classes of x2go.pulseaudio module are for Windows only')

        if logger is None:
            self.logger = log.X2GoLogger(loglevel=loglevel)
        else:
            self.logger = copy.deepcopy(logger)
        self.logger.tag = __NAME__

        self.path = path
        self.client_instance = client_instance
        self._keepalive = None

        threading.Thread.__init__(self)
        self.daemon = True
        self.start()

    def run(self):
        """\
        This method is called once the C{X2GoPulseAudio.start()} method has been called. To tear 
        down the Pulseaudio daemon call the L{X2GoPulseAudio.stop_thread()} method.

        """
        self._keepalive = True
        cmd = 'pulseaudio.exe'
        cmd_options = [
            '-n',
            '--exit-idle-time=-1',
            '-L "module-native-protocol-tcp port=4713 auth-cookie=\\\\.pulse-cookie"',
            '-L "module-esound-protocol-tcp port=16001"',
            '-L module-waveout',
        ]

        # Fix for python-x2go bug #537.
        # Works Around PulseAudio bug #80772.
        # Tested with PulseAudio 5.0.
        # This argument will not cause PulseAudio 1.1 to fail to launch.
        # However, PulseAudio 1.1 ignores it for some reason.
        # So yes, the fact that 1.1 ignores it would be a bug in python-x2go if
        # we ever ship 1.1 again.
        #
        # wv.major == 5 matches 2000, XP, and Server 2003 (R2).
        # (Not that we support 2000.)
        wv = sys.getwindowsversion()
        if (wv.major==5):
            self.logger('Windows XP or Server 2003 (R2) detected.', loglevel=log.loglevel_DEBUG)
            self.logger('Setting PulseAudio to "Normal" CPU priority.', loglevel=log.loglevel_DEBUG)
            cmd_options.insert(0,"--high-priority=no")

        cmd_options = " %s" % " ".join(cmd_options)

        if not os.path.isdir(os.path.join(_LOCAL_HOME, '.pulse', '%s-runtime' % socket.gethostname())):
            os.makedirs(os.path.join(_LOCAL_HOME, '.pulse', '%s-runtime' % socket.gethostname()))
        self.logger('starting PulseAudio server with command line: %s%s' % (cmd, cmd_options), loglevel=log.loglevel_DEBUG)

        si = win32process.STARTUPINFO()
        p_info = win32process.CreateProcess(None,
                                            '%s\\%s %s' % (self.path, cmd, cmd_options),
                                            None,
                                            None,
                                            0,
                                            win32con.CREATE_NO_WINDOW|win32process.NORMAL_PRIORITY_CLASS,
                                            None,
                                            None,
                                            si,
                                           )
        (hProcess, hThread, processId, threadId) = p_info

        gevent.sleep(5)
        rc = win32event.WaitForMultipleObjects([hProcess],
                                               1,
                                               1, # wait just one millisec
                                              )
        _is_alive = ( rc != win32event.WAIT_OBJECT_0 )
        if self.client_instance and not _is_alive:
            if os.environ.has_key('CLIENTNAME'):
                self.client_instance.HOOK_pulseaudio_not_supported_in_RDPsession()
            else:
                self.client_instance.HOOK_pulseaudio_server_startup_failed()

        while self._keepalive and _is_alive:
            gevent.sleep(1)
            rc = win32event.WaitForMultipleObjects([hProcess],
                                               1,
                                               1, # wait just one millisec
                                              )
            _is_alive = ( rc != win32event.WAIT_OBJECT_0 )
            if self.client_instance and not _is_alive:
                self.client_instance.HOOK_pulseaudio_server_died()

        self.logger('terminating running PulseAudio server', loglevel=log.loglevel_DEBUG)

        # there is no real kill command on Windows...
        self.logger('PulseAudio process ID to terminate: %s' % processId, loglevel=log.loglevel_DEBUG)
        try:
            win32process.TerminateProcess(hProcess, 0)
        except win32process.error:
            pass

    def stop_thread(self):
        """\
        Tear down a running Pulseaudio daemon.

        """
        self.logger('stop_thread() method has been called', loglevel=log.loglevel_DEBUG)
        self._keepalive = False