[Reportbug-commits] r596 - in trunk (reportbug reportbug_4merge)

morph-guest at users.alioth.debian.org morph-guest at users.alioth.debian.org
Wed Aug 6 21:49:15 UTC 2008


    Date: Wednesday, August 6, 2008 @ 21:49:13
  Author: morph-guest
Revision: 596

renaming reportbug exec to easy branches/modules merge

Added:
  trunk/reportbug_4merge
    (from rev 594, trunk/reportbug)
Deleted:
  trunk/reportbug

Deleted: trunk/reportbug
===================================================================
--- trunk/reportbug	2008-08-06 07:26:56 UTC (rev 595)
+++ trunk/reportbug	2008-08-06 21:49:13 UTC (rev 596)
@@ -1,1831 +0,0 @@
-#! /usr/bin/python
-# -*- python -*-
-# reportbug - Report a bug in the Debian distribution.
-#   Written by Chris Lawrence <lawrencc at debian.org>
-#   Copyright (C) 1999-2007 Chris Lawrence
-#
-# This program is freely distributable per the following license:
-#
-LICENSE="""\
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appears in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation.
-
-I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL I
-BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
-DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE."""
-#
-# Version ##VERSION##; see changelog for revision history
-# $Id: reportbug,v 1.98.2.33 2008-04-18 05:38:27 lawrencc Exp $
-
-DEBUGGER = 'lawrencc at debian.org'
-DEFAULT_BTS = 'debian'
-
-import sys, os
-sys.path = ['/usr/share/reportbug'] + sys.path
-
-import optparse
-import re
-import locale
-import commands
-import rfc822
-import gettext
-import textwrap
-
-from reportbuglib import reportbug
-from reportbuglib.reportbug import (
-    VERSION, COPYRIGHT,
-    MODE_EXPERT, MODE_ADVANCED, MODE_NOVICE, MODE_STANDARD,
-    )
-from reportbuglib.rbtempfile import (
-    TempFile,
-    tempfile_prefix,
-    cleanup_temp_file,
-    )
-from reportbuglib.reportbug_exceptions import (
-    UINotImportable, UINotImplemented,
-    NoNetwork, NoPackage, NoBugs, NoReport,
-    )
-from reportbuglib import reportbug_submit
-from reportbuglib import checkversions
-from reportbuglib import debianbts
-from reportbuglib import checkbuildd
-from reportbuglib import reportbug_ui_text as ui
-
-try:
-    gettext.install('reportbug')
-except IOError:
-    pass
-
-# Magic constant time
-MIN_USER_ID = 250
-
-quietly = False
-
-# Cheat for now.
-# ewrite() may put stuff on the status bar or in message boxes depending on UI
-def ewrite(*args):
-    return quietly or ui.log_message(*args)
-
-def efail(*args):
-    ui.display_failure(*args)
-    sys.exit(1)
-
-# Lame message when we store a report as a temp file.
-def stopmsg(filename):
-    ui.final_message(
-        'reportbug stopped; your incomplete report is stored as "%s".\n'
-        'This file may be located in a temporary directory; if so, it might '
-        'disappear without any further notice. To recover this file to use '
-        'it as bug report body, please take a look at the "-i FILE, '
-        '--include=FILE" option.\n', filename)
-
-# Obscene hack :)
-def system(cmdline):
-    try:
-        x = os.getcwd()
-    except OSError:
-        os.chdir('/')
-    os.system(cmdline)
-
-def include_file_in_report(message, message_filename,
-                           attachment_filenames, package_name,
-                           include_filename, charset, inline=False):
-    """ Include a file in the report.
-
-        :parameters:
-            `message`
-                The current text of the message.
-            `message_filename`
-                The current message filename.
-            `attachment_filenames`
-                List of current attachment filenames.
-            `package_name`
-                Name of the package for this report.
-            `include_filename`
-                Full pathname of the file to be included.
-            `inline`
-                If True, include the message inline with the message
-                text. Otherwise, add the file path to the attachments.
-
-        :return value:
-            Tuple (`message`, `message_filename`, `attachments`) of
-            values as modified during the process of including the new
-            file.
-
-        """
-    if inline:
-        try:
-            fp = file(include_filename)
-            message += '\n*** %s\n%s' % (
-                       include_filename.decode(charset, 'replace'),
-                       fp.read().decode(charset, 'replace'))
-            fp.close()
-            fp, temp_filename = TempFile(
-                prefix=tempfile_prefix(package_name))
-            fp.write(message.encode(charset, 'replace'))
-            fp.close()
-            os.unlink(message_filename)
-            message_filename = temp_filename
-        except (IOError, OSError), exc:
-            ewrite('Unable to attach file %s\n%s\n',
-                   include_filename, str(exc))
-    else:
-        attachment_filenames.append(include_filename)
-
-    return (message, message_filename, attachment_filenames)
-
-def handle_editing(filename, dmessage, options, sendto, attachments, package,
-                   editor=None, charset='utf-8'):
-    if not editor:
-        editor = options.editor
-    editor = reportbug.which_editor(editor)
-    message = None
-    skip_editing = False
-    while True:
-        if not skip_editing:
-            (message, changed) = ui.spawn_editor(message or dmessage, filename,
-                                                 editor, charset)
-        skip_editing = False
-        if not message:
-            x = ''
-            while x != 'y':
-                x = ui.select_options('Done editing', 'Ynq',
-                                      {'y': 'Continue (editing done).',
-                                       'n': "Don't continue yet.",
-                                       'q': 'Exit without sending report.'})
-                if x == 'q':
-                    stopmsg(filename)
-                    sys.exit(1)
-
-            message = file(filename).read().decode(charset, 'replace')
-            changed = True
-
-        prompt = 'Submit this report on %s (e to edit)' % package
-
-        if options.kudos:
-            prompt = 'Send this message (e to edit)'
-            ewrite("Message will be sent to %s\n", sendto)
-        elif options.outfile:
-            ewrite("Report will be saved as %s\n", options.outfile)
-        else:
-            ewrite("Report will be sent to %s\n", sendto)
-
-        if attachments:
-            ewrite('Attachments:\n')
-            for name in attachments:
-                ewrite(' %s\n', name)
-
-        subject = re.search('^Subject: ', message, re.M | re.I)
-        if not subject:
-            ewrite('No subject found in message.  Please edit again.\n')
-
-        menuopts = "Ynaceilmpq"
-
-        if not changed or not subject:
-            menuopts = "ynacEilmpq"
-
-        # cfr Debian BTS #293361
-        if package == 'wnpp':
-            for itp_line in debianbts.itp_template.rsplit('\n'):
-                # if the line is not empty and it's in the message the user wrote
-                if itp_line in message and itp_line != '':
-                    ewrite("Wrong line: %s\n", itp_line)
-                    menuopts = "Eq"
-                    prompt = 'ERROR: you have composed an ITP with fields unchanged from the template; this will NOT be submitted. You should edit all fields so they contain correct values for your ITP (e to edit)'
-
-        x = ui.select_options(prompt, menuopts,
-                              {'y': 'Submit the bug report via email.',
-                               'n': "Don't submit the bug report; instead, "
-                               "save it in a temporary file (exits reportbug).",
-                               'q': "Save it in a temporary file and quit.",
-                               'a': "Attach a file.",
-                               'i': "Include a text file.",
-                               'c': "Change editor and re-edit.",
-                               'e': 'Re-edit the bug report.',
-                               'l': 'Pipe the message through the pager.',
-                               'p': 'Print message to stdout.',
-                               'm': "Choose a mailer to edit the report."})
-        if x in ('a', 'i'):
-            invalid = True
-            while invalid:
-                if x == 'i':
-                    attachfile = ui.get_filename('Choose a text file to include: ')
-                else:
-                    attachfile = ui.get_filename('Choose a file to attach: ')
-                if attachfile:
-                    attachfile = os.path.expanduser(attachfile)
-                    if os.access(attachfile, os.R_OK) and os.path.isfile(attachfile):
-                        invalid = False
-                        inline = (x == 'i')
-                        (message, filename, attachments) = include_file_in_report(
-                            message, filename, attachments, package,
-                            attachfile, charset, inline=inline)
-                        if not inline:
-                            skip_editing = True
-                    else:
-                        ewrite("Can't find %s to include!\n", attachfile)
-                else:
-                    break
-        elif x == 'c':
-            ed = ui.get_filename('Choose editor: ', default=options.editor)
-            if ed:
-                editor = ed
-        elif x == 'm':
-            mailers = [(x, '') for x in reportbug.MUA.keys()]
-            mailers.sort()
-            mailer = ui.menu('Choose a mailer for your report', mailers,
-                             'Select mailer: ', default='', empty_ok=True)
-            if mailer:
-                mailer = reportbug.MUA.get(mailer)
-                if mailer:
-                    options.mua = mailer
-                    break
-            skip_editing = True
-        elif x in ('n', 'q'):
-            stopmsg(filename)
-            sys.exit(1)
-        elif x in ('l', 'p'):
-            skip_editing = True
-            if x == 'l':
-                pager = os.environ.get('PAGER', 'sensible-pager')
-                os.popen(pager, 'w').write(message.encode(charset, 'replace'))
-            else:
-                sys.stdout.write(message.encode(charset, 'replace'))
-        elif x == 'y':
-            if message == dmessage:
-                x = ui.select_options(
-                    'Report is unchanged.  Edit this report or quit', 'Eqs',
-                    {'q': "Don't submit the bug report; instead, save it "
-                     "in a temporary file and quit.",
-                     'e': 'Re-edit the bug report.',
-                     's': 'Send report anyway.'})
-                if x == 'q':
-                    stopmsg(filename)
-                    sys.exit(1)
-                    break
-                elif x == 's':
-                    ewrite('Sending empty report anyway...\n')
-                    break
-            else:
-                break
-
-    return file(filename).read()
-
-def find_package_for(filename, notatty=False, pathonly=False):
-    ewrite("Finding package for '%s'...\n", filename)
-    (newfilename, packages) = reportbug.find_package_for(filename, pathonly)
-    if newfilename != filename:
-        filename = newfilename
-        ewrite("Resolved as '%s'.\n", filename)
-    if not packages:
-        ewrite("No packages match.\n")
-        return (filename, None)
-    elif len(packages) > 1:
-        packlist = packages.items()
-        packlist.sort()
-
-        if notatty:
-            print "Please re-run reportbug selecting one of these packages:"
-            for pkg, files in packlist:
-                print "  "+pkg
-            sys.exit(1)
-
-        packs = []
-        for pkg, files in packlist:
-            if len(files) > 3:
-                files[3:] = ['...']
-            packs.append( (pkg, ', '.join(files) ) )
-
-        package = ui.menu("Multiple packages match: ", packs, 'Select one '
-                          'of these packages: ', any_ok=True)
-        return (filename, package)
-    else:
-        package = packages.keys()[0]
-        ewrite("Using package '%s'.\n", package)
-        return (filename, package)
-
-def validate_package_name(package):
-    if not re.match(r'^[a-z0-9][a-z0-9\-\+\.]+$', package):
-        ui.long_message("%s is not a valid package name.", package)
-        package = None
-    return package
-
-def get_other_package_name(others):
-    """Displays the list of pseudo-packages and returns the one selected."""
-
-    result = ui.menu("Please enter the name of the package in which you "
-                     "have found a problem, or choose one of these bug "
-                     "categories:", others, "Enter a package: ", any_ok=True,
-                     default='')
-    if isinstance(result, basestring):
-        # If the package selected is kernel, we replace it with linux-image
-        # since it contains additional information useful to maintainer
-        if result == 'kernel':
-	    result = 'linux-image'
-        return result
-    else:
-        return None
-
-def get_package_name(bts='debian', mode=MODE_EXPERT):
-    others = debianbts.SYSTEMS[bts].get('otherpkgs')
-    prompt = "Please enter the name of the package in which you have found "\
-             "a problem"
-    if others:
-        prompt += ", or type 'other' to report a more general problem."
-    else:
-        prompt += '.'
-
-    options = []
-    pkglist = commands.getoutput('apt-cache pkgnames')
-    if pkglist:
-        options += pkglist.split()
-    if others:
-        options += others.keys()
-
-    package = None
-    while package is None:
-        package = ui.get_string(prompt, options, force_prompt=True)
-        if not package:
-            return
-        if others and package and package == 'other':
-            package = get_other_package_name(others)
-        if not package:
-            return
-        package = validate_package_name(package)
-
-    if mode < MODE_STANDARD:
-        if package == 'reportbug':
-            if not ui.yes_no('Is "reportbug" actually the package you are '
-                             'having problems with',
-                             'Yes, I am actually experiencing a problem with '
-                             'reportbug.',
-                             'No, I really meant to file a bug report on '
-                             'another package.'):
-                return get_package_name(bts, mode)
-
-    if mode < MODE_EXPERT:
-        if package in ('bugs.debian.org', 'debbugs'):
-            if ui.yes_no('Are you reporting a problem with this program '
-                         '(reportbug)', 'Yes, this is actually a bug in '
-                         'reportbug.', 'No, this is really a problem in the '
-                         'bug tracking system itself.'):
-                package = 'reportbug'
-
-        if package in ('general', 'project', 'debian-general', 'base'):
-            if not ui.yes_no(
-                "Are you sure this bug doesn't apply to a specific package?",
-                'Yes, this bug is truly general.',
-                'No, this is not really a general bug.', False):
-                return get_package_name(bts, mode)
-
-        if package == 'wnpp':
-            if not ui.yes_no(
-                'Are you sure you want to file a WNPP report?',
-                'Yes, I am a developer or know what I\'m doing.',
-                'No, I am not a developer and I don\'t know what wnpp means.',
-                False):
-                return get_package_name(bts, mode)
-
-        if package == 'ftp.debian.org':
-            if not ui.yes_no(
-                'Are you sure you want to file a bug on ftp.debian.org?',
-                'Yes, I am a developer or know what I\'m doing.',
-                'No, I am not a developer and I don\'t know what ftp.debian.org is.',
-                False):
-                return get_package_name(bts, mode)
-
-    return package
-
-def special_prompts(package, bts, ui, fromaddr):
-    prompts = debianbts.SYSTEMS[bts].get('specials')
-    if prompts:
-        pkgprompts = prompts.get(package)
-        if pkgprompts:
-            return pkgprompts(package, bts, ui, fromaddr)
-    return
-
-def offer_configuration(options):
-    charset = locale.nl_langinfo(locale.CODESET)
-    # It would be nice if there were some canonical character set conversion
-    if charset.lower() == 'ansi_x3.4-1968':
-        charset = 'us-ascii'
-    ui.charset = charset
-
-    if not options.configure:
-        ui.long_message('Welcome to reportbug!  Since it looks like this is '
-                        'the first time you have used reportbug, we are '
-                        'configuring its behavior.  These settings will be '
-                        'saved to the file "%s", which you will be free to '
-                        'edit further.\n\n', reportbug.USERFILE)
-    mode = ui.menu('Please choose the default operating mode for reportbug.',
-                   reportbug.MODES, 'Select mode: ', options.mode,
-                   order=reportbug.MODELIST)
-
-    uis = dict()
-    for i in reportbug.AVAILABLE_UIS:
-        if (i in reportbug.UIS) and i != 'newt':
-            uis[i] = reportbug.UIS[i]
-    if len(uis) > 1:
-        interface = ui.menu(
-            'Please choose the default interface for reportbug.', uis,
-            'Select interface: ', options.interface)
-    else:
-        interface = 'text'
-
-    online = ui.yes_no('Will reportbug often have direct '
-                       'Internet access?  (You should answer yes to this '
-                       'question unless you know what you are doing and '
-                       'plan to check whether duplicate reports have been '
-                       'filed via some other channel.)',
-                       'Yes, reportbug should assume it has access to the '
-                       'network always.',
-                       'No, I am only online occasionally to send and '
-                       'receive mail.',
-                       default=(not options.offline))
-
-    def_realname, def_email = reportbug.get_email()
-
-    try:
-        if options.realname:
-            realname = options.realname.encode(charset, 'replace')
-        else:
-            realname = def_realname.encode(charset, 'replace')
-    except UnicodeDecodeError:
-        realname = ''
-
-    realname = ui.get_string('What real name should be used for sending bug '
-                             'reports? [%s]' % realname, force_prompt=True)
-    if isinstance(realname, str):
-        realname = realname.decode(charset, 'replace')
-
-    from_addr = ui.get_string(
-        'Which of your email addresses should be used when sending bug '
-        'reports? (Note that this address will be visible in the bug tracking '
-        'system, so you may want to use a webmail address or another address '
-        'with good spam filtering capabilities.) [%s]' %
-        (options.email or def_email), force_prompt=True)
-
-    stupidmode = not ui.yes_no(
-        'Do you have a "mail transport agent" (MTA) like Exim, Postfix or '
-        'SSMTP configured on this computer to send mail to the Internet?',
-        'Yes, I can run /usr/sbin/sendmail without horrible things happening. '
-        'If you can send email from this machine without setting an SMTP Host '
-        'in your mailer, you should choose this answer.',
-        'No, I need to use an SMTP Host or I don\'t know if I have an MTA.',
-        (not options.smtphost))
-
-    if stupidmode:
-        opts = []
-        if options.smtphost:
-            opts += [options.smtphost]
-        smtphost = ui.get_string(
-            'Please enter the name of your SMTP host.  Usually it\'s called '
-            'something like "mail.example.org" or "smtp.example.org". '
-            'Just press ENTER if you don\'t have one or don\'t know.',
-            options=opts, force_prompt=True)
-        if smtphost:
-            stupidmode = False
-    else:
-        smtphost = ''
-
-    if smtphost:
-        smtpuser = ui.get_string(
-            ('If you need to use a user name to send email via "%s" on your '
-             'computer, please enter that user name.  Just press ENTER if you '
-             'don\'t need a user name.' % smtphost), force_prompt=True)
-    else:
-        smtpuser = ''
-
-    if os.path.exists(reportbug.USERFILE):
-        try:
-            os.rename(reportbug.USERFILE, reportbug.USERFILE+'~')
-        except OSError:
-            ewrite('Unable to rename %s as %s~\n', reportbug.USERFILE,
-                   reportbug.USERFILE)
-
-    try:
-        fd = os.open(reportbug.USERFILE, os.O_WRONLY|os.O_TRUNC|os.O_CREAT,
-                     0600)
-    except OSError, x:
-        ui.long_message('Unable to save %s; most likely, you do not have a '
-                        'home directory.  Please fix this before using '
-                        'reportbug again.\n', reportbug.USERFILE)
-        sys.exit(1)
-
-    fp = os.fdopen(fd, 'w')
-    print >> fp, '# reportbug preferences file'
-    print >> fp, '# character encoding: %s' % charset
-    print >> fp, '# Version of reportbug this preferences file was written by'
-    print >> fp, 'reportbug_version "##VERSION##"'
-    print >> fp, '# default operating mode: one of:',
-    print >> fp, ', '.join(reportbug.MODELIST)
-    print >> fp, 'mode %s' % mode
-    print >> fp, '# default user interface'
-    print >> fp, 'ui %s' % interface
-    print >> fp, '# offline setting - comment out to be online'
-    if not online:
-        print >> fp, 'offline'
-    else:
-        print >> fp, '#offline'
-    print >> fp, '# name and email setting (if non-default)'
-    rn = 'realname "%s"'
-    em = 'email "%s"'
-    email_addy = (from_addr or options.email or def_email)
-    email_name = (realname or options.realname or def_realname)
-
-    if email_name != def_realname:
-        print >> fp, rn % email_name.encode(charset, 'replace')
-    else:
-        print >> fp, '# '+(rn % email_name.encode(charset, 'replace'))
-
-    if email_addy != def_email:
-        print >> fp, em % email_addy
-    else:
-        print >> fp, '# '+(em % email_addy)
-
-    uid = os.getuid()
-    if uid < MIN_USER_ID:
-        print >> fp, '# Suppress user ID check for this user'
-        print >> fp, 'no-check-uid'
-
-    if smtphost:
-        print >> fp, '# Send all outgoing mail via the following host'
-        print >> fp, 'smtphost "%s"' % smtphost
-        if smtpuser:
-            print >> fp, 'smtpuser "%s"' % smtpuser
-            print >> fp, '#smtppasswd "my password here"'
-        else:
-            print >> fp, '# If you need to enter a user name and password:'
-            print >> fp, '#smtpuser "my username here"'
-            print >> fp, '#smtppasswd "my password here"'
-
-    if stupidmode:
-        print >> fp, '# Disable fallback mode by commenting out the following:'
-        print >> fp, 'no-cc'
-        print >> fp, 'header "X-Debbugs-CC: %s"' % email_addy
-        print >> fp, 'smtphost bugs.debian.org'
-    else:
-        print >> fp, '# If nothing else works, remove the # at the beginning'
-        print >> fp, '# of the following three lines:'
-        print >> fp, '#no-cc'
-        print >> fp, '#header "X-Debbugs-CC: %s"' % email_addy
-        print >> fp, '#smtphost bugs.debian.org'
-
-    print >> fp, '# You can add other settings after this line.  See'
-    print >> fp, '# /etc/reportbug.conf for a full listing of options.'
-    fp.close()
-    ui.final_message('Default preferences file written.  To reconfigure, '
-                     're-run reportbug with the "--configure" option.\n')
-
-def verify_option(option, opt, value, parser, *args):
-    heading, valid = args
-    if value == 'help':
-        ewrite('%s:\n %s\n' % (heading, '\n '.join(valid)))
-        sys.exit(1)
-    elif value in valid:
-        setattr(parser.values, option.dest, value)
-    else:
-        ewrite('Ignored bogus setting for %s: %s\n' % (opt, value))
-
-def verify_append_option(option, opt, value, parser, *args):
-    heading, valid = args
-    if value == 'help':
-        ewrite('%s:\n %s\n' % (heading, '\n '.join(valid)))
-        sys.exit(1)
-    elif value in valid:
-        try:
-            getattr(parser.values, option.dest).append(value)
-        except AttributeError:
-            setattr(parser.values, option.dest, [value])
-    else:
-        ewrite('Ignored bogus setting for %s: %s\n' % (opt, value))
-
-def main():
-    global quietly, ui
-
-    try:
-        locale.setlocale(locale.LC_ALL, '')
-    except locale.Error, x:
-        print >> sys.stderr, '*** Warning:', x
-
-    charset = locale.nl_langinfo(locale.CODESET)
-    # It would be nice if there were some canonical character set conversion
-    if charset.lower() == 'ansi_x3.4-1968':
-        charset = 'us-ascii'
-
-    defaults = dict(sendto="submit", mode="novice", mta="/usr/sbin/sendmail",
-                    check_available=True, query_src=True, debconf=True,
-                    editor='', offline=False, verify=True, check_uid=True,
-                    testmode=False, attachments=[], keyid='', body=None,
-                    bodyfile=None, smtptls=False, smtpuser='', smtppasswd='',
-                    paranoid=False)
-
-    if not sys.stdin.isatty():
-        defaults.update({ 'dontquery' : True, 'notatty' : True,
-                          'printonly' : True })
-
-    # Convention: consider `option.foo' names read-only; they always contain
-    # the original value as determined by the cascade of command-line options
-    # and configuration files.  When we need to adjust a value, we first say
-    # "foo = options.foo" and then refer to just `foo'.
-    args = reportbug.parse_config_files()
-    for option, arg in args.items():
-        if option in reportbug.CONFIG_ARGS:
-            if isinstance(arg, unicode):
-                arg = arg.encode(charset, 'replace')
-            defaults[option] = arg
-        else:
-            sys.stderr.write('Warning: untranslated token "%s"\n' % option)
-
-    parser = optparse.OptionParser(
-        usage='%prog [options] <package | filename>', version=VERSION)
-    parser.set_defaults(**defaults)
-    parser.add_option('-c', '--no-config-files', action="store_true",
-                      dest='noconf', help='do not include conffiles in report')
-    parser.add_option('-C', '--class', action='callback', type='string',
-                      callback=verify_option, dest="klass", metavar='CLASS',
-                      callback_args=('Permitted report classes:',
-                                     debianbts.CLASSLIST),
-                      help='specify report class for GNATS BTSes')
-    parser.add_option('-d', '--debug', action='store_true', default=False,
-                      dest='debugmode', help='send report only to yourself')
-    parser.add_option('--test', action="store_true", default=False,
-                      dest="testmode",
-                      help="operate in test mode (maintainer use only)")
-    parser.add_option('-e', '--editor', dest='editor',
-                      help='specify an editor for your report')
-    parser.add_option('-f', '--filename', dest='searchfor',
-                      help='file to search for')
-    parser.add_option('--path', dest='pathonly', action="store_true",
-                      default=False, help='only search the path with -f')
-    parser.add_option('-g', '--gnupg', '--gpg', action='store_const',
-                      dest='sign', const='gpg',
-                      help='sign report with GNU Privacy Guard')
-    parser.add_option('-G', '--gnus', action='store_const', dest='mua',
-                      const=reportbug.MUA['gnus'],
-                      help='send the report using GNUS')
-    parser.add_option('--pgp', action='store_const', dest='sign',
-                      const='pgp', help='sign report with PGP')
-    parser.add_option('-K', '--keyid', type="string", dest="keyid",
-                      help="key ID to use for PGP/GnuPG signatures")
-    parser.add_option('-H', '--header', action='append', dest='headers',
-                      help='add a custom RFC822 header to your report')
-    parser.add_option('-P', '--pseudo-header', action='append', dest='pseudos',
-                      help='add a custom pseudo-header to your report')
-    parser.add_option('--license', action='store_true', default=False,
-                      help='show copyright and license information')
-    parser.add_option('-m', '--maintonly', action='store_const',
-                      dest='sendto', const='maintonly',
-                      help='send the report to the maintainer only')
-    parser.add_option('-M', '--mutt', action='store_const', dest='mua',
-                      const=reportbug.MUA['mutt'],
-                      help='send the report using mutt')
-    parser.add_option('--mirror', action='append', help='add a BTS mirror',
-                      dest='mirrors')
-    parser.add_option('-a', '--af', action='store_const', dest='mua',
-                      const=reportbug.MUA['af'],
-                      help='send the report using af')
-    parser.add_option('-n', '--mh', '--nmh', action='store_const', dest='mua',
-                      help='send the report using mh/nmh',
-                      const=reportbug.MUA['mh'])
-    parser.add_option('--mua', dest='mua',
-                      help='send the report using the specified mailer')
-    parser.add_option('--mta', dest='mta', help='send the report using the '
-                      'specified mail transport agent')
-    parser.add_option('--list-cc', action='append', dest='listcc',
-                      help='send a copy to the specified address')
-    parser.add_option('-p', '--print', action='store_true', dest='printonly',
-                      help='output the report to standard output only')
-    parser.add_option('--report-quiet', action='store_const', dest='sendto',
-                      const='quiet', help='file report without any mail to '
-                      'the maintainer or tracking lists')
-    parser.add_option('-q', '--quiet', action='store_true', dest='quietly',
-                      help='reduce the verbosity of the output', default=False)
-    parser.add_option('-s', '--subject', help='the subject for your report')
-    parser.add_option('-x', '--no-cc', dest='nocc', action='store_true',
-                      help='do not send a copy of the report to yourself')
-    parser.add_option('-z', '--no-compress', dest='nocompress',
-                      action='store_true', help='do not strip blank lines '
-                      'and comments from config files')
-    parser.add_option('-o', '--output', dest='outfile', help='output the '
-                      'report to the specified file')
-    parser.add_option('-O', '--offline', help='disable all external queries',
-                      action='store_true')
-    parser.add_option('-i', '--include', action='append',
-                      help='include the specified file in the report')
-    parser.add_option('-A', '--attach', action='append', dest='attachments',
-                      help='attach the specified file to the report')
-    parser.add_option('-b', '--no-query-bts', action='store_true',
-                      dest='dontquery',help='do not query the BTS for reports')
-    parser.add_option('--query-bts', action='store_false', dest='dontquery',
-                      help='query the BTS for reports')
-    parser.add_option('-T', '--tag', action='callback', dest='tags',
-                      callback=verify_append_option,  type='string',
-                      callback_args=('Permitted tags:',
-                                     debianbts.TAGLIST+['none']),
-                      help='add the specified tag to the report')
-    parser.add_option('--http_proxy', '--proxy', help='use this proxy for '
-                      'HTTP accesses')
-    parser.add_option('--email', help='specify originating email address')
-    parser.add_option('--realname', help='specify real name for your report')
-    parser.add_option('--smtphost', help='specify SMTP server for mailing')
-    parser.add_option('--tls', help='use TLS to talk to SMTP servers',
-                      dest="smtptls", action='store_true')
-    parser.add_option('--smtpuser', help='username to use for SMTP')
-    parser.add_option('--smtppasswd', help='password to use for SMTP')
-    parser.add_option('--replyto', '--reply-to', help='specify Reply-To '
-                      'address for your report')
-    parser.add_option('--query-source', action='store_true', dest='query_src',
-                      help='query on source packages, not binary packages')
-    parser.add_option('--no-query-source', action='store_false',
-                      dest='query_src', help='query on binary packages only')
-    parser.add_option('--debconf', action='store_true',
-                      help='include debconf settings in your report')
-    parser.add_option('--no-debconf', action='store_false', dest='debconf',
-                      help='exclude debconf settings from your report')
-    parser.add_option('-j', '--justification', help='include justification '
-                      'for the severity of your report')
-    parser.add_option('-V', '--package-version', dest='pkgversion',
-                      help='specify the version number for the package')
-    parser.add_option('-u', '--interface', '--ui', action='callback',
-                      callback=verify_option, type='string', dest='interface',
-                      callback_args=('Valid user interfaces',
-                                     reportbug.AVAILABLE_UIS),
-                      help='choose which user interface to use')
-    parser.add_option('-Q', '--query-only', action='store_true',
-                      dest='queryonly', help='only query the BTS')
-    parser.add_option('-t', '--type', action='callback', dest='type',
-                      callback=verify_option, type='string',
-                      callback_args=('Valid types of report:',
-                                     ('gnats', 'debbugs')),
-                      help='choose the type of report to file')
-    parser.add_option('-B', '--bts', action='callback', dest='bts',
-                      callback=verify_option, type='string',
-                      callback_args=('Valid bug tracking systems',
-                                     debianbts.SYSTEMS.keys()),
-                      help='choose BTS to file the report with')
-    parser.add_option('-S', '--severity', action='callback',
-                      callback=verify_option, type='string', dest='severity',
-                      callback_args=('Valid severities', debianbts.SEVLIST),
-                      help='identify the severity of the report')
-    parser.add_option('--template', action='store_true',
-                      help='output a template report only')
-    parser.add_option('--configure', action='store_true',
-                      help='reconfigure reportbug for this user')
-    parser.add_option('--check-available', action='store_true',
-                      help='check for new releases at packages.debian.org')
-    parser.add_option('--no-check-available', action='store_false',
-                      dest='check_available', help='do not check for new '
-                      'releases')
-    parser.add_option('--mode', action='callback', help='choose the operating '
-                      'mode for reportbug', callback=verify_option,
-                      type='string', dest='mode',
-                      callback_args=('Permitted operating modes',
-                                     reportbug.MODES.keys()))
-    parser.add_option('-v', '--verify', action='store_true', help='verify '
-                      'integrity of installed package using debsums')
-    parser.add_option('--no-verify', action='store_false', dest='verify',
-                      help='do not verify package installation')
-    parser.add_option('-k', '--kudos', action='store_true', default=False,
-                      help='send appreciative email to the maintainer, rather '
-                      'than filing a bug report')
-    parser.add_option('--check-installed', action='store_true',
-                      dest='querydpkg', help='check whether the specified '
-                      'package is installed when filing a report (default)')
-    parser.add_option('--body', dest="body", type="string",
-                      help="specify the body for the report as a string")
-    parser.add_option('--body-file', '--bodyfile', dest="bodyfile",
-                      type="string",
-                      help="use the specified file as the body of the report")
-    parser.add_option('-I', '--no-check-installed', action='store_false',
-                      default=True, dest='querydpkg',
-                      help='don\'t check whether the package is installed')
-    parser.add_option('--exit-prompt', action='store_true', dest='exitprompt',
-                      help='prompt before exiting')
-    parser.add_option('--paranoid', action='store_true', dest='paranoid',
-                      help='show contents of message before sending')
-    parser.add_option('--no-paranoid', action='store_false', dest='paranoid',
-                      help='don\'t show contents of message before sending '
-                      '(default)')
-
-    (options, args) = parser.parse_args()
-
-    # Load the interface, *before* the configuration step.
-    sys.argv = sys.argv[:1] + list(args)
-    if options.interface:
-        interface = options.interface
-        if interface in ('gnome', 'newt'):
-            ui.long_message("The %s interface is not supported.  Unless you "
-                            "are debugging reportbug, please do not use it.  "
-                            "If you are debugging reportbug, please DO NOT "
-                            "file bugs more serious than 'normal' that "
-                            "indicate problems with this interface.\n",
-                            interface)
-
-        iface = 'reportbug_ui_%(interface)s' % vars()
-        try:
-            lib_package = __import__('reportbuglib', fromlist=[iface])
-            ui = getattr(lib_package, iface)
-        except UINotImportable, msg:
-            ui.long_message('*** Unable to import %s interface: %s '
-                            'Falling back to text interface.\n',
-                            interface, msg)
-            ewrite('\n')
-
-        reportbug_submit.ui = ui
-        # Add INTERFACE as an environment variable to access it from the
-        # script gathering the special information for reportbug, when
-        # a new bug should be filed against it.
-        os.environ['INTERFACE'] = interface
-
-    iface = UI(options, args)
-    if not hasattr(ui, 'run_interface'):
-        return iface.user_interface()
-    return ui.run_interface(iface.user_interface)
-
-class UI(object):
-    def __init__(self, options, args):
-        self.options = options
-        self.args = args
-
-    def user_interface(self):
-        body = ''
-        filename = None
-        notatty = not ui.ISATTY
-
-        charset = locale.nl_langinfo(locale.CODESET)
-        # It would be nice if there were some canonical character set conversion
-        if charset.lower() == 'ansi_x3.4-1968':
-            charset = 'us-ascii'
-
-        # Allow the UI to know what charset we're using
-        ui.charset = charset
-
-        if self.options.configure:
-            offer_configuration(self.options)
-            sys.exit(0)
-        elif self.options.license:
-            print COPYRIGHT
-            print
-            print LICENSE
-            sys.exit(0)
-
-        # These option values may get adjusted below, so give them a variable name.
-        sendto = self.options.sendto
-        check_available = self.options.check_available
-        dontquery = self.options.dontquery
-        headers = self.options.headers or []
-        pseudos = self.options.pseudos or []
-        mua = self.options.mua
-        pkgversion = self.options.pkgversion
-        quietly = self.options.quietly
-        severity = self.options.severity
-        smtphost = self.options.smtphost
-        subject = self.options.subject
-        bts = self.options.bts or 'debian'
-        sysinfo = debianbts.SYSTEMS[bts]
-        rtype = self.options.type or sysinfo.get('type')
-        attachments = self.options.attachments
-        pgp_addr = self.options.keyid
-
-        if self.options.body:
-            body = textwrap.fill(self.options.body)
-        elif self.options.bodyfile:
-            try:
-                body = file(self.options.bodyfile).read()
-            except:
-                ewrite('Unable to read body from file %s.\n', self.options.bodyfile)
-                sys.exit(1)
-
-        if body and not body.endswith('\n'):
-            body += '\n'
-
-        if self.options.queryonly:
-            check_available = False
-
-        if self.options.offline:
-            check_available = False
-            dontquery = True
-
-        if self.options.tags:
-            taglist = self.options.tags
-            if 'none' in taglist:
-                taglist = []
-        else:
-            taglist = []
-
-        if self.options.testmode:
-            self.options.debugmode = True
-            self.options.tags = ['none']
-            check_available = False
-            dontquery = True
-            severity = 'normal'
-            subject = 'testing'
-            taglist = []
-
-        interactive = True
-        if self.options.template:
-            check_available = interactive = False
-            dontquery = quietly = notatty = True
-            mua = smtphost = None
-            severity = severity or 'wishlist'
-            subject = subject or 'none'
-            taglist = taglist or []
-
-        if self.options.outfile or self.options.printonly:
-            mua = smtphost = None
-
-        if smtphost and smtphost.lower() == 'master.debian.org':
-            ui.long_message('*** Warning: master.debian.org is no longer an appropriate smtphost setting for reportbug; please update your .reportbugrc file.\n')
-            smtphost = 'bugs.debian.org'
-
-        if attachments and mua:
-            ewrite('Attachments are incompatible with using an MUA.  They will be ignored.\n')
-            attachments = []
-
-        if reportbug.first_run():
-            if not self.args:
-                offer_configuration(self.options)
-                main()
-                sys.exit(0)
-            else:
-                ewrite('Warning: no reportbug configuration found.  Proceeding in %s mode.\n' % self.options.mode)
-
-        mode = reportbug.MODELIST.index(self.options.mode)
-
-        # Disable signatures when in printonly or mua mode
-        # (since they'll be bogus anyway)
-        sign = self.options.sign
-        if (self.options.mua or self.options.printonly) and sign:
-            sign = ''
-            if self.options.mua:
-                ewrite('The signature option is ignored when using an MUA.\n')
-            elif self.options.printonly:
-                ewrite('The signature option is ignored when producing a template.\n')
-
-        uid = os.getuid()
-        if uid < MIN_USER_ID:
-            if notatty and not uid:
-                ewrite("reportbug will not run as root non-interactively.\n")
-                sys.exit(1)
-
-            if not uid or self.options.check_uid:
-                if not uid:
-                    message = "Running 'reportbug' as root is probably insecure!"
-                else:
-                    message = "Running 'reportbug' as an administrative user "\
-                              "is probably not a good idea!"
-                message += '  Continue'
-
-                if not ui.yes_no(message, 'Continue with reportbug.', 'Exit.',
-                                 False):
-                    ewrite("reportbug stopped.\n")
-                    sys.exit(1)
-
-        if (reportbug.first_run() and not self.args):
-            offer_configuration(self.options)
-            ewrite('To report a bug, please rerun reportbug.\n')
-            sys.exit(0)
-
-        foundfile = None
-        package = None
-        if not len(self.args) and not self.options.searchfor and not notatty:
-            package = get_package_name(bts, mode)
-        elif len(self.args) > 1:
-            ewrite("Please report one bug at a time.\n")
-            ewrite("[Did you forget to put all switches before the "
-                   "package name?]\n")
-            sys.exit(1)
-        elif self.options.searchfor:
-            (foundfile, package) = find_package_for(self.options.searchfor, notatty,
-                                                    self.options.pathonly)
-        elif len(self.args):
-            package = self.args[0]
-            if package and package.startswith('/'):
-                (foundfile, package) = find_package_for(package, notatty)
-
-        others = debianbts.SYSTEMS[bts].get('otherpkgs')
-        if package == 'other' and others:
-            package = get_other_package_name(others)
-
-        if not package:
-            efail("No package specified; stopping.\n")
-
-        tfprefix = tempfile_prefix(package)
-        if self.options.interface == 'text':
-            ewrite('*** Welcome to reportbug.  Use ? for help at prompts. ***\n')
-
-        try:
-            blah = u'hello'.encode(charset)
-        except LookupError:
-            ui.long_message(
-                'Unable to use specified character set "%s"; you probably need '
-                'either cjkcodecs (for users of Asian locales) or iconvcodec '
-                'installed.\nFalling back to ASCII encoding.\n', charset)
-            charset = 'us-ascii'
-        else:
-            ewrite("Detected character set: %s\n"
-                   "Please change your locale if this is incorrect.\n\n", charset)
-
-        fromaddr = reportbug.get_user_id(self.options.email, self.options.realname, charset)
-        ewrite("Using '%s' as your from address.\n", fromaddr.encode(charset, 'replace'))
-        fromaddr = fromaddr.encode('utf-8')
-        if self.options.debugmode:
-            sendto = fromaddr
-
-        edname = reportbug.which_editor(self.options.editor)
-        baseedname = os.path.basename(edname)
-        if baseedname == 'sensible-editor':
-            edname = reportbug.realpath('/usr/bin/editor')
-
-        if not notatty and 'vi' in baseedname and mode < MODE_STANDARD and \
-               'EDITOR' not in os.environ:
-            if not ui.yes_no('You appear to be using the "vi" editor, which is '
-                             'not suited for new users.  You probably want to '
-                             'change this setting by using "update-alternatives '
-                             '--config editor" as root.  (You can bypass this '
-                             'message in the future by using reportbug in '
-                             '"standard" mode or higher.) '
-                             'Do you want to continue?',
-                             'Continue filing this report.',
-                             'Stop reportbug to change editors.', False):
-                ewrite('Exiting per user request.\n')
-                sys.exit(1)
-
-        incfiles = u""
-        if self.options.include:
-            for f in self.options.include:
-                if os.path.exists(f):
-                    fp = file(f)
-                    incfiles = u'%s\n*** %s\n%s' % (
-                               incfiles, f.decode('utf-8', 'replace'),
-                               fp.read().decode('utf-8', 'replace'))
-                    fp.close()
-                else:
-                    ewrite("Can't find %s to include!\n", f)
-                    sys.exit(1)
-            incfiles += '\n'
-
-        pkgavail = maintainer = origin = src_name = state = ''
-        depends = []
-        recommends = []
-        suggests = []
-        conffiles = []
-        reportinfo = None
-        isvirtual = (package in sysinfo.get('otherpkgs', {}).keys() and
-                     package not in sysinfo.get('nonvirtual', []))
-        issource = installed = usedavail = False
-        status = None
-
-        if not pkgversion and self.options.querydpkg and \
-               sysinfo.get('query-dpkg', True):
-            ewrite("Getting status for %s...\n", package)
-            status = reportbug.get_package_status(package)
-
-            pkgavail, installed = status[1], status[6]
-            # Packages that only exist to do weird dependency things
-            deppkgs = sysinfo.get('deppkgs')
-            if pkgavail and deppkgs:
-                if installed and package in deppkgs:
-                    depends = status[2]
-                    if depends:
-                        newdepends = []
-                        for x in depends:
-                            newdepends.extend(x)
-                        depends = newdepends
-                        if len(depends) == 1:
-                            if mode < MODE_ADVANCED:
-                                ewrite('Dependency package "%s" corresponds to '
-                                   'actual package "%s".\n', package, depends[0])
-                                package = depends[0]
-                        else:
-                            opts = [(x,
-                                     (reportbug.get_package_status(x)[11] or
-                                      'not installed')) for x in depends]
-                            if mode >= MODE_ADVANCED:
-                                opts += [(package,
-                                          status[11]+' (dependency package)')]
-
-                            package = ui.menu('%s is a dependency package.  '
-                                              'Which of the following '
-                                              'packages is the bug in?' % package,
-                                              opts,
-                                              'Select one of these packages: ')
-                        ewrite("Getting status for %s...\n", package)
-                        status = reportbug.get_package_status(package)
-                        pkgavail, installed = status[1], status[6]
-
-            if not pkgavail and not isvirtual:
-                # Look for a matching source package
-                packages = reportbug.get_source_package(package)
-                if len(packages) > 0:
-                    src = package
-                    if len(packages) and not notatty:
-                        packages.sort()
-                        if src not in [x[0] for x in packages]:
-                            packages.append( (src, 'Source package') )
-
-                        if len(packages) > 1:
-                            package = ui.menu(
-                                'Which of the following packages is the bug in?',
-                                packages, empty_ok=True,
-                                prompt='Select one of these packages: ')
-                        else:
-                            package = packages[0][0]
-
-                    if not package:
-                        efail("No package specified; stopping.\n")
-
-                    if package != src:
-                        ewrite("Getting status for %s...\n", package)
-                        status = reportbug.get_package_status(package)
-                        pkgavail, installed = status[1], status[6]
-                    elif len(packages) > 1:
-                        issource = True
-                else:
-                    ewrite('No matching source or binary packages.\n')
-
-            if (not installed and not isvirtual and not issource) and not notatty:
-                packages = reportbug.packages_providing(package)
-                tmp = pack = None
-                if not packages:
-                    if ui.yes_no(
-                        'A package named "%s" does not appear to be installed; do '
-                        'you want to search for a similar-looking filename in '
-                        'an installed package' % package,
-                        'Look for a file with a similar filename.',
-                        'Continue filing with this package name.', True):
-                        pkgavail = False
-                    else:
-                        pack = package
-                        packages = [(package, '')]
-                        ewrite("Getting available info for %s...\n", package)
-                        status = reportbug.get_package_status(package, avail=True)
-                        check_available = False
-                        usedavail = True
-
-                if not packages and not pkgavail and not pack:
-                    (tmp, pack) = find_package_for(package, notatty)
-                    if pack:
-                        status = None
-                        if not ui.yes_no(
-                            "A package named '%s' does not appear to be installed "
-                            "on your system; however, '%s' contains a file named "
-                            "'%s'.  Do you want to file your report on the "
-                            "package reportbug found" % (package, pack, tmp),
-                            'Yes, use the package specified.',
-                            'No, give up the search.'):
-                            efail("Package not installed; stopping.\n")
-
-                if not status and pack:
-                    foundfile, package = tmp, pack
-                    ewrite("Getting status for %s...\n", package)
-                    status = reportbug.get_package_status(package)
-                elif not packages:
-                    if not ui.yes_no(
-                        'This package does not appear to be installed; continue '
-                        'with this report', 'Ignore this problem and continue.',
-                        'Exit without filing a report.', False):
-                        efail("Package not installed; stopping.\n")
-                elif (len(packages) > 1) or (packages[0][0] != package):
-                    this_package = [(package, 'Uninstalled/non-existent package')]
-                    packages.sort()
-                    package = ui.menu('Which of the following installed packages '
-                                      'is the bug in?', packages + this_package,
-                                      'Select one of these packages: ',
-                                      empty_ok=True)
-                    if not package:
-                        efail("No package specified; stopping.\n")
-                    else:
-                        ewrite("Getting status for %s...\n", package)
-                        status = reportbug.get_package_status(package)
-            elif not pkgavail and not notatty and not isvirtual and not issource:
-                if not ui.yes_no(
-                    'This package does not appear to exist; continue',
-                    'Ignore this problem and continue.',
-                    'Exit without filing a report.', False):
-                    efail("Package does not exist; stopping.\n")
-                    sys.exit(1)
-
-            (pkgversion, pkgavail, depends, recommends, conffiles, maintainer,
-             installed, origin, vendor, reportinfo, priority, desc, src_name,
-             fulldesc, state, suggests) = status
-
-        buginfo = '/usr/share/bug/' + package
-        bugexec = submitas = submitto = presubj = None
-        reportwith = []
-        supplemental = []
-        if os.path.isfile(buginfo) and os.access(buginfo, os.X_OK):
-            bugexec = buginfo
-        elif os.path.isdir(buginfo):
-            if os.path.isfile(buginfo+'/script') and os.access(buginfo+'/script', os.X_OK):
-                bugexec = buginfo+'/script'
-
-            if os.path.isfile(buginfo+'/presubj'):
-                presubj = buginfo+'/presubj'
-
-            if os.path.isfile(buginfo+'/control'):
-                submitas, submitto, reportwith, supplemental = \
-                          reportbug.parse_bug_control_file(buginfo+'/control')
-        elif os.path.isfile('/usr/share/bug/default/'+package) \
-             and os.access('/usr/share/bug/default/'+package, os.X_OK):
-            bugexec = '/usr/share/bug/default/'+package
-        elif os.path.isdir('/usr/share/bug/default/'+package):
-            buginfo = '/usr/share/bug/default/'+package
-            if os.path.isfile(buginfo+'/script') and os.access(buginfo+'/script',
-                                                               os.X_OK):
-                bugexec = buginfo+'/script'
-
-            if os.path.isfile(buginfo+'/presubj'):
-                presubj = buginfo+'/presubj'
-
-            if os.path.isfile(buginfo+'/control'):
-                submitas, submitto, reportwith, supplemental = \
-                          reportbug.parse_bug_control_file(buginfo+'/control')
-
-        if submitas and (submitas not in reportwith):
-            reportwith += [submitas]
-
-        if reportwith:
-            # Remove current package from report-with list
-            reportwith = [x for x in reportwith if x != package]
-
-        if (pkgavail and self.options.verify and os.path.exists('/usr/bin/debsums')
-            and not (notatty or self.options.kudos) and state == 'installed'):
-            ewrite('Verifying package integrity...\n')
-            rc, output = commands.getstatusoutput('/usr/bin/debsums -s'+
-                                                  commands.mkarg(package))
-            if rc:
-                if not ui.yes_no(
-                    'There may be a problem with your installation of '+package+
-                    ';\nthe following files appear to be missing or changed:\n'+
-                    output+'\nDo you still want to file a report',
-                    'Ignore this problem and continue.  This may be '
-                    'appropriate if you have fixed the package manually already.  '
-                    'This problem may also result from the use of localepurge.',
-                    'Exit without filing a report.', False, nowrap=True):
-                    efail("Package integrity check failed; stopping.\n")
-
-        if not pkgversion or usedavail or (not pkgavail and
-                                           not self.options.pkgversion):
-            if not (isvirtual or notatty):
-                pkgversion = ui.get_string('Please enter the version of the '
-                                           'package this report applies to '
-                                           '(blank OK)', force_prompt=True)
-        elif (check_available and not (self.options.kudos or notatty or self.options.offline)
-              and state == 'installed' and bts == 'debian'):
-            arch = reportbug.get_arch()
-            check_more = (mode > MODE_STANDARD)
-            if check_more:
-                ewrite('Checking for newer versions at packages.debian.org,'+
-                  ' incoming.debian.org and http://ftp-master.debian.org/new.html\n')
-            else:
-                ewrite('Checking for newer versions at packages.debian.org...\n')
-            (avail, toonew) = checkversions.check_available(
-                package, pkgversion, check_incoming=check_more,
-                check_newqueue=check_more,
-                http_proxy=self.options.http_proxy, arch=arch)
-            if toonew:
-                if not ui.yes_no(
-                    '\nYour version of %s (%s) is newer than that in Debian!\n'
-                    'Do you still want to file a report' % (package, pkgversion),
-                    'Ignore this problem and continue.  This may be '
-                    'appropriate if you know this bug is present in older '
-                    'releases of the package, or you\'re running a mixed '
-                    'stable/testing installation.',
-                    'Exit without filing a report.', False):
-                    efail("Newer released version; stopping.\n")
-
-            if avail:
-                availtext = ''
-                availlist = avail.keys()
-                availlist.sort()
-                for rel in availlist:
-                    availtext += '  %s: %s\n' % (rel, avail[rel])
-
-                if not ui.yes_no(
-                    ('\nYour version (%s) of %s appears to be out of date.\nThe '
-                    'following newer release(s) are available in the Debian '
-                    'archive:\n' % (pkgversion, package))+availtext+
-                    'Do you still want to file a report',
-                    'Ignore this problem and continue.  This may be '
-                    'appropriate if you know this bug is still present in more '
-                    'recent releases of the package.',
-                    'Exit without filing a report.', False, nowrap=True):
-                    efail("Newer released version; stopping.\n")
-
-        bts = DEFAULT_BTS
-        if self.options.bts:
-            bts = self.options.bts
-            ewrite("Will send report to %s (per request).\n",
-                   debianbts.SYSTEMS[bts].get('name', bts))
-        elif origin:
-            if origin.lower() == bts:
-                ewrite("Package originates from %s.\n", vendor or origin)
-                reportinfo = None
-            elif origin.lower() in debianbts.SYSTEMS.keys():
-                ewrite("Package originates from %s; overriding your system "
-                       "selection.\n", vendor or origin)
-                bts = origin.lower()
-                sysinfo = debianbts.SYSTEMS[bts]
-            elif reportinfo:
-                ewrite("Unknown origin %s; will send to %s.\n", origin,
-                       reportinfo[1])
-                rtype, submitto = reportinfo
-            elif submitto:
-                ewrite("Unknown origin %s; will send to %s.\n", origin, submitto)
-            else:
-                ewrite("Unknown origin %s; will send to %s.\n", origin, bts)
-        elif reportinfo:
-            rtype, submitto = reportinfo
-            ewrite("Will use %s protocol talking to %s.\n", rtype, submitto)
-            dontquery = True
-        else:
-            lsbr = commands.getoutput('lsb_release -si 2>/dev/null')
-            if lsbr:
-                distro = lsbr.strip().lower()
-                if distro in debianbts.SYSTEMS:
-                    bts = distro
-                    ewrite("Will send report to %s (per lsb_release).\n",
-                           debianbts.SYSTEMS[bts].get('name', bts))
-
-        if rtype == 'mailto':
-            rtype = 'debbugs'
-            dontquery = True
-
-        special = False
-        if not body and not subject and not notatty:
-            res = special_prompts(package, bts, ui, fromaddr)
-            if res:
-                (subject, severity, h, ph, body, query) = res
-                headers += h
-                pseudos += ph
-                if not query:
-                    dontquery = True
-                special = True
-
-        exinfo = None
-        if not (dontquery or notatty or self.options.kudos):
-            pkg, src = package, issource
-            if self.options.query_src:
-                src = True
-                if src_name:
-                    pkg = src_name
-            try:
-                exinfo = ui.handle_bts_query(pkg, bts, self.options.mirrors,
-                                             self.options.http_proxy,
-                                             source=src,
-                                             queryonly=self.options.queryonly,
-                                             version=pkgversion)
-            except UINotImplemented:
-                exinfo = None
-            except NoNetwork:
-                sys.exit(1)
-            except NoPackage:
-                if not self.options.queryonly and maintainer and ui.yes_no(
-                    'There is no record of this package in the bug tracking '
-                    'system.\nSend report directly to maintainer',
-                    'Send the report to the maintainer (%s).' % maintainer,
-                    'Send the report to the BTS anyway.'):
-                    rtype = 'debbugs'
-                    sendto = maintainer
-            except NoBugs:
-                ewrite('No bug reports found.\n')
-            except NoReport:
-                if self.options.queryonly:
-                    ewrite('Exiting at user request.\n')
-                else:
-                    ewrite('Nothing new to report; exiting.\n')
-                return
-
-            if self.options.queryonly and not exinfo:
-                return
-
-        ccaddr = os.environ.get('MAILCC')
-        if self.options.nocc:
-            bccaddr = os.environ.get('MAILBCC')
-        else:
-            bccaddr = os.environ.get('MAILBCC', fromaddr)
-
-        if maintainer:
-            mstr = u"Maintainer for %s is '%s'.\n" % (package, maintainer)
-            ewrite(mstr.encode(charset, 'replace'))
-            if 'qa.debian.org' in maintainer:
-                ui.long_message('''\
-This package is currently "orphaned"; if you are a current or prospective
-Debian developer, you might consider adopting it.  Please be aware that your
-report may not be resolved for a while, and that packages that have been
-orphaned for a long period of time are often removed from the archive.\n''')
-                ui.ewrite('\nFor more details, please see: http://www.debian.org/devel/wnpp/\n')
-
-        if self.options.kudos:
-            sendto = '%s at packages.debian.org' % package
-
-        depinfo = ""
-        # Grab dependency list, removing version conditions.
-        if (depends or recommends or suggests) and not self.options.kudos:
-            ewrite("Looking up dependencies of %s...\n", package)
-            depinfo = (reportbug.get_dependency_info(package, depends) +
-                       reportbug.get_dependency_info(package, recommends, "recommends") +
-                       reportbug.get_dependency_info(package, suggests, "suggests"))
-
-        if reportwith and not self.options.kudos:
-            for extrapackage in reportwith:
-                ewrite("Getting status for related package %s...\n", extrapackage)
-                extrastatus = reportbug.get_package_status(extrapackage)
-                if extrastatus[2]:
-                    extradepends = [x for x in extrastatus[2] if package not in x]
-                    ewrite("Looking up dependencies of related package %s...\n", extrapackage)
-                    depinfo += reportbug.get_dependency_info(extrapackage, extradepends)
-
-        if supplemental and not self.options.kudos:
-            ewrite("Looking up status of additional packages...\n")
-            depinfo += reportbug.get_dependency_info(
-                package, [[x] for x in supplemental], rel='is related to')
-
-        confinfo = []
-        if conffiles and not self.options.kudos:
-            ewrite("Getting changed configuration files...\n")
-            confinfo, changed = reportbug.get_changed_config_files(
-                conffiles, nocompress)
-
-            if self.options.noconf and changed:
-                for f in changed:
-                    confinfo[f] = 'changed [not included]'
-            elif changed and not notatty:
-                while 1:
-                    x = ui.select_self.options(
-                        "*** WARNING: The following configuration files have been "
-                        "modified:\n"+ "\n".join(changed)+
-                        "\nSend modified configuration files", 'Ynd',
-                        {'y':'Send your modified configuration files.',
-                         'n':"Don't send modified configuration files.",
-                         'd':'Display modified configuration files.'})
-                    if x == 'n':
-                        for f in changed:
-                            confinfo[f] = 'changed [not included]'
-                        break
-                    elif x == 'd':
-                        PAGER = os.environ.get('PAGER', '/usr/bin/sensible-pager')
-                        system(PAGER+' '+' '.join(changed))
-                    else:
-                        break
-
-        conftext = u''
-        if confinfo:
-            conftext = u'\n-- Configuration Files:\n'
-            files = confinfo.keys()
-            files.sort()
-            for f in files:
-                conftext = conftext + u'%s %s\n' % (f, confinfo[f])
-
-        if (self.options.debconf and os.path.exists('/usr/bin/debconf-show') and
-            not self.options.kudos and installed):
-            showpkgs = package
-            if reportwith:
-                showpkgs += ' ' + ' '.join(reportwith)
-            (status, output) = commands.getstatusoutput(
-                'DEBCONF_SYSTEMRC=1 DEBCONF_NOWARNINGS=yes '
-                '/usr/bin/debconf-show %s' % showpkgs )
-            if status:
-                conftext += '\n-- debconf-show failed\n'
-            elif output:
-                output = output.decode('utf-8', 'replace')
-                outstr = output.encode(charset, 'replace')
-                if (notatty or ui.yes_no(
-                    "*** The following debconf settings were detected:\n"
-                    +outstr+"\nInclude these settings in your report",
-                    'Send your debconf settings.',
-                    "Don't send your debconf settings.", nowrap=True)):
-                    conftext += u'\n-- debconf information:\n%s\n' % output
-                else:
-                    conftext += u'\n-- debconf information excluded\n'
-            else:
-                conftext += u'\n-- no debconf information\n'
-
-        ewrite('\n')
-        prompted = False
-        if interactive and not (self.options.kudos or exinfo) and presubj:
-            ui.display_report(file(presubj).read()+'\n')
-
-        if self.options.kudos:
-            subject = subject or ('Thanks for packaging %s!' % package)
-        elif exinfo:
-            if special:
-                body = ''
-            prompted = True
-            subject = ui.get_string(
-                'Please provide a subject for your response; no subject will '
-                'stop reportbug.', force_prompt=True)
-            # Check to make sure the bug still exists to avoid auto-reopens
-            if subject and pkgversion:
-                if not ui.yes_no('Does this bug still exist in version %s '
-                                 'of this package?' % pkgversion,
-                                 'Yes, it does.',
-                                 'No, it doesn\'t (or I don\'t know).',
-                                 default=False):
-                    pkgversion = None
-        elif not subject and not notatty:
-            prompted = True
-            subject = ui.get_string(
-                'Please briefly describe your problem (you can elaborate in '
-                'a moment; an empty response will stop reportbug).  This will '
-		'be the bug email subject, so write a concise summary of what '
-		'is wrong with the package, for example, "fails to send email" '
-		'or "does not start with -q option specified."', force_prompt=True)
-
-        if not subject:
-            efail("No subject specified; stopping.\n")
-
-        if len(subject) > 100 and prompted and mode < MODE_EXPERT:
-            subject = ui.get_string(
-                'Your description is a bit long; please enter a shorter subject. '
-                '(An empty response will retain the existing subject.)',
-                force_prompt=True) or subject
-        if package != 'wnpp' and prompted and mode < MODE_EXPERT:
-            if foundfile:
-                subject = foundfile + ": " + subject
-                ewrite("Rewriting subject to '%s'\n", subject)
-            elif (not re.match(r"\S+:\s", subject) and package not in subject):
-                subject = package + ": " + subject
-                ewrite("Rewriting subject to '%s'\n", subject)
-
-        listcc = self.options.listcc
-        if not listcc:
-            listcc = []
-
-        if not listcc and mode > MODE_STANDARD and rtype == 'debbugs' and not self.options.testmode and not self.options.template:
-            listcc += ui.get_multiline('Enter any additional addresses this report should be sent to; press ENTER after each address.')
-
-        if severity and rtype:
-            severity = debianbts.convert_severity(severity, rtype)
-
-        klass = self.options.klass
-        if not notatty and not (exinfo or self.options.kudos):
-            if not severity:
-                if rtype == 'gnats':
-                    severities = debianbts.SEVERITIES_gnats
-                    default = 'non-critical'
-                else:
-                    severities = debianbts.SEVERITIES
-                    default = 'normal'
-
-                severity = ui.menu("How would you rate the severity of this "
-                                   "problem or report?", severities,
-                                   'Please select a severity level: ',
-                                   default=default, order=debianbts.SEVLIST)
-
-            if rtype == 'gnats':
-                # Class of report
-                klass = ui.menu("What sort of problem are you reporting?",
-                                debianbts.CLASSES, 'Please select a class: ',
-                                default='sw-bug', order=debianbts.CLASSLIST)
-
-        severity = severity or 'normal'
-
-        justification = self.options.justification
-        if rtype == 'debbugs' and package != 'wnpp' and mode < MODE_EXPERT:
-            if severity in ('critical', 'grave'):
-                justification = ui.menu(
-                    'You are reporting a ' +severity+' bug; which of the '
-                    'following criteria does it meet?',
-                    debianbts.JUSTIFICATIONS[severity],
-                    'Please select the impact of the bug: ', default='unknown')
-            elif severity == 'serious':
-                justification = ui.get_string(
-                    'You are reporting a serious bug; which section of the '
-                    'Debian Policy Manual contains the "must" or "required" '
-                    'directive that it violates (E.g., "1.2.3")? '
-                    'Just type "unknown" if you are not sure (that would '
-                    'downgrade severity to normal).', force_prompt=True)
-                if re.match('[0-9]+\.[0-9.]+', justification):
-                    justification = 'Policy ' + justification
-                elif not justification:
-                    justification = 'unknown'
-
-            if justification == 'unknown':
-                justification = ''
-                severity = 'normal'
-                ewrite('Severity downgraded to "normal".\n')
-
-        if severity == 'does-not-build':
-            if pkgversion and not src_name:
-                src_name = package
-            if src_name and check_available and not notatty:
-                ewrite('Checking buildd.debian.org for past builds of %s...\n',
-                       src_name)
-                built = checkbuildd.check_built(src_name,
-                                                http_proxy=self.options.http_proxy)
-
-                if built:
-                    ewrite('Successful past builds... treating as serious.\n')
-                    severity = 'serious'
-                    justification = 'no longer builds from source'
-                else:
-                    ewrite('No successful builds... treating as important.\n')
-                    severity = 'important'
-                    justification = 'fails to build from source'
-            else:
-                if notatty:
-                    severity = 'important'
-                    justification = 'fails to build from source'
-                else:
-                    if ui.yes_no(
-                        'Has this package successfully been built for this '
-                        'architecture in the past (you can look this up at '
-                        'buildd.debian.org)',
-                        'Yes, this is a recently-introduced problem.',
-                        'No, it has always been this way.'):
-                        severity = 'serious'
-                        justification = 'no longer builds from source'
-                    else:
-                        severity = 'important'
-                        justification = 'fails to build from source'
-
-        HOMEDIR = os.environ.get('HOME', '/')
-
-        if (rtype == 'debbugs' and not self.options.tags and
-            not (notatty or self.options.kudos or exinfo) and package not in ('wnpp','ftp.debian.org') and
-            mode > MODE_NOVICE):
-            # Multiple-choice checkbox
-            if severity in ('grave', 'critical', 'serious'):
-                tags = debianbts.TAGS.copy()
-                tags.update(debianbts.CRITICAL_TAGS)
-                tagorder = debianbts.TAGLIST + debianbts.CRITICAL_TAGLIST
-            else:
-                tags = debianbts.TAGS
-                tagorder = debianbts.TAGLIST
-
-            taglist = ui.select_multiple(
-                'Do any of the following apply to this report?', tags,
-                'Please select tags: ', order=tagorder,
-                extras=debianbts.EXTRA_TAGS)
-
-        patch = ('patch' in taglist)
-
-        if justification and 'security' not in taglist and 'security' in \
-               justification:
-            ewrite('Adding security tag to this report.\n')
-            taglist += ['security']
-
-        if taglist:
-            tags = ' '.join(taglist)
-        else:
-            tags = ''
-
-        # Execute bug script
-        if (interactive or self.options.template) and bugexec and not self.options.kudos:
-            if os.path.exists('handle_bugscript'):
-                handler = './handle_bugscript'
-            else:
-                handler = '/usr/share/reportbug/handle_bugscript'
-
-            fh, filename = TempFile(prefix=tfprefix)
-            fh.close()
-            system('%s %s %s' % (handler, commands.mkarg(bugexec),
-                                 commands.mkarg(filename)))
-
-            addinfo = None
-            if not self.options.noconf:
-                fp = open(filename)
-                addinfo = u"\n-- Package-specific info:\n"+fp.read().decode('utf-8', 'replace')
-                fp.close()
-
-            cleanup_temp_file(filename)
-            if addinfo and incfiles:
-                incfiles = addinfo + u"\n" + incfiles
-            elif addinfo:
-                incfiles = addinfo
-
-        if bts == 'debian' and 'security' in taglist:
-            ewrite('Will send a CC of this report to the Debian Security and Testing Security Team.\n')
-            listcc += ['Debian Security Team <team at security.debian.org>']
-            listcc += ['Debian Testing Security Team <secure-testing-team at lists.alioth.debian.org>']
-
-        if listcc:
-            headers.append('X-Debbugs-CC: '+', '.join(listcc))
-
-        # Prepare bug report
-        if self.options.kudos:
-            message = u'\n\n'
-            if not mua:
-                SIGFILE = os.path.join(HOMEDIR, '.signature')
-                try:
-                    message = u"\n\n-- \n"+file(SIGFILE).read().decode('utf-8', 'replace')
-                except IOError:
-                    pass
-        else:
-            message = reportbug.generate_blank_report(
-                submitas or package, pkgversion, severity, justification,
-                depinfo, conftext, foundfile, incfiles, bts, exinfo, rtype,
-                klass, subject, tags, body, mode, pseudos)
-
-        # Substitute server email address
-        if submitto and '@' not in sendto:
-            if '@' in submitto:
-                sendto = submitto
-            else:
-                if exinfo:
-                    if sendto != 'submit':
-                        sendto = '%d-%s' % (exinfo, sendto)
-                    else:
-                        sendto = str(exinfo)
-
-                sendto = sendto+'@'+submitto
-        elif '@' not in sendto:
-            if exinfo:
-                if sendto != 'submit':
-                    sendto = '%d-%s' % (exinfo, sendto)
-                else:
-                    sendto = str(exinfo)
-
-            try:
-                sendto = sysinfo['email'] % sendto
-            except TypeError:
-                sendto = sysinfo['email']
-
-            sendto = rfc822.dump_address_pair((sysinfo['name']+
-                                               ' Bug Tracking System', sendto))
-
-        mailing = not (mua or self.options.printonly or self.options.template)
-        message = u"Subject: %s\n%s" % (subject, message)
-
-        if mailing:
-            fh, filename = TempFile(prefix=tfprefix)
-            fh.write(message.encode(charset, 'replace'))
-            fh.close()
-            oldmua = mua or self.options.mua
-            if not self.options.body and not self.options.bodyfile:
-                message = handle_editing(filename, message, self.options,
-                                         sendto, attachments, package,
-                                         charset=charset)
-            if not oldmua and self.options.mua:
-                mua = self.options.mua
-            if mua:
-                mailing = False
-            elif not sendto:
-                print message,
-                cleanup_temp_file(filename)
-                return
-
-            cleanup_temp_file(filename)
-
-            if not mua and patch and not attachments and not notatty:
-                while True:
-                    patchfile = ui.get_filename(
-                        'What is the filename of the patch (if none, or you have '
-                        'already included it, just press ENTER)?',
-                        force_prompt=True)
-                    if patchfile:
-                        attachfile = os.path.expanduser(patchfile)
-                        if os.path.exists(attachfile):
-                            attachments.append(attachfile)
-                            break
-                        else:
-                            ewrite('%s not found!', attachfile)
-                    else:
-                        break
-
-        body, headers, pseudoheaders = reportbug.cleanup_msg(message,headers,rtype)
-
-        if sign:
-            ewrite('Passing message to %s for signature...\n', sign)
-            oldbody = body
-            body = reportbug_submit.sign_message(body, fromaddr, package, pgp_addr,
-                                                 sign)
-            if not body:
-                ewrite('Signature failed; sending message unsigned.\n')
-                body = oldbody
-
-        if pseudoheaders:
-            body = '\n'.join(pseudoheaders)+'\n\n'+body
-
-        # Strip the body of useless whitespace at the end, then put a final
-        # newline in the message.  See #234963.
-        body = body.rstrip('\n')+'\n'
-
-        reportbug_submit.send_report(
-            body, attachments, mua, fromaddr, sendto, ccaddr, bccaddr,
-            headers, package, charset, mailing, sysinfo, rtype, exinfo,
-            self.options.replyto, self.options.printonly, self.options.template,
-            self.options.outfile, self.options.mta, self.options.kudos, self.options.smtptls,
-            smtphost, self.options.smtpuser, self.options.smtppasswd, self.options.paranoid)
-
-        if self.options.exitprompt:
-            ui.get_string('Please press ENTER to exit reportbug: ')
-        return
-
-if __name__ == '__main__':
-    try:
-        main()
-    except KeyboardInterrupt:
-        ewrite("\nreportbug: exiting due to user interrupt.\n")
-    except debianbts.Error, x:
-        ewrite('error accessing BTS: %s\n' % x)

Copied: trunk/reportbug_4merge (from rev 594, trunk/reportbug)
===================================================================
--- trunk/reportbug_4merge	                        (rev 0)
+++ trunk/reportbug_4merge	2008-08-06 21:49:13 UTC (rev 596)
@@ -0,0 +1,1831 @@
+#! /usr/bin/python
+# -*- python -*-
+# reportbug - Report a bug in the Debian distribution.
+#   Written by Chris Lawrence <lawrencc at debian.org>
+#   Copyright (C) 1999-2007 Chris Lawrence
+#
+# This program is freely distributable per the following license:
+#
+LICENSE="""\
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appears in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation.
+
+I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL I
+BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE."""
+#
+# Version ##VERSION##; see changelog for revision history
+# $Id: reportbug,v 1.98.2.33 2008-04-18 05:38:27 lawrencc Exp $
+
+DEBUGGER = 'lawrencc at debian.org'
+DEFAULT_BTS = 'debian'
+
+import sys, os
+sys.path = ['/usr/share/reportbug'] + sys.path
+
+import optparse
+import re
+import locale
+import commands
+import rfc822
+import gettext
+import textwrap
+
+from reportbuglib import reportbug
+from reportbuglib.reportbug import (
+    VERSION, COPYRIGHT,
+    MODE_EXPERT, MODE_ADVANCED, MODE_NOVICE, MODE_STANDARD,
+    )
+from reportbuglib.rbtempfile import (
+    TempFile,
+    tempfile_prefix,
+    cleanup_temp_file,
+    )
+from reportbuglib.reportbug_exceptions import (
+    UINotImportable, UINotImplemented,
+    NoNetwork, NoPackage, NoBugs, NoReport,
+    )
+from reportbuglib import reportbug_submit
+from reportbuglib import checkversions
+from reportbuglib import debianbts
+from reportbuglib import checkbuildd
+from reportbuglib import reportbug_ui_text as ui
+
+try:
+    gettext.install('reportbug')
+except IOError:
+    pass
+
+# Magic constant time
+MIN_USER_ID = 250
+
+quietly = False
+
+# Cheat for now.
+# ewrite() may put stuff on the status bar or in message boxes depending on UI
+def ewrite(*args):
+    return quietly or ui.log_message(*args)
+
+def efail(*args):
+    ui.display_failure(*args)
+    sys.exit(1)
+
+# Lame message when we store a report as a temp file.
+def stopmsg(filename):
+    ui.final_message(
+        'reportbug stopped; your incomplete report is stored as "%s".\n'
+        'This file may be located in a temporary directory; if so, it might '
+        'disappear without any further notice. To recover this file to use '
+        'it as bug report body, please take a look at the "-i FILE, '
+        '--include=FILE" option.\n', filename)
+
+# Obscene hack :)
+def system(cmdline):
+    try:
+        x = os.getcwd()
+    except OSError:
+        os.chdir('/')
+    os.system(cmdline)
+
+def include_file_in_report(message, message_filename,
+                           attachment_filenames, package_name,
+                           include_filename, charset, inline=False):
+    """ Include a file in the report.
+
+        :parameters:
+            `message`
+                The current text of the message.
+            `message_filename`
+                The current message filename.
+            `attachment_filenames`
+                List of current attachment filenames.
+            `package_name`
+                Name of the package for this report.
+            `include_filename`
+                Full pathname of the file to be included.
+            `inline`
+                If True, include the message inline with the message
+                text. Otherwise, add the file path to the attachments.
+
+        :return value:
+            Tuple (`message`, `message_filename`, `attachments`) of
+            values as modified during the process of including the new
+            file.
+
+        """
+    if inline:
+        try:
+            fp = file(include_filename)
+            message += '\n*** %s\n%s' % (
+                       include_filename.decode(charset, 'replace'),
+                       fp.read().decode(charset, 'replace'))
+            fp.close()
+            fp, temp_filename = TempFile(
+                prefix=tempfile_prefix(package_name))
+            fp.write(message.encode(charset, 'replace'))
+            fp.close()
+            os.unlink(message_filename)
+            message_filename = temp_filename
+        except (IOError, OSError), exc:
+            ewrite('Unable to attach file %s\n%s\n',
+                   include_filename, str(exc))
+    else:
+        attachment_filenames.append(include_filename)
+
+    return (message, message_filename, attachment_filenames)
+
+def handle_editing(filename, dmessage, options, sendto, attachments, package,
+                   editor=None, charset='utf-8'):
+    if not editor:
+        editor = options.editor
+    editor = reportbug.which_editor(editor)
+    message = None
+    skip_editing = False
+    while True:
+        if not skip_editing:
+            (message, changed) = ui.spawn_editor(message or dmessage, filename,
+                                                 editor, charset)
+        skip_editing = False
+        if not message:
+            x = ''
+            while x != 'y':
+                x = ui.select_options('Done editing', 'Ynq',
+                                      {'y': 'Continue (editing done).',
+                                       'n': "Don't continue yet.",
+                                       'q': 'Exit without sending report.'})
+                if x == 'q':
+                    stopmsg(filename)
+                    sys.exit(1)
+
+            message = file(filename).read().decode(charset, 'replace')
+            changed = True
+
+        prompt = 'Submit this report on %s (e to edit)' % package
+
+        if options.kudos:
+            prompt = 'Send this message (e to edit)'
+            ewrite("Message will be sent to %s\n", sendto)
+        elif options.outfile:
+            ewrite("Report will be saved as %s\n", options.outfile)
+        else:
+            ewrite("Report will be sent to %s\n", sendto)
+
+        if attachments:
+            ewrite('Attachments:\n')
+            for name in attachments:
+                ewrite(' %s\n', name)
+
+        subject = re.search('^Subject: ', message, re.M | re.I)
+        if not subject:
+            ewrite('No subject found in message.  Please edit again.\n')
+
+        menuopts = "Ynaceilmpq"
+
+        if not changed or not subject:
+            menuopts = "ynacEilmpq"
+
+        # cfr Debian BTS #293361
+        if package == 'wnpp':
+            for itp_line in debianbts.itp_template.rsplit('\n'):
+                # if the line is not empty and it's in the message the user wrote
+                if itp_line in message and itp_line != '':
+                    ewrite("Wrong line: %s\n", itp_line)
+                    menuopts = "Eq"
+                    prompt = 'ERROR: you have composed an ITP with fields unchanged from the template; this will NOT be submitted. You should edit all fields so they contain correct values for your ITP (e to edit)'
+
+        x = ui.select_options(prompt, menuopts,
+                              {'y': 'Submit the bug report via email.',
+                               'n': "Don't submit the bug report; instead, "
+                               "save it in a temporary file (exits reportbug).",
+                               'q': "Save it in a temporary file and quit.",
+                               'a': "Attach a file.",
+                               'i': "Include a text file.",
+                               'c': "Change editor and re-edit.",
+                               'e': 'Re-edit the bug report.',
+                               'l': 'Pipe the message through the pager.',
+                               'p': 'Print message to stdout.',
+                               'm': "Choose a mailer to edit the report."})
+        if x in ('a', 'i'):
+            invalid = True
+            while invalid:
+                if x == 'i':
+                    attachfile = ui.get_filename('Choose a text file to include: ')
+                else:
+                    attachfile = ui.get_filename('Choose a file to attach: ')
+                if attachfile:
+                    attachfile = os.path.expanduser(attachfile)
+                    if os.access(attachfile, os.R_OK) and os.path.isfile(attachfile):
+                        invalid = False
+                        inline = (x == 'i')
+                        (message, filename, attachments) = include_file_in_report(
+                            message, filename, attachments, package,
+                            attachfile, charset, inline=inline)
+                        if not inline:
+                            skip_editing = True
+                    else:
+                        ewrite("Can't find %s to include!\n", attachfile)
+                else:
+                    break
+        elif x == 'c':
+            ed = ui.get_filename('Choose editor: ', default=options.editor)
+            if ed:
+                editor = ed
+        elif x == 'm':
+            mailers = [(x, '') for x in reportbug.MUA.keys()]
+            mailers.sort()
+            mailer = ui.menu('Choose a mailer for your report', mailers,
+                             'Select mailer: ', default='', empty_ok=True)
+            if mailer:
+                mailer = reportbug.MUA.get(mailer)
+                if mailer:
+                    options.mua = mailer
+                    break
+            skip_editing = True
+        elif x in ('n', 'q'):
+            stopmsg(filename)
+            sys.exit(1)
+        elif x in ('l', 'p'):
+            skip_editing = True
+            if x == 'l':
+                pager = os.environ.get('PAGER', 'sensible-pager')
+                os.popen(pager, 'w').write(message.encode(charset, 'replace'))
+            else:
+                sys.stdout.write(message.encode(charset, 'replace'))
+        elif x == 'y':
+            if message == dmessage:
+                x = ui.select_options(
+                    'Report is unchanged.  Edit this report or quit', 'Eqs',
+                    {'q': "Don't submit the bug report; instead, save it "
+                     "in a temporary file and quit.",
+                     'e': 'Re-edit the bug report.',
+                     's': 'Send report anyway.'})
+                if x == 'q':
+                    stopmsg(filename)
+                    sys.exit(1)
+                    break
+                elif x == 's':
+                    ewrite('Sending empty report anyway...\n')
+                    break
+            else:
+                break
+
+    return file(filename).read()
+
+def find_package_for(filename, notatty=False, pathonly=False):
+    ewrite("Finding package for '%s'...\n", filename)
+    (newfilename, packages) = reportbug.find_package_for(filename, pathonly)
+    if newfilename != filename:
+        filename = newfilename
+        ewrite("Resolved as '%s'.\n", filename)
+    if not packages:
+        ewrite("No packages match.\n")
+        return (filename, None)
+    elif len(packages) > 1:
+        packlist = packages.items()
+        packlist.sort()
+
+        if notatty:
+            print "Please re-run reportbug selecting one of these packages:"
+            for pkg, files in packlist:
+                print "  "+pkg
+            sys.exit(1)
+
+        packs = []
+        for pkg, files in packlist:
+            if len(files) > 3:
+                files[3:] = ['...']
+            packs.append( (pkg, ', '.join(files) ) )
+
+        package = ui.menu("Multiple packages match: ", packs, 'Select one '
+                          'of these packages: ', any_ok=True)
+        return (filename, package)
+    else:
+        package = packages.keys()[0]
+        ewrite("Using package '%s'.\n", package)
+        return (filename, package)
+
+def validate_package_name(package):
+    if not re.match(r'^[a-z0-9][a-z0-9\-\+\.]+$', package):
+        ui.long_message("%s is not a valid package name.", package)
+        package = None
+    return package
+
+def get_other_package_name(others):
+    """Displays the list of pseudo-packages and returns the one selected."""
+
+    result = ui.menu("Please enter the name of the package in which you "
+                     "have found a problem, or choose one of these bug "
+                     "categories:", others, "Enter a package: ", any_ok=True,
+                     default='')
+    if isinstance(result, basestring):
+        # If the package selected is kernel, we replace it with linux-image
+        # since it contains additional information useful to maintainer
+        if result == 'kernel':
+	    result = 'linux-image'
+        return result
+    else:
+        return None
+
+def get_package_name(bts='debian', mode=MODE_EXPERT):
+    others = debianbts.SYSTEMS[bts].get('otherpkgs')
+    prompt = "Please enter the name of the package in which you have found "\
+             "a problem"
+    if others:
+        prompt += ", or type 'other' to report a more general problem."
+    else:
+        prompt += '.'
+
+    options = []
+    pkglist = commands.getoutput('apt-cache pkgnames')
+    if pkglist:
+        options += pkglist.split()
+    if others:
+        options += others.keys()
+
+    package = None
+    while package is None:
+        package = ui.get_string(prompt, options, force_prompt=True)
+        if not package:
+            return
+        if others and package and package == 'other':
+            package = get_other_package_name(others)
+        if not package:
+            return
+        package = validate_package_name(package)
+
+    if mode < MODE_STANDARD:
+        if package == 'reportbug':
+            if not ui.yes_no('Is "reportbug" actually the package you are '
+                             'having problems with',
+                             'Yes, I am actually experiencing a problem with '
+                             'reportbug.',
+                             'No, I really meant to file a bug report on '
+                             'another package.'):
+                return get_package_name(bts, mode)
+
+    if mode < MODE_EXPERT:
+        if package in ('bugs.debian.org', 'debbugs'):
+            if ui.yes_no('Are you reporting a problem with this program '
+                         '(reportbug)', 'Yes, this is actually a bug in '
+                         'reportbug.', 'No, this is really a problem in the '
+                         'bug tracking system itself.'):
+                package = 'reportbug'
+
+        if package in ('general', 'project', 'debian-general', 'base'):
+            if not ui.yes_no(
+                "Are you sure this bug doesn't apply to a specific package?",
+                'Yes, this bug is truly general.',
+                'No, this is not really a general bug.', False):
+                return get_package_name(bts, mode)
+
+        if package == 'wnpp':
+            if not ui.yes_no(
+                'Are you sure you want to file a WNPP report?',
+                'Yes, I am a developer or know what I\'m doing.',
+                'No, I am not a developer and I don\'t know what wnpp means.',
+                False):
+                return get_package_name(bts, mode)
+
+        if package == 'ftp.debian.org':
+            if not ui.yes_no(
+                'Are you sure you want to file a bug on ftp.debian.org?',
+                'Yes, I am a developer or know what I\'m doing.',
+                'No, I am not a developer and I don\'t know what ftp.debian.org is.',
+                False):
+                return get_package_name(bts, mode)
+
+    return package
+
+def special_prompts(package, bts, ui, fromaddr):
+    prompts = debianbts.SYSTEMS[bts].get('specials')
+    if prompts:
+        pkgprompts = prompts.get(package)
+        if pkgprompts:
+            return pkgprompts(package, bts, ui, fromaddr)
+    return
+
+def offer_configuration(options):
+    charset = locale.nl_langinfo(locale.CODESET)
+    # It would be nice if there were some canonical character set conversion
+    if charset.lower() == 'ansi_x3.4-1968':
+        charset = 'us-ascii'
+    ui.charset = charset
+
+    if not options.configure:
+        ui.long_message('Welcome to reportbug!  Since it looks like this is '
+                        'the first time you have used reportbug, we are '
+                        'configuring its behavior.  These settings will be '
+                        'saved to the file "%s", which you will be free to '
+                        'edit further.\n\n', reportbug.USERFILE)
+    mode = ui.menu('Please choose the default operating mode for reportbug.',
+                   reportbug.MODES, 'Select mode: ', options.mode,
+                   order=reportbug.MODELIST)
+
+    uis = dict()
+    for i in reportbug.AVAILABLE_UIS:
+        if (i in reportbug.UIS) and i != 'newt':
+            uis[i] = reportbug.UIS[i]
+    if len(uis) > 1:
+        interface = ui.menu(
+            'Please choose the default interface for reportbug.', uis,
+            'Select interface: ', options.interface)
+    else:
+        interface = 'text'
+
+    online = ui.yes_no('Will reportbug often have direct '
+                       'Internet access?  (You should answer yes to this '
+                       'question unless you know what you are doing and '
+                       'plan to check whether duplicate reports have been '
+                       'filed via some other channel.)',
+                       'Yes, reportbug should assume it has access to the '
+                       'network always.',
+                       'No, I am only online occasionally to send and '
+                       'receive mail.',
+                       default=(not options.offline))
+
+    def_realname, def_email = reportbug.get_email()
+
+    try:
+        if options.realname:
+            realname = options.realname.encode(charset, 'replace')
+        else:
+            realname = def_realname.encode(charset, 'replace')
+    except UnicodeDecodeError:
+        realname = ''
+
+    realname = ui.get_string('What real name should be used for sending bug '
+                             'reports? [%s]' % realname, force_prompt=True)
+    if isinstance(realname, str):
+        realname = realname.decode(charset, 'replace')
+
+    from_addr = ui.get_string(
+        'Which of your email addresses should be used when sending bug '
+        'reports? (Note that this address will be visible in the bug tracking '
+        'system, so you may want to use a webmail address or another address '
+        'with good spam filtering capabilities.) [%s]' %
+        (options.email or def_email), force_prompt=True)
+
+    stupidmode = not ui.yes_no(
+        'Do you have a "mail transport agent" (MTA) like Exim, Postfix or '
+        'SSMTP configured on this computer to send mail to the Internet?',
+        'Yes, I can run /usr/sbin/sendmail without horrible things happening. '
+        'If you can send email from this machine without setting an SMTP Host '
+        'in your mailer, you should choose this answer.',
+        'No, I need to use an SMTP Host or I don\'t know if I have an MTA.',
+        (not options.smtphost))
+
+    if stupidmode:
+        opts = []
+        if options.smtphost:
+            opts += [options.smtphost]
+        smtphost = ui.get_string(
+            'Please enter the name of your SMTP host.  Usually it\'s called '
+            'something like "mail.example.org" or "smtp.example.org". '
+            'Just press ENTER if you don\'t have one or don\'t know.',
+            options=opts, force_prompt=True)
+        if smtphost:
+            stupidmode = False
+    else:
+        smtphost = ''
+
+    if smtphost:
+        smtpuser = ui.get_string(
+            ('If you need to use a user name to send email via "%s" on your '
+             'computer, please enter that user name.  Just press ENTER if you '
+             'don\'t need a user name.' % smtphost), force_prompt=True)
+    else:
+        smtpuser = ''
+
+    if os.path.exists(reportbug.USERFILE):
+        try:
+            os.rename(reportbug.USERFILE, reportbug.USERFILE+'~')
+        except OSError:
+            ewrite('Unable to rename %s as %s~\n', reportbug.USERFILE,
+                   reportbug.USERFILE)
+
+    try:
+        fd = os.open(reportbug.USERFILE, os.O_WRONLY|os.O_TRUNC|os.O_CREAT,
+                     0600)
+    except OSError, x:
+        ui.long_message('Unable to save %s; most likely, you do not have a '
+                        'home directory.  Please fix this before using '
+                        'reportbug again.\n', reportbug.USERFILE)
+        sys.exit(1)
+
+    fp = os.fdopen(fd, 'w')
+    print >> fp, '# reportbug preferences file'
+    print >> fp, '# character encoding: %s' % charset
+    print >> fp, '# Version of reportbug this preferences file was written by'
+    print >> fp, 'reportbug_version "##VERSION##"'
+    print >> fp, '# default operating mode: one of:',
+    print >> fp, ', '.join(reportbug.MODELIST)
+    print >> fp, 'mode %s' % mode
+    print >> fp, '# default user interface'
+    print >> fp, 'ui %s' % interface
+    print >> fp, '# offline setting - comment out to be online'
+    if not online:
+        print >> fp, 'offline'
+    else:
+        print >> fp, '#offline'
+    print >> fp, '# name and email setting (if non-default)'
+    rn = 'realname "%s"'
+    em = 'email "%s"'
+    email_addy = (from_addr or options.email or def_email)
+    email_name = (realname or options.realname or def_realname)
+
+    if email_name != def_realname:
+        print >> fp, rn % email_name.encode(charset, 'replace')
+    else:
+        print >> fp, '# '+(rn % email_name.encode(charset, 'replace'))
+
+    if email_addy != def_email:
+        print >> fp, em % email_addy
+    else:
+        print >> fp, '# '+(em % email_addy)
+
+    uid = os.getuid()
+    if uid < MIN_USER_ID:
+        print >> fp, '# Suppress user ID check for this user'
+        print >> fp, 'no-check-uid'
+
+    if smtphost:
+        print >> fp, '# Send all outgoing mail via the following host'
+        print >> fp, 'smtphost "%s"' % smtphost
+        if smtpuser:
+            print >> fp, 'smtpuser "%s"' % smtpuser
+            print >> fp, '#smtppasswd "my password here"'
+        else:
+            print >> fp, '# If you need to enter a user name and password:'
+            print >> fp, '#smtpuser "my username here"'
+            print >> fp, '#smtppasswd "my password here"'
+
+    if stupidmode:
+        print >> fp, '# Disable fallback mode by commenting out the following:'
+        print >> fp, 'no-cc'
+        print >> fp, 'header "X-Debbugs-CC: %s"' % email_addy
+        print >> fp, 'smtphost bugs.debian.org'
+    else:
+        print >> fp, '# If nothing else works, remove the # at the beginning'
+        print >> fp, '# of the following three lines:'
+        print >> fp, '#no-cc'
+        print >> fp, '#header "X-Debbugs-CC: %s"' % email_addy
+        print >> fp, '#smtphost bugs.debian.org'
+
+    print >> fp, '# You can add other settings after this line.  See'
+    print >> fp, '# /etc/reportbug.conf for a full listing of options.'
+    fp.close()
+    ui.final_message('Default preferences file written.  To reconfigure, '
+                     're-run reportbug with the "--configure" option.\n')
+
+def verify_option(option, opt, value, parser, *args):
+    heading, valid = args
+    if value == 'help':
+        ewrite('%s:\n %s\n' % (heading, '\n '.join(valid)))
+        sys.exit(1)
+    elif value in valid:
+        setattr(parser.values, option.dest, value)
+    else:
+        ewrite('Ignored bogus setting for %s: %s\n' % (opt, value))
+
+def verify_append_option(option, opt, value, parser, *args):
+    heading, valid = args
+    if value == 'help':
+        ewrite('%s:\n %s\n' % (heading, '\n '.join(valid)))
+        sys.exit(1)
+    elif value in valid:
+        try:
+            getattr(parser.values, option.dest).append(value)
+        except AttributeError:
+            setattr(parser.values, option.dest, [value])
+    else:
+        ewrite('Ignored bogus setting for %s: %s\n' % (opt, value))
+
+def main():
+    global quietly, ui
+
+    try:
+        locale.setlocale(locale.LC_ALL, '')
+    except locale.Error, x:
+        print >> sys.stderr, '*** Warning:', x
+
+    charset = locale.nl_langinfo(locale.CODESET)
+    # It would be nice if there were some canonical character set conversion
+    if charset.lower() == 'ansi_x3.4-1968':
+        charset = 'us-ascii'
+
+    defaults = dict(sendto="submit", mode="novice", mta="/usr/sbin/sendmail",
+                    check_available=True, query_src=True, debconf=True,
+                    editor='', offline=False, verify=True, check_uid=True,
+                    testmode=False, attachments=[], keyid='', body=None,
+                    bodyfile=None, smtptls=False, smtpuser='', smtppasswd='',
+                    paranoid=False)
+
+    if not sys.stdin.isatty():
+        defaults.update({ 'dontquery' : True, 'notatty' : True,
+                          'printonly' : True })
+
+    # Convention: consider `option.foo' names read-only; they always contain
+    # the original value as determined by the cascade of command-line options
+    # and configuration files.  When we need to adjust a value, we first say
+    # "foo = options.foo" and then refer to just `foo'.
+    args = reportbug.parse_config_files()
+    for option, arg in args.items():
+        if option in reportbug.CONFIG_ARGS:
+            if isinstance(arg, unicode):
+                arg = arg.encode(charset, 'replace')
+            defaults[option] = arg
+        else:
+            sys.stderr.write('Warning: untranslated token "%s"\n' % option)
+
+    parser = optparse.OptionParser(
+        usage='%prog [options] <package | filename>', version=VERSION)
+    parser.set_defaults(**defaults)
+    parser.add_option('-c', '--no-config-files', action="store_true",
+                      dest='noconf', help='do not include conffiles in report')
+    parser.add_option('-C', '--class', action='callback', type='string',
+                      callback=verify_option, dest="klass", metavar='CLASS',
+                      callback_args=('Permitted report classes:',
+                                     debianbts.CLASSLIST),
+                      help='specify report class for GNATS BTSes')
+    parser.add_option('-d', '--debug', action='store_true', default=False,
+                      dest='debugmode', help='send report only to yourself')
+    parser.add_option('--test', action="store_true", default=False,
+                      dest="testmode",
+                      help="operate in test mode (maintainer use only)")
+    parser.add_option('-e', '--editor', dest='editor',
+                      help='specify an editor for your report')
+    parser.add_option('-f', '--filename', dest='searchfor',
+                      help='file to search for')
+    parser.add_option('--path', dest='pathonly', action="store_true",
+                      default=False, help='only search the path with -f')
+    parser.add_option('-g', '--gnupg', '--gpg', action='store_const',
+                      dest='sign', const='gpg',
+                      help='sign report with GNU Privacy Guard')
+    parser.add_option('-G', '--gnus', action='store_const', dest='mua',
+                      const=reportbug.MUA['gnus'],
+                      help='send the report using GNUS')
+    parser.add_option('--pgp', action='store_const', dest='sign',
+                      const='pgp', help='sign report with PGP')
+    parser.add_option('-K', '--keyid', type="string", dest="keyid",
+                      help="key ID to use for PGP/GnuPG signatures")
+    parser.add_option('-H', '--header', action='append', dest='headers',
+                      help='add a custom RFC822 header to your report')
+    parser.add_option('-P', '--pseudo-header', action='append', dest='pseudos',
+                      help='add a custom pseudo-header to your report')
+    parser.add_option('--license', action='store_true', default=False,
+                      help='show copyright and license information')
+    parser.add_option('-m', '--maintonly', action='store_const',
+                      dest='sendto', const='maintonly',
+                      help='send the report to the maintainer only')
+    parser.add_option('-M', '--mutt', action='store_const', dest='mua',
+                      const=reportbug.MUA['mutt'],
+                      help='send the report using mutt')
+    parser.add_option('--mirror', action='append', help='add a BTS mirror',
+                      dest='mirrors')
+    parser.add_option('-a', '--af', action='store_const', dest='mua',
+                      const=reportbug.MUA['af'],
+                      help='send the report using af')
+    parser.add_option('-n', '--mh', '--nmh', action='store_const', dest='mua',
+                      help='send the report using mh/nmh',
+                      const=reportbug.MUA['mh'])
+    parser.add_option('--mua', dest='mua',
+                      help='send the report using the specified mailer')
+    parser.add_option('--mta', dest='mta', help='send the report using the '
+                      'specified mail transport agent')
+    parser.add_option('--list-cc', action='append', dest='listcc',
+                      help='send a copy to the specified address')
+    parser.add_option('-p', '--print', action='store_true', dest='printonly',
+                      help='output the report to standard output only')
+    parser.add_option('--report-quiet', action='store_const', dest='sendto',
+                      const='quiet', help='file report without any mail to '
+                      'the maintainer or tracking lists')
+    parser.add_option('-q', '--quiet', action='store_true', dest='quietly',
+                      help='reduce the verbosity of the output', default=False)
+    parser.add_option('-s', '--subject', help='the subject for your report')
+    parser.add_option('-x', '--no-cc', dest='nocc', action='store_true',
+                      help='do not send a copy of the report to yourself')
+    parser.add_option('-z', '--no-compress', dest='nocompress',
+                      action='store_true', help='do not strip blank lines '
+                      'and comments from config files')
+    parser.add_option('-o', '--output', dest='outfile', help='output the '
+                      'report to the specified file')
+    parser.add_option('-O', '--offline', help='disable all external queries',
+                      action='store_true')
+    parser.add_option('-i', '--include', action='append',
+                      help='include the specified file in the report')
+    parser.add_option('-A', '--attach', action='append', dest='attachments',
+                      help='attach the specified file to the report')
+    parser.add_option('-b', '--no-query-bts', action='store_true',
+                      dest='dontquery',help='do not query the BTS for reports')
+    parser.add_option('--query-bts', action='store_false', dest='dontquery',
+                      help='query the BTS for reports')
+    parser.add_option('-T', '--tag', action='callback', dest='tags',
+                      callback=verify_append_option,  type='string',
+                      callback_args=('Permitted tags:',
+                                     debianbts.TAGLIST+['none']),
+                      help='add the specified tag to the report')
+    parser.add_option('--http_proxy', '--proxy', help='use this proxy for '
+                      'HTTP accesses')
+    parser.add_option('--email', help='specify originating email address')
+    parser.add_option('--realname', help='specify real name for your report')
+    parser.add_option('--smtphost', help='specify SMTP server for mailing')
+    parser.add_option('--tls', help='use TLS to talk to SMTP servers',
+                      dest="smtptls", action='store_true')
+    parser.add_option('--smtpuser', help='username to use for SMTP')
+    parser.add_option('--smtppasswd', help='password to use for SMTP')
+    parser.add_option('--replyto', '--reply-to', help='specify Reply-To '
+                      'address for your report')
+    parser.add_option('--query-source', action='store_true', dest='query_src',
+                      help='query on source packages, not binary packages')
+    parser.add_option('--no-query-source', action='store_false',
+                      dest='query_src', help='query on binary packages only')
+    parser.add_option('--debconf', action='store_true',
+                      help='include debconf settings in your report')
+    parser.add_option('--no-debconf', action='store_false', dest='debconf',
+                      help='exclude debconf settings from your report')
+    parser.add_option('-j', '--justification', help='include justification '
+                      'for the severity of your report')
+    parser.add_option('-V', '--package-version', dest='pkgversion',
+                      help='specify the version number for the package')
+    parser.add_option('-u', '--interface', '--ui', action='callback',
+                      callback=verify_option, type='string', dest='interface',
+                      callback_args=('Valid user interfaces',
+                                     reportbug.AVAILABLE_UIS),
+                      help='choose which user interface to use')
+    parser.add_option('-Q', '--query-only', action='store_true',
+                      dest='queryonly', help='only query the BTS')
+    parser.add_option('-t', '--type', action='callback', dest='type',
+                      callback=verify_option, type='string',
+                      callback_args=('Valid types of report:',
+                                     ('gnats', 'debbugs')),
+                      help='choose the type of report to file')
+    parser.add_option('-B', '--bts', action='callback', dest='bts',
+                      callback=verify_option, type='string',
+                      callback_args=('Valid bug tracking systems',
+                                     debianbts.SYSTEMS.keys()),
+                      help='choose BTS to file the report with')
+    parser.add_option('-S', '--severity', action='callback',
+                      callback=verify_option, type='string', dest='severity',
+                      callback_args=('Valid severities', debianbts.SEVLIST),
+                      help='identify the severity of the report')
+    parser.add_option('--template', action='store_true',
+                      help='output a template report only')
+    parser.add_option('--configure', action='store_true',
+                      help='reconfigure reportbug for this user')
+    parser.add_option('--check-available', action='store_true',
+                      help='check for new releases at packages.debian.org')
+    parser.add_option('--no-check-available', action='store_false',
+                      dest='check_available', help='do not check for new '
+                      'releases')
+    parser.add_option('--mode', action='callback', help='choose the operating '
+                      'mode for reportbug', callback=verify_option,
+                      type='string', dest='mode',
+                      callback_args=('Permitted operating modes',
+                                     reportbug.MODES.keys()))
+    parser.add_option('-v', '--verify', action='store_true', help='verify '
+                      'integrity of installed package using debsums')
+    parser.add_option('--no-verify', action='store_false', dest='verify',
+                      help='do not verify package installation')
+    parser.add_option('-k', '--kudos', action='store_true', default=False,
+                      help='send appreciative email to the maintainer, rather '
+                      'than filing a bug report')
+    parser.add_option('--check-installed', action='store_true',
+                      dest='querydpkg', help='check whether the specified '
+                      'package is installed when filing a report (default)')
+    parser.add_option('--body', dest="body", type="string",
+                      help="specify the body for the report as a string")
+    parser.add_option('--body-file', '--bodyfile', dest="bodyfile",
+                      type="string",
+                      help="use the specified file as the body of the report")
+    parser.add_option('-I', '--no-check-installed', action='store_false',
+                      default=True, dest='querydpkg',
+                      help='don\'t check whether the package is installed')
+    parser.add_option('--exit-prompt', action='store_true', dest='exitprompt',
+                      help='prompt before exiting')
+    parser.add_option('--paranoid', action='store_true', dest='paranoid',
+                      help='show contents of message before sending')
+    parser.add_option('--no-paranoid', action='store_false', dest='paranoid',
+                      help='don\'t show contents of message before sending '
+                      '(default)')
+
+    (options, args) = parser.parse_args()
+
+    # Load the interface, *before* the configuration step.
+    sys.argv = sys.argv[:1] + list(args)
+    if options.interface:
+        interface = options.interface
+        if interface in ('gnome', 'newt'):
+            ui.long_message("The %s interface is not supported.  Unless you "
+                            "are debugging reportbug, please do not use it.  "
+                            "If you are debugging reportbug, please DO NOT "
+                            "file bugs more serious than 'normal' that "
+                            "indicate problems with this interface.\n",
+                            interface)
+
+        iface = 'reportbug_ui_%(interface)s' % vars()
+        try:
+            lib_package = __import__('reportbuglib', fromlist=[iface])
+            ui = getattr(lib_package, iface)
+        except UINotImportable, msg:
+            ui.long_message('*** Unable to import %s interface: %s '
+                            'Falling back to text interface.\n',
+                            interface, msg)
+            ewrite('\n')
+
+        reportbug_submit.ui = ui
+        # Add INTERFACE as an environment variable to access it from the
+        # script gathering the special information for reportbug, when
+        # a new bug should be filed against it.
+        os.environ['INTERFACE'] = interface
+
+    iface = UI(options, args)
+    if not hasattr(ui, 'run_interface'):
+        return iface.user_interface()
+    return ui.run_interface(iface.user_interface)
+
+class UI(object):
+    def __init__(self, options, args):
+        self.options = options
+        self.args = args
+
+    def user_interface(self):
+        body = ''
+        filename = None
+        notatty = not ui.ISATTY
+
+        charset = locale.nl_langinfo(locale.CODESET)
+        # It would be nice if there were some canonical character set conversion
+        if charset.lower() == 'ansi_x3.4-1968':
+            charset = 'us-ascii'
+
+        # Allow the UI to know what charset we're using
+        ui.charset = charset
+
+        if self.options.configure:
+            offer_configuration(self.options)
+            sys.exit(0)
+        elif self.options.license:
+            print COPYRIGHT
+            print
+            print LICENSE
+            sys.exit(0)
+
+        # These option values may get adjusted below, so give them a variable name.
+        sendto = self.options.sendto
+        check_available = self.options.check_available
+        dontquery = self.options.dontquery
+        headers = self.options.headers or []
+        pseudos = self.options.pseudos or []
+        mua = self.options.mua
+        pkgversion = self.options.pkgversion
+        quietly = self.options.quietly
+        severity = self.options.severity
+        smtphost = self.options.smtphost
+        subject = self.options.subject
+        bts = self.options.bts or 'debian'
+        sysinfo = debianbts.SYSTEMS[bts]
+        rtype = self.options.type or sysinfo.get('type')
+        attachments = self.options.attachments
+        pgp_addr = self.options.keyid
+
+        if self.options.body:
+            body = textwrap.fill(self.options.body)
+        elif self.options.bodyfile:
+            try:
+                body = file(self.options.bodyfile).read()
+            except:
+                ewrite('Unable to read body from file %s.\n', self.options.bodyfile)
+                sys.exit(1)
+
+        if body and not body.endswith('\n'):
+            body += '\n'
+
+        if self.options.queryonly:
+            check_available = False
+
+        if self.options.offline:
+            check_available = False
+            dontquery = True
+
+        if self.options.tags:
+            taglist = self.options.tags
+            if 'none' in taglist:
+                taglist = []
+        else:
+            taglist = []
+
+        if self.options.testmode:
+            self.options.debugmode = True
+            self.options.tags = ['none']
+            check_available = False
+            dontquery = True
+            severity = 'normal'
+            subject = 'testing'
+            taglist = []
+
+        interactive = True
+        if self.options.template:
+            check_available = interactive = False
+            dontquery = quietly = notatty = True
+            mua = smtphost = None
+            severity = severity or 'wishlist'
+            subject = subject or 'none'
+            taglist = taglist or []
+
+        if self.options.outfile or self.options.printonly:
+            mua = smtphost = None
+
+        if smtphost and smtphost.lower() == 'master.debian.org':
+            ui.long_message('*** Warning: master.debian.org is no longer an appropriate smtphost setting for reportbug; please update your .reportbugrc file.\n')
+            smtphost = 'bugs.debian.org'
+
+        if attachments and mua:
+            ewrite('Attachments are incompatible with using an MUA.  They will be ignored.\n')
+            attachments = []
+
+        if reportbug.first_run():
+            if not self.args:
+                offer_configuration(self.options)
+                main()
+                sys.exit(0)
+            else:
+                ewrite('Warning: no reportbug configuration found.  Proceeding in %s mode.\n' % self.options.mode)
+
+        mode = reportbug.MODELIST.index(self.options.mode)
+
+        # Disable signatures when in printonly or mua mode
+        # (since they'll be bogus anyway)
+        sign = self.options.sign
+        if (self.options.mua or self.options.printonly) and sign:
+            sign = ''
+            if self.options.mua:
+                ewrite('The signature option is ignored when using an MUA.\n')
+            elif self.options.printonly:
+                ewrite('The signature option is ignored when producing a template.\n')
+
+        uid = os.getuid()
+        if uid < MIN_USER_ID:
+            if notatty and not uid:
+                ewrite("reportbug will not run as root non-interactively.\n")
+                sys.exit(1)
+
+            if not uid or self.options.check_uid:
+                if not uid:
+                    message = "Running 'reportbug' as root is probably insecure!"
+                else:
+                    message = "Running 'reportbug' as an administrative user "\
+                              "is probably not a good idea!"
+                message += '  Continue'
+
+                if not ui.yes_no(message, 'Continue with reportbug.', 'Exit.',
+                                 False):
+                    ewrite("reportbug stopped.\n")
+                    sys.exit(1)
+
+        if (reportbug.first_run() and not self.args):
+            offer_configuration(self.options)
+            ewrite('To report a bug, please rerun reportbug.\n')
+            sys.exit(0)
+
+        foundfile = None
+        package = None
+        if not len(self.args) and not self.options.searchfor and not notatty:
+            package = get_package_name(bts, mode)
+        elif len(self.args) > 1:
+            ewrite("Please report one bug at a time.\n")
+            ewrite("[Did you forget to put all switches before the "
+                   "package name?]\n")
+            sys.exit(1)
+        elif self.options.searchfor:
+            (foundfile, package) = find_package_for(self.options.searchfor, notatty,
+                                                    self.options.pathonly)
+        elif len(self.args):
+            package = self.args[0]
+            if package and package.startswith('/'):
+                (foundfile, package) = find_package_for(package, notatty)
+
+        others = debianbts.SYSTEMS[bts].get('otherpkgs')
+        if package == 'other' and others:
+            package = get_other_package_name(others)
+
+        if not package:
+            efail("No package specified; stopping.\n")
+
+        tfprefix = tempfile_prefix(package)
+        if self.options.interface == 'text':
+            ewrite('*** Welcome to reportbug.  Use ? for help at prompts. ***\n')
+
+        try:
+            blah = u'hello'.encode(charset)
+        except LookupError:
+            ui.long_message(
+                'Unable to use specified character set "%s"; you probably need '
+                'either cjkcodecs (for users of Asian locales) or iconvcodec '
+                'installed.\nFalling back to ASCII encoding.\n', charset)
+            charset = 'us-ascii'
+        else:
+            ewrite("Detected character set: %s\n"
+                   "Please change your locale if this is incorrect.\n\n", charset)
+
+        fromaddr = reportbug.get_user_id(self.options.email, self.options.realname, charset)
+        ewrite("Using '%s' as your from address.\n", fromaddr.encode(charset, 'replace'))
+        fromaddr = fromaddr.encode('utf-8')
+        if self.options.debugmode:
+            sendto = fromaddr
+
+        edname = reportbug.which_editor(self.options.editor)
+        baseedname = os.path.basename(edname)
+        if baseedname == 'sensible-editor':
+            edname = reportbug.realpath('/usr/bin/editor')
+
+        if not notatty and 'vi' in baseedname and mode < MODE_STANDARD and \
+               'EDITOR' not in os.environ:
+            if not ui.yes_no('You appear to be using the "vi" editor, which is '
+                             'not suited for new users.  You probably want to '
+                             'change this setting by using "update-alternatives '
+                             '--config editor" as root.  (You can bypass this '
+                             'message in the future by using reportbug in '
+                             '"standard" mode or higher.) '
+                             'Do you want to continue?',
+                             'Continue filing this report.',
+                             'Stop reportbug to change editors.', False):
+                ewrite('Exiting per user request.\n')
+                sys.exit(1)
+
+        incfiles = u""
+        if self.options.include:
+            for f in self.options.include:
+                if os.path.exists(f):
+                    fp = file(f)
+                    incfiles = u'%s\n*** %s\n%s' % (
+                               incfiles, f.decode('utf-8', 'replace'),
+                               fp.read().decode('utf-8', 'replace'))
+                    fp.close()
+                else:
+                    ewrite("Can't find %s to include!\n", f)
+                    sys.exit(1)
+            incfiles += '\n'
+
+        pkgavail = maintainer = origin = src_name = state = ''
+        depends = []
+        recommends = []
+        suggests = []
+        conffiles = []
+        reportinfo = None
+        isvirtual = (package in sysinfo.get('otherpkgs', {}).keys() and
+                     package not in sysinfo.get('nonvirtual', []))
+        issource = installed = usedavail = False
+        status = None
+
+        if not pkgversion and self.options.querydpkg and \
+               sysinfo.get('query-dpkg', True):
+            ewrite("Getting status for %s...\n", package)
+            status = reportbug.get_package_status(package)
+
+            pkgavail, installed = status[1], status[6]
+            # Packages that only exist to do weird dependency things
+            deppkgs = sysinfo.get('deppkgs')
+            if pkgavail and deppkgs:
+                if installed and package in deppkgs:
+                    depends = status[2]
+                    if depends:
+                        newdepends = []
+                        for x in depends:
+                            newdepends.extend(x)
+                        depends = newdepends
+                        if len(depends) == 1:
+                            if mode < MODE_ADVANCED:
+                                ewrite('Dependency package "%s" corresponds to '
+                                   'actual package "%s".\n', package, depends[0])
+                                package = depends[0]
+                        else:
+                            opts = [(x,
+                                     (reportbug.get_package_status(x)[11] or
+                                      'not installed')) for x in depends]
+                            if mode >= MODE_ADVANCED:
+                                opts += [(package,
+                                          status[11]+' (dependency package)')]
+
+                            package = ui.menu('%s is a dependency package.  '
+                                              'Which of the following '
+                                              'packages is the bug in?' % package,
+                                              opts,
+                                              'Select one of these packages: ')
+                        ewrite("Getting status for %s...\n", package)
+                        status = reportbug.get_package_status(package)
+                        pkgavail, installed = status[1], status[6]
+
+            if not pkgavail and not isvirtual:
+                # Look for a matching source package
+                packages = reportbug.get_source_package(package)
+                if len(packages) > 0:
+                    src = package
+                    if len(packages) and not notatty:
+                        packages.sort()
+                        if src not in [x[0] for x in packages]:
+                            packages.append( (src, 'Source package') )
+
+                        if len(packages) > 1:
+                            package = ui.menu(
+                                'Which of the following packages is the bug in?',
+                                packages, empty_ok=True,
+                                prompt='Select one of these packages: ')
+                        else:
+                            package = packages[0][0]
+
+                    if not package:
+                        efail("No package specified; stopping.\n")
+
+                    if package != src:
+                        ewrite("Getting status for %s...\n", package)
+                        status = reportbug.get_package_status(package)
+                        pkgavail, installed = status[1], status[6]
+                    elif len(packages) > 1:
+                        issource = True
+                else:
+                    ewrite('No matching source or binary packages.\n')
+
+            if (not installed and not isvirtual and not issource) and not notatty:
+                packages = reportbug.packages_providing(package)
+                tmp = pack = None
+                if not packages:
+                    if ui.yes_no(
+                        'A package named "%s" does not appear to be installed; do '
+                        'you want to search for a similar-looking filename in '
+                        'an installed package' % package,
+                        'Look for a file with a similar filename.',
+                        'Continue filing with this package name.', True):
+                        pkgavail = False
+                    else:
+                        pack = package
+                        packages = [(package, '')]
+                        ewrite("Getting available info for %s...\n", package)
+                        status = reportbug.get_package_status(package, avail=True)
+                        check_available = False
+                        usedavail = True
+
+                if not packages and not pkgavail and not pack:
+                    (tmp, pack) = find_package_for(package, notatty)
+                    if pack:
+                        status = None
+                        if not ui.yes_no(
+                            "A package named '%s' does not appear to be installed "
+                            "on your system; however, '%s' contains a file named "
+                            "'%s'.  Do you want to file your report on the "
+                            "package reportbug found" % (package, pack, tmp),
+                            'Yes, use the package specified.',
+                            'No, give up the search.'):
+                            efail("Package not installed; stopping.\n")
+
+                if not status and pack:
+                    foundfile, package = tmp, pack
+                    ewrite("Getting status for %s...\n", package)
+                    status = reportbug.get_package_status(package)
+                elif not packages:
+                    if not ui.yes_no(
+                        'This package does not appear to be installed; continue '
+                        'with this report', 'Ignore this problem and continue.',
+                        'Exit without filing a report.', False):
+                        efail("Package not installed; stopping.\n")
+                elif (len(packages) > 1) or (packages[0][0] != package):
+                    this_package = [(package, 'Uninstalled/non-existent package')]
+                    packages.sort()
+                    package = ui.menu('Which of the following installed packages '
+                                      'is the bug in?', packages + this_package,
+                                      'Select one of these packages: ',
+                                      empty_ok=True)
+                    if not package:
+                        efail("No package specified; stopping.\n")
+                    else:
+                        ewrite("Getting status for %s...\n", package)
+                        status = reportbug.get_package_status(package)
+            elif not pkgavail and not notatty and not isvirtual and not issource:
+                if not ui.yes_no(
+                    'This package does not appear to exist; continue',
+                    'Ignore this problem and continue.',
+                    'Exit without filing a report.', False):
+                    efail("Package does not exist; stopping.\n")
+                    sys.exit(1)
+
+            (pkgversion, pkgavail, depends, recommends, conffiles, maintainer,
+             installed, origin, vendor, reportinfo, priority, desc, src_name,
+             fulldesc, state, suggests) = status
+
+        buginfo = '/usr/share/bug/' + package
+        bugexec = submitas = submitto = presubj = None
+        reportwith = []
+        supplemental = []
+        if os.path.isfile(buginfo) and os.access(buginfo, os.X_OK):
+            bugexec = buginfo
+        elif os.path.isdir(buginfo):
+            if os.path.isfile(buginfo+'/script') and os.access(buginfo+'/script', os.X_OK):
+                bugexec = buginfo+'/script'
+
+            if os.path.isfile(buginfo+'/presubj'):
+                presubj = buginfo+'/presubj'
+
+            if os.path.isfile(buginfo+'/control'):
+                submitas, submitto, reportwith, supplemental = \
+                          reportbug.parse_bug_control_file(buginfo+'/control')
+        elif os.path.isfile('/usr/share/bug/default/'+package) \
+             and os.access('/usr/share/bug/default/'+package, os.X_OK):
+            bugexec = '/usr/share/bug/default/'+package
+        elif os.path.isdir('/usr/share/bug/default/'+package):
+            buginfo = '/usr/share/bug/default/'+package
+            if os.path.isfile(buginfo+'/script') and os.access(buginfo+'/script',
+                                                               os.X_OK):
+                bugexec = buginfo+'/script'
+
+            if os.path.isfile(buginfo+'/presubj'):
+                presubj = buginfo+'/presubj'
+
+            if os.path.isfile(buginfo+'/control'):
+                submitas, submitto, reportwith, supplemental = \
+                          reportbug.parse_bug_control_file(buginfo+'/control')
+
+        if submitas and (submitas not in reportwith):
+            reportwith += [submitas]
+
+        if reportwith:
+            # Remove current package from report-with list
+            reportwith = [x for x in reportwith if x != package]
+
+        if (pkgavail and self.options.verify and os.path.exists('/usr/bin/debsums')
+            and not (notatty or self.options.kudos) and state == 'installed'):
+            ewrite('Verifying package integrity...\n')
+            rc, output = commands.getstatusoutput('/usr/bin/debsums -s'+
+                                                  commands.mkarg(package))
+            if rc:
+                if not ui.yes_no(
+                    'There may be a problem with your installation of '+package+
+                    ';\nthe following files appear to be missing or changed:\n'+
+                    output+'\nDo you still want to file a report',
+                    'Ignore this problem and continue.  This may be '
+                    'appropriate if you have fixed the package manually already.  '
+                    'This problem may also result from the use of localepurge.',
+                    'Exit without filing a report.', False, nowrap=True):
+                    efail("Package integrity check failed; stopping.\n")
+
+        if not pkgversion or usedavail or (not pkgavail and
+                                           not self.options.pkgversion):
+            if not (isvirtual or notatty):
+                pkgversion = ui.get_string('Please enter the version of the '
+                                           'package this report applies to '
+                                           '(blank OK)', force_prompt=True)
+        elif (check_available and not (self.options.kudos or notatty or self.options.offline)
+              and state == 'installed' and bts == 'debian'):
+            arch = reportbug.get_arch()
+            check_more = (mode > MODE_STANDARD)
+            if check_more:
+                ewrite('Checking for newer versions at packages.debian.org,'+
+                  ' incoming.debian.org and http://ftp-master.debian.org/new.html\n')
+            else:
+                ewrite('Checking for newer versions at packages.debian.org...\n')
+            (avail, toonew) = checkversions.check_available(
+                package, pkgversion, check_incoming=check_more,
+                check_newqueue=check_more,
+                http_proxy=self.options.http_proxy, arch=arch)
+            if toonew:
+                if not ui.yes_no(
+                    '\nYour version of %s (%s) is newer than that in Debian!\n'
+                    'Do you still want to file a report' % (package, pkgversion),
+                    'Ignore this problem and continue.  This may be '
+                    'appropriate if you know this bug is present in older '
+                    'releases of the package, or you\'re running a mixed '
+                    'stable/testing installation.',
+                    'Exit without filing a report.', False):
+                    efail("Newer released version; stopping.\n")
+
+            if avail:
+                availtext = ''
+                availlist = avail.keys()
+                availlist.sort()
+                for rel in availlist:
+                    availtext += '  %s: %s\n' % (rel, avail[rel])
+
+                if not ui.yes_no(
+                    ('\nYour version (%s) of %s appears to be out of date.\nThe '
+                    'following newer release(s) are available in the Debian '
+                    'archive:\n' % (pkgversion, package))+availtext+
+                    'Do you still want to file a report',
+                    'Ignore this problem and continue.  This may be '
+                    'appropriate if you know this bug is still present in more '
+                    'recent releases of the package.',
+                    'Exit without filing a report.', False, nowrap=True):
+                    efail("Newer released version; stopping.\n")
+
+        bts = DEFAULT_BTS
+        if self.options.bts:
+            bts = self.options.bts
+            ewrite("Will send report to %s (per request).\n",
+                   debianbts.SYSTEMS[bts].get('name', bts))
+        elif origin:
+            if origin.lower() == bts:
+                ewrite("Package originates from %s.\n", vendor or origin)
+                reportinfo = None
+            elif origin.lower() in debianbts.SYSTEMS.keys():
+                ewrite("Package originates from %s; overriding your system "
+                       "selection.\n", vendor or origin)
+                bts = origin.lower()
+                sysinfo = debianbts.SYSTEMS[bts]
+            elif reportinfo:
+                ewrite("Unknown origin %s; will send to %s.\n", origin,
+                       reportinfo[1])
+                rtype, submitto = reportinfo
+            elif submitto:
+                ewrite("Unknown origin %s; will send to %s.\n", origin, submitto)
+            else:
+                ewrite("Unknown origin %s; will send to %s.\n", origin, bts)
+        elif reportinfo:
+            rtype, submitto = reportinfo
+            ewrite("Will use %s protocol talking to %s.\n", rtype, submitto)
+            dontquery = True
+        else:
+            lsbr = commands.getoutput('lsb_release -si 2>/dev/null')
+            if lsbr:
+                distro = lsbr.strip().lower()
+                if distro in debianbts.SYSTEMS:
+                    bts = distro
+                    ewrite("Will send report to %s (per lsb_release).\n",
+                           debianbts.SYSTEMS[bts].get('name', bts))
+
+        if rtype == 'mailto':
+            rtype = 'debbugs'
+            dontquery = True
+
+        special = False
+        if not body and not subject and not notatty:
+            res = special_prompts(package, bts, ui, fromaddr)
+            if res:
+                (subject, severity, h, ph, body, query) = res
+                headers += h
+                pseudos += ph
+                if not query:
+                    dontquery = True
+                special = True
+
+        exinfo = None
+        if not (dontquery or notatty or self.options.kudos):
+            pkg, src = package, issource
+            if self.options.query_src:
+                src = True
+                if src_name:
+                    pkg = src_name
+            try:
+                exinfo = ui.handle_bts_query(pkg, bts, self.options.mirrors,
+                                             self.options.http_proxy,
+                                             source=src,
+                                             queryonly=self.options.queryonly,
+                                             version=pkgversion)
+            except UINotImplemented:
+                exinfo = None
+            except NoNetwork:
+                sys.exit(1)
+            except NoPackage:
+                if not self.options.queryonly and maintainer and ui.yes_no(
+                    'There is no record of this package in the bug tracking '
+                    'system.\nSend report directly to maintainer',
+                    'Send the report to the maintainer (%s).' % maintainer,
+                    'Send the report to the BTS anyway.'):
+                    rtype = 'debbugs'
+                    sendto = maintainer
+            except NoBugs:
+                ewrite('No bug reports found.\n')
+            except NoReport:
+                if self.options.queryonly:
+                    ewrite('Exiting at user request.\n')
+                else:
+                    ewrite('Nothing new to report; exiting.\n')
+                return
+
+            if self.options.queryonly and not exinfo:
+                return
+
+        ccaddr = os.environ.get('MAILCC')
+        if self.options.nocc:
+            bccaddr = os.environ.get('MAILBCC')
+        else:
+            bccaddr = os.environ.get('MAILBCC', fromaddr)
+
+        if maintainer:
+            mstr = u"Maintainer for %s is '%s'.\n" % (package, maintainer)
+            ewrite(mstr.encode(charset, 'replace'))
+            if 'qa.debian.org' in maintainer:
+                ui.long_message('''\
+This package is currently "orphaned"; if you are a current or prospective
+Debian developer, you might consider adopting it.  Please be aware that your
+report may not be resolved for a while, and that packages that have been
+orphaned for a long period of time are often removed from the archive.\n''')
+                ui.ewrite('\nFor more details, please see: http://www.debian.org/devel/wnpp/\n')
+
+        if self.options.kudos:
+            sendto = '%s at packages.debian.org' % package
+
+        depinfo = ""
+        # Grab dependency list, removing version conditions.
+        if (depends or recommends or suggests) and not self.options.kudos:
+            ewrite("Looking up dependencies of %s...\n", package)
+            depinfo = (reportbug.get_dependency_info(package, depends) +
+                       reportbug.get_dependency_info(package, recommends, "recommends") +
+                       reportbug.get_dependency_info(package, suggests, "suggests"))
+
+        if reportwith and not self.options.kudos:
+            for extrapackage in reportwith:
+                ewrite("Getting status for related package %s...\n", extrapackage)
+                extrastatus = reportbug.get_package_status(extrapackage)
+                if extrastatus[2]:
+                    extradepends = [x for x in extrastatus[2] if package not in x]
+                    ewrite("Looking up dependencies of related package %s...\n", extrapackage)
+                    depinfo += reportbug.get_dependency_info(extrapackage, extradepends)
+
+        if supplemental and not self.options.kudos:
+            ewrite("Looking up status of additional packages...\n")
+            depinfo += reportbug.get_dependency_info(
+                package, [[x] for x in supplemental], rel='is related to')
+
+        confinfo = []
+        if conffiles and not self.options.kudos:
+            ewrite("Getting changed configuration files...\n")
+            confinfo, changed = reportbug.get_changed_config_files(
+                conffiles, nocompress)
+
+            if self.options.noconf and changed:
+                for f in changed:
+                    confinfo[f] = 'changed [not included]'
+            elif changed and not notatty:
+                while 1:
+                    x = ui.select_self.options(
+                        "*** WARNING: The following configuration files have been "
+                        "modified:\n"+ "\n".join(changed)+
+                        "\nSend modified configuration files", 'Ynd',
+                        {'y':'Send your modified configuration files.',
+                         'n':"Don't send modified configuration files.",
+                         'd':'Display modified configuration files.'})
+                    if x == 'n':
+                        for f in changed:
+                            confinfo[f] = 'changed [not included]'
+                        break
+                    elif x == 'd':
+                        PAGER = os.environ.get('PAGER', '/usr/bin/sensible-pager')
+                        system(PAGER+' '+' '.join(changed))
+                    else:
+                        break
+
+        conftext = u''
+        if confinfo:
+            conftext = u'\n-- Configuration Files:\n'
+            files = confinfo.keys()
+            files.sort()
+            for f in files:
+                conftext = conftext + u'%s %s\n' % (f, confinfo[f])
+
+        if (self.options.debconf and os.path.exists('/usr/bin/debconf-show') and
+            not self.options.kudos and installed):
+            showpkgs = package
+            if reportwith:
+                showpkgs += ' ' + ' '.join(reportwith)
+            (status, output) = commands.getstatusoutput(
+                'DEBCONF_SYSTEMRC=1 DEBCONF_NOWARNINGS=yes '
+                '/usr/bin/debconf-show %s' % showpkgs )
+            if status:
+                conftext += '\n-- debconf-show failed\n'
+            elif output:
+                output = output.decode('utf-8', 'replace')
+                outstr = output.encode(charset, 'replace')
+                if (notatty or ui.yes_no(
+                    "*** The following debconf settings were detected:\n"
+                    +outstr+"\nInclude these settings in your report",
+                    'Send your debconf settings.',
+                    "Don't send your debconf settings.", nowrap=True)):
+                    conftext += u'\n-- debconf information:\n%s\n' % output
+                else:
+                    conftext += u'\n-- debconf information excluded\n'
+            else:
+                conftext += u'\n-- no debconf information\n'
+
+        ewrite('\n')
+        prompted = False
+        if interactive and not (self.options.kudos or exinfo) and presubj:
+            ui.display_report(file(presubj).read()+'\n')
+
+        if self.options.kudos:
+            subject = subject or ('Thanks for packaging %s!' % package)
+        elif exinfo:
+            if special:
+                body = ''
+            prompted = True
+            subject = ui.get_string(
+                'Please provide a subject for your response; no subject will '
+                'stop reportbug.', force_prompt=True)
+            # Check to make sure the bug still exists to avoid auto-reopens
+            if subject and pkgversion:
+                if not ui.yes_no('Does this bug still exist in version %s '
+                                 'of this package?' % pkgversion,
+                                 'Yes, it does.',
+                                 'No, it doesn\'t (or I don\'t know).',
+                                 default=False):
+                    pkgversion = None
+        elif not subject and not notatty:
+            prompted = True
+            subject = ui.get_string(
+                'Please briefly describe your problem (you can elaborate in '
+                'a moment; an empty response will stop reportbug).  This will '
+		'be the bug email subject, so write a concise summary of what '
+		'is wrong with the package, for example, "fails to send email" '
+		'or "does not start with -q option specified."', force_prompt=True)
+
+        if not subject:
+            efail("No subject specified; stopping.\n")
+
+        if len(subject) > 100 and prompted and mode < MODE_EXPERT:
+            subject = ui.get_string(
+                'Your description is a bit long; please enter a shorter subject. '
+                '(An empty response will retain the existing subject.)',
+                force_prompt=True) or subject
+        if package != 'wnpp' and prompted and mode < MODE_EXPERT:
+            if foundfile:
+                subject = foundfile + ": " + subject
+                ewrite("Rewriting subject to '%s'\n", subject)
+            elif (not re.match(r"\S+:\s", subject) and package not in subject):
+                subject = package + ": " + subject
+                ewrite("Rewriting subject to '%s'\n", subject)
+
+        listcc = self.options.listcc
+        if not listcc:
+            listcc = []
+
+        if not listcc and mode > MODE_STANDARD and rtype == 'debbugs' and not self.options.testmode and not self.options.template:
+            listcc += ui.get_multiline('Enter any additional addresses this report should be sent to; press ENTER after each address.')
+
+        if severity and rtype:
+            severity = debianbts.convert_severity(severity, rtype)
+
+        klass = self.options.klass
+        if not notatty and not (exinfo or self.options.kudos):
+            if not severity:
+                if rtype == 'gnats':
+                    severities = debianbts.SEVERITIES_gnats
+                    default = 'non-critical'
+                else:
+                    severities = debianbts.SEVERITIES
+                    default = 'normal'
+
+                severity = ui.menu("How would you rate the severity of this "
+                                   "problem or report?", severities,
+                                   'Please select a severity level: ',
+                                   default=default, order=debianbts.SEVLIST)
+
+            if rtype == 'gnats':
+                # Class of report
+                klass = ui.menu("What sort of problem are you reporting?",
+                                debianbts.CLASSES, 'Please select a class: ',
+                                default='sw-bug', order=debianbts.CLASSLIST)
+
+        severity = severity or 'normal'
+
+        justification = self.options.justification
+        if rtype == 'debbugs' and package != 'wnpp' and mode < MODE_EXPERT:
+            if severity in ('critical', 'grave'):
+                justification = ui.menu(
+                    'You are reporting a ' +severity+' bug; which of the '
+                    'following criteria does it meet?',
+                    debianbts.JUSTIFICATIONS[severity],
+                    'Please select the impact of the bug: ', default='unknown')
+            elif severity == 'serious':
+                justification = ui.get_string(
+                    'You are reporting a serious bug; which section of the '
+                    'Debian Policy Manual contains the "must" or "required" '
+                    'directive that it violates (E.g., "1.2.3")? '
+                    'Just type "unknown" if you are not sure (that would '
+                    'downgrade severity to normal).', force_prompt=True)
+                if re.match('[0-9]+\.[0-9.]+', justification):
+                    justification = 'Policy ' + justification
+                elif not justification:
+                    justification = 'unknown'
+
+            if justification == 'unknown':
+                justification = ''
+                severity = 'normal'
+                ewrite('Severity downgraded to "normal".\n')
+
+        if severity == 'does-not-build':
+            if pkgversion and not src_name:
+                src_name = package
+            if src_name and check_available and not notatty:
+                ewrite('Checking buildd.debian.org for past builds of %s...\n',
+                       src_name)
+                built = checkbuildd.check_built(src_name,
+                                                http_proxy=self.options.http_proxy)
+
+                if built:
+                    ewrite('Successful past builds... treating as serious.\n')
+                    severity = 'serious'
+                    justification = 'no longer builds from source'
+                else:
+                    ewrite('No successful builds... treating as important.\n')
+                    severity = 'important'
+                    justification = 'fails to build from source'
+            else:
+                if notatty:
+                    severity = 'important'
+                    justification = 'fails to build from source'
+                else:
+                    if ui.yes_no(
+                        'Has this package successfully been built for this '
+                        'architecture in the past (you can look this up at '
+                        'buildd.debian.org)',
+                        'Yes, this is a recently-introduced problem.',
+                        'No, it has always been this way.'):
+                        severity = 'serious'
+                        justification = 'no longer builds from source'
+                    else:
+                        severity = 'important'
+                        justification = 'fails to build from source'
+
+        HOMEDIR = os.environ.get('HOME', '/')
+
+        if (rtype == 'debbugs' and not self.options.tags and
+            not (notatty or self.options.kudos or exinfo) and package not in ('wnpp','ftp.debian.org') and
+            mode > MODE_NOVICE):
+            # Multiple-choice checkbox
+            if severity in ('grave', 'critical', 'serious'):
+                tags = debianbts.TAGS.copy()
+                tags.update(debianbts.CRITICAL_TAGS)
+                tagorder = debianbts.TAGLIST + debianbts.CRITICAL_TAGLIST
+            else:
+                tags = debianbts.TAGS
+                tagorder = debianbts.TAGLIST
+
+            taglist = ui.select_multiple(
+                'Do any of the following apply to this report?', tags,
+                'Please select tags: ', order=tagorder,
+                extras=debianbts.EXTRA_TAGS)
+
+        patch = ('patch' in taglist)
+
+        if justification and 'security' not in taglist and 'security' in \
+               justification:
+            ewrite('Adding security tag to this report.\n')
+            taglist += ['security']
+
+        if taglist:
+            tags = ' '.join(taglist)
+        else:
+            tags = ''
+
+        # Execute bug script
+        if (interactive or self.options.template) and bugexec and not self.options.kudos:
+            if os.path.exists('handle_bugscript'):
+                handler = './handle_bugscript'
+            else:
+                handler = '/usr/share/reportbug/handle_bugscript'
+
+            fh, filename = TempFile(prefix=tfprefix)
+            fh.close()
+            system('%s %s %s' % (handler, commands.mkarg(bugexec),
+                                 commands.mkarg(filename)))
+
+            addinfo = None
+            if not self.options.noconf:
+                fp = open(filename)
+                addinfo = u"\n-- Package-specific info:\n"+fp.read().decode('utf-8', 'replace')
+                fp.close()
+
+            cleanup_temp_file(filename)
+            if addinfo and incfiles:
+                incfiles = addinfo + u"\n" + incfiles
+            elif addinfo:
+                incfiles = addinfo
+
+        if bts == 'debian' and 'security' in taglist:
+            ewrite('Will send a CC of this report to the Debian Security and Testing Security Team.\n')
+            listcc += ['Debian Security Team <team at security.debian.org>']
+            listcc += ['Debian Testing Security Team <secure-testing-team at lists.alioth.debian.org>']
+
+        if listcc:
+            headers.append('X-Debbugs-CC: '+', '.join(listcc))
+
+        # Prepare bug report
+        if self.options.kudos:
+            message = u'\n\n'
+            if not mua:
+                SIGFILE = os.path.join(HOMEDIR, '.signature')
+                try:
+                    message = u"\n\n-- \n"+file(SIGFILE).read().decode('utf-8', 'replace')
+                except IOError:
+                    pass
+        else:
+            message = reportbug.generate_blank_report(
+                submitas or package, pkgversion, severity, justification,
+                depinfo, conftext, foundfile, incfiles, bts, exinfo, rtype,
+                klass, subject, tags, body, mode, pseudos)
+
+        # Substitute server email address
+        if submitto and '@' not in sendto:
+            if '@' in submitto:
+                sendto = submitto
+            else:
+                if exinfo:
+                    if sendto != 'submit':
+                        sendto = '%d-%s' % (exinfo, sendto)
+                    else:
+                        sendto = str(exinfo)
+
+                sendto = sendto+'@'+submitto
+        elif '@' not in sendto:
+            if exinfo:
+                if sendto != 'submit':
+                    sendto = '%d-%s' % (exinfo, sendto)
+                else:
+                    sendto = str(exinfo)
+
+            try:
+                sendto = sysinfo['email'] % sendto
+            except TypeError:
+                sendto = sysinfo['email']
+
+            sendto = rfc822.dump_address_pair((sysinfo['name']+
+                                               ' Bug Tracking System', sendto))
+
+        mailing = not (mua or self.options.printonly or self.options.template)
+        message = u"Subject: %s\n%s" % (subject, message)
+
+        if mailing:
+            fh, filename = TempFile(prefix=tfprefix)
+            fh.write(message.encode(charset, 'replace'))
+            fh.close()
+            oldmua = mua or self.options.mua
+            if not self.options.body and not self.options.bodyfile:
+                message = handle_editing(filename, message, self.options,
+                                         sendto, attachments, package,
+                                         charset=charset)
+            if not oldmua and self.options.mua:
+                mua = self.options.mua
+            if mua:
+                mailing = False
+            elif not sendto:
+                print message,
+                cleanup_temp_file(filename)
+                return
+
+            cleanup_temp_file(filename)
+
+            if not mua and patch and not attachments and not notatty:
+                while True:
+                    patchfile = ui.get_filename(
+                        'What is the filename of the patch (if none, or you have '
+                        'already included it, just press ENTER)?',
+                        force_prompt=True)
+                    if patchfile:
+                        attachfile = os.path.expanduser(patchfile)
+                        if os.path.exists(attachfile):
+                            attachments.append(attachfile)
+                            break
+                        else:
+                            ewrite('%s not found!', attachfile)
+                    else:
+                        break
+
+        body, headers, pseudoheaders = reportbug.cleanup_msg(message,headers,rtype)
+
+        if sign:
+            ewrite('Passing message to %s for signature...\n', sign)
+            oldbody = body
+            body = reportbug_submit.sign_message(body, fromaddr, package, pgp_addr,
+                                                 sign)
+            if not body:
+                ewrite('Signature failed; sending message unsigned.\n')
+                body = oldbody
+
+        if pseudoheaders:
+            body = '\n'.join(pseudoheaders)+'\n\n'+body
+
+        # Strip the body of useless whitespace at the end, then put a final
+        # newline in the message.  See #234963.
+        body = body.rstrip('\n')+'\n'
+
+        reportbug_submit.send_report(
+            body, attachments, mua, fromaddr, sendto, ccaddr, bccaddr,
+            headers, package, charset, mailing, sysinfo, rtype, exinfo,
+            self.options.replyto, self.options.printonly, self.options.template,
+            self.options.outfile, self.options.mta, self.options.kudos, self.options.smtptls,
+            smtphost, self.options.smtpuser, self.options.smtppasswd, self.options.paranoid)
+
+        if self.options.exitprompt:
+            ui.get_string('Please press ENTER to exit reportbug: ')
+        return
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        ewrite("\nreportbug: exiting due to user interrupt.\n")
+    except debianbts.Error, x:
+        ewrite('error accessing BTS: %s\n' % x)


Property changes on: trunk/reportbug_4merge
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:mergeinfo
   + 




More information about the Reportbug-commits mailing list