This file is indexed.

/usr/share/pyshared/chirpui/reporting.py is in chirp 0.3.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
# Copyright 2011 Dan Smith <dsmith@danplanet.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# README:
#
# I know that collecting data is not very popular.  I don't like it
# either.  However, it's hard to tell what drivers people are using
# and I think it would be helpful if I had that information.  This is
# completely optional, so you can turn it off if you want.  It doesn't
# report anything other than version and model usage information.  The
# code below is very conservative, and will disable itself if reporting
# fails even once or takes too long to perform.  It's run in a thread
# so that the user shouldn't even notice it's happening.
#

import threading
import os
import time

from chirp import CHIRP_VERSION, platform

REPORT_URL = "http://chirp.danplanet.com/report/report.php?do_report"
ENABLED = True
DEBUG = os.getenv("CHIRP_DEBUG") == "y"
THREAD_SEM = threading.Semaphore(10) # Maximum number of outstanding threads
LAST = 0
LAST_TYPE = None

try:
    # Don't let failure to import any of these modules cause trouble
    from chirpui import config
    import xmlrpclib
except:
    ENABLED = False

def debug(string):
    if DEBUG:
        print string

def should_report():
    if not ENABLED:
        debug("Not reporting due to recent failure")
        return False

    conf = config.get()
    if conf.get_bool("no_report"):
        debug("Reporting disabled")
        return False

    return True

def _report_model_usage(model, direction, success):
    global ENABLED
    if direction not in ["live", "download", "upload", "import", "export", "importsrc"]:
        print "Invalid direction `%s'" % direction
        return True # This is a bug, but not fatal

    model = "%s_%s" % (model.VENDOR, model.MODEL)
    data = "%s,%s,%s" % (model, direction, success)

    debug("Reporting model usage: %s" % data)

    proxy = xmlrpclib.ServerProxy(REPORT_URL)
    id = proxy.report_stats(CHIRP_VERSION,
                            platform.get_platform().os_version_string(),
                            "model_use",
                            data)

    # If the server returns zero, it wants us to shut up
    return id != 0

def _report_exception(stack):
    global ENABLED

    debug("Reporting exception")

    proxy = xmlrpclib.ServerProxy(REPORT_URL)
    id = proxy.report_exception(CHIRP_VERSION,
                                platform.get_platform().os_version_string(),
                                "exception",
                                stack)

    # If the server returns zero, it wants us to shut up
    return id != 0

def _report_misc_error(module, data):
    global ENABLED

    debug("Reporting misc error with %s" % module)

    proxy = xmlrpclib.ServerProxy(REPORT_URL)
    id = proxy.report_misc_error(CHIRP_VERSION,
                                 platform.get_platform().os_version_string(),
                                 module, data)

    # If the server returns zero, it wants us to shut up
    return id != 0

def _check_for_updates(callback):
    debug("Checking for updates")
    proxy = xmlrpclib.ServerProxy(REPORT_URL)
    ver = proxy.check_for_updates(CHIRP_VERSION,
                                  platform.get_platform().os_version_string())

    debug("Server reports version %s is latest" % ver)
    callback(ver)
    return True

class ReportThread(threading.Thread):
    def __init__(self, func, *args):
        threading.Thread.__init__(self)
        self.__func = func
        self.__args = args

    def _run(self):
        try:
            return self.__func(*self.__args)
        except Exception, e:
            debug("Failed to report: %s" % e)
            return False
        
    def run(self):
        start = time.time()
        result = self._run()
        if not result:
            # Reporting failed
            ENABLED = False
        elif (time.time() - start) > 15:
            # Reporting took too long
            debug("Time to report was %.2f sec -- Disabling" % \
                      (time.time()-start))
            ENABLED = False

        THREAD_SEM.release()

def dispatch_thread(func, *args):
    global LAST
    global LAST_TYPE

    # If reporting is disabled or failing, bail
    if not should_report():
        debug("Reporting is disabled")
        return

    # If the time between now and the last report is less than 5 seconds, bail
    delta = time.time() - LAST
    if delta < 5 and func == LAST_TYPE:
        debug("Throttling...")
        return

    LAST = time.time()
    LAST_TYPE = func

    # If there are already too many threads running, bail
    if not THREAD_SEM.acquire(False):
        debug("Too many threads already running")
        return

    t = ReportThread(func, *args)
    t.start()

def report_model_usage(model, direction, success):
    dispatch_thread(_report_model_usage, model, direction, success)

def report_exception(stack):
    dispatch_thread(_report_exception, stack)

def report_misc_error(module, data):
    dispatch_thread(_report_misc_error, module, data)

# Calls callback with the latest version
def check_for_updates(callback):
    dispatch_thread(_check_for_updates, callback)