This file is indexed.

/usr/lib/python2.7/dist-packages/x2go/mimebox.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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# -*- 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.

"""\
L{X2GoMIMEboxQueue} sets up a thread that listens for incoming files that
shall be opened locally on the client.

For each file that gets dropped in the MIME box an individual 
thread is started (L{X2GoMIMEboxJob}) that handles the processing 
of the incoming file.

"""
__NAME__ = 'x2gomimeboxqueue-pylib'

# modules
import os
import copy
import types
import threading
import gevent

# Python X2Go modules
import defaults
import utils
import log
import mimeboxactions


class X2GoMIMEboxQueue(threading.Thread):
    """\
    If the X2Go MIME box is supported in a particaluar L{X2GoSession} instance
    this class provides a sub-thread for handling incoming files in the MIME box
    directory. The actual handling of a dropped file is handled by the classes
    L{X2GoMIMEboxActionOPEN}, L{X2GoMIMEboxActionOPENWITH} and L{X2GoMIMEboxActionSAVEAS}.

    """
    mimebox_action = None

    mimebox = None
    active_jobs = {}
    mimebox_history = []

    def __init__(self, profile_name='UNKNOWN', session_name='UNKNOWN', 
                       mimebox_dir=None, mimebox_action=None, mimebox_extensions=[],
                       client_instance=None, logger=None, loglevel=log.loglevel_DEFAULT):
        """\
        @param profile_name: name of the session profile this print queue belongs to
        @type profile_name: C{str}
        @param mimebox_dir: local directory for incoming MIME box files
        @type mimebox_dir: C{str}
        @param mimebox_action: name or instance of either of the possible X2Go print action classes
        @type mimebox_action: C{str} or instance
        @param client_instance: the underlying L{X2GoClient} instance
        @type client_instance: C{obj}
        @param logger: you can pass an L{X2GoLogger} object to the
            L{X2GoPrintQueue} 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}

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

        self.profile_name = profile_name
        self.session_name = session_name
        self.mimebox_dir = mimebox_dir
        if self.mimebox_dir: self.mimebox_dir = os.path.normpath(self.mimebox_dir)
        self.mimebox_extensions = mimebox_extensions
        self.client_instance = client_instance
        self.client_rootdir = client_instance.get_client_rootdir()

        # this has to be set before we set the MIME box action...
        self._accept_jobs = False

        if mimebox_action is None:
            mimebox_action = mimeboxactions.X2GoMIMEboxActionOPEN(client_instance=self.client_instance, logger=self.logger)
        elif type(mimebox_action) in (types.StringType, types.UnicodeType):
            mimebox_action = self.set_mimebox_action(mimebox_action, client_instance=self.client_instance, logger=self.logger)
        else:
            # hope it's already an instance...
            self.mimebox_action = mimebox_action

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


    def __del__(self):
        """\
        Class destructor.

        """
        self.stop_thread()

    def pause(self):
        """\
        Prevent acceptance of new incoming files. The processing of MIME box jobs that 
        are currently still active will be completed, though.

        """
        if self._accept_jobs == True:
            self._accept_jobs = False
            self.logger('paused thread: %s' % repr(self), loglevel=log.loglevel_DEBUG)

    def resume(self):
        """\
        Resume operation of the X2Go MIME box queue and continue accepting new incoming 
        files.

        """
        if self._accept_jobs == False:
            self._accept_jobs = True
            self.logger('resumed thread: %s' % repr(self), loglevel=log.loglevel_DEBUG)

    def stop_thread(self):
        """\
        Stops this L{X2GoMIMEboxQueue} thread completely.

        """
        self.pause()
        self._keepalive = False
        self.logger('stopping thread: %s' % repr(self), loglevel=log.loglevel_DEBUG)

    @property
    def _incoming_mimebox_jobs(self):
        if os.path.exists(self.mimebox_dir):
            l = os.listdir(self.mimebox_dir)
            mimebox_jobs = []
            for _ext in self.mimebox_extensions:
                mimebox_jobs.extend([ dj for dj in l if dj.upper().endswith(_ext.upper()) ])
            else:
                mimebox_jobs = l
            return [ dj for dj in mimebox_jobs if dj not in self.active_jobs.keys() ]
        else:
            return []

    def set_mimebox_action(self, mimebox_action, **kwargs):
        """\
        Modify the MIME box action of this L{X2GoMIMEboxQueue} thread during runtime. The 
        change of the MIME box action will be valid for the next incoming file in the MIME box
        directory.

        @param mimebox_action: the MIME box action to execute for incoming files
        @type mimebox_action: C{str} or C{obj}
        @param kwargs: extra options for the specified MIME box action
        @type kwargs: C{dict}

        """
        if mimebox_action in defaults.X2GO_MIMEBOX_ACTIONS.keys():
            mimebox_action = defaults.X2GO_MIMEBOX_ACTIONS[mimebox_action]

        if mimebox_action in defaults.X2GO_MIMEBOX_ACTIONS.values():
            self.mimebox_action = eval ('mimeboxactions.%s(**kwargs)' % mimebox_action)

    def run(self):
        """\
        This method gets called once the L{X2GoMIMEboxQueue} thread is started by the C{X2GoMIMEboxQueue.start()} method.

        """
        self.logger('starting MIME box queue thread: %s' % repr(self), loglevel=log.loglevel_DEBUG)

        self._keepalive = True
        while self._keepalive:

            while self._accept_jobs:

                if self._incoming_mimebox_jobs:

                    for _job in self._incoming_mimebox_jobs:
                        self.logger('processing incoming X2Go MIME box job: %s' % _job, loglevel=log.loglevel_NOTICE)
                        _new_mimeboxjob_thread = X2GoMIMEboxJob(target=x2go_mimeboxjob_handler,
                                                                kwargs={ 
                                                                  'mimebox_file': _job,
                                                                  'mimebox_extensions': self.mimebox_extensions,
                                                                  'mimebox_action': self.mimebox_action,
                                                                  'parent_thread': self,
                                                                  'logger': self.logger, 
                                                                }
                                                               )
                        self.active_jobs['%s' % _job] = _new_mimeboxjob_thread
                        _new_mimeboxjob_thread.start()

                gevent.sleep(3)

            gevent.sleep(1)


def x2go_mimeboxjob_handler(mimebox_file=None, 
                            mimebox_extensions=[],
                            mimebox_action=None,
                            parent_thread=None, logger=None, ):
    """\
    This function is called as a handler function for each incoming X2Go MIME box file
    represented by the class L{X2GoMIMEboxJob}.

    @param mimebox_file: MIME box file name as placed in to the X2Go MIME box spool directory
    @type mimebox_file: C{str}
    @param mimebox_action: an instance of either of the possible C{X2GoMIMEboxActionXXX} classes
    @type mimebox_action: C{X2GoMIMEboxActionXXX} nstance
    @param parent_thread: the L{X2GoMIMEboxQueue} thread that actually created this handler's L{X2GoMIMEboxJob} instance
    @type parent_thread: C{obj}
    @param logger: the L{X2GoMIMEboxQueue}'s logging instance
    @type logger: C{obj}

    """
    mimebox_action.profile_name = parent_thread.profile_name
    mimebox_action.session_name = parent_thread.session_name

    logger('action for printing is: %s' % mimebox_action, loglevel=log.loglevel_DEBUG)

    _dotfile = mimebox_file.startswith('.')
    _blacklisted = mimebox_file.upper().split('.')[-1] in defaults.X2GO_MIMEBOX_EXTENSIONS_BLACKLIST
    _really_process = bool(not _blacklisted  and ((not mimebox_extensions) or [ ext for ext in mimebox_extensions if mimebox_file.upper().endswith('%s' % ext.upper()) ]))
    if _really_process and not _blacklisted and not _dotfile:
        mimebox_action.do_process(mimebox_file=mimebox_file,
                                  mimebox_dir=parent_thread.mimebox_dir,
                                 )
    elif not _blacklisted and not _dotfile:
        logger('file extension of MIME box file %s is prohibited by session profile configuration' % mimebox_file, loglevel=log.loglevel_NOTICE)
    elif _dotfile:
        logger('placing files starting with a dot (.<file>) into the X2Go MIME box is prohibited, ignoring the file ,,%s\'\'' % mimebox_file, loglevel=log.loglevel_WARN)
    else:
        logger('file extension of MIME box file %s has been found in Python X2Go\' hardcoded MIME box extenstions blacklist' % mimebox_file, loglevel=log.loglevel_WARN)

    logger('removing MIME box file %s' % mimebox_file, loglevel=log.loglevel_DEBUG)

    utils.patiently_remove_file(parent_thread.mimebox_dir, mimebox_file)
    logger('removed print job file %s' % mimebox_file, loglevel=log.loglevel_DEBUG)

    del parent_thread.active_jobs['%s' % mimebox_file]
    parent_thread.mimebox_history.append(mimebox_file)
    # in case we do a lot of mimebox file exports we do not want to risk an
    # endlessly growing mimebox job history
    if len(parent_thread.mimebox_history) > 100:
        parent_thread.mimebox_history = parent_thread.mimebox_history[-100:]


class X2GoMIMEboxJob(threading.Thread):
    """\
    For each X2Go MIME box job we create a sub-thread that let's 
    the MIME box job be processed in the background.

    As a handler for this class the function L{x2go_mimeboxjob_handler()} 
    is used.

    """
    def __init__(self, **kwargs):
        """\
        Construct the X2Go MIME box job thread...

        All parameters (**kwargs) are passed through to the constructor
        of C{threading.Thread()}.

        """
        threading.Thread.__init__(self, **kwargs)
        self.daemon = True