This file is indexed.

/usr/bin/sb_bnserver is in spambayes 1.1b1-1.

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

The actual contents of the file can be viewed below.

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

# Another server version of hammie.py
# This is not intended to be run manually, it is the opportunistic
# daemon backend of sb_bnfilter.
#
# Author: Toby Dickenson
#

"""Usage: %(program)s [options] FILE

Where:
    -h
        show usage and exit
    -p FILE
        use pickle FILE as the persistent store.  loads data from this file
        if it exists, and saves data to this file at the end.
    -d FILE
        use DBM store FILE as the persistent store.
    -o section:option:value
        set [section, option] in the options database to value
    -a seconds
        timeout in seconds between requests before this server terminates
    -A number
        terminate this server after this many requests
    FILE
        unix domain socket used on which we listen    
"""

import os, getopt, sys, SocketServer, traceback, select, socket, errno

# See Options.py for explanations of these properties
program = sys.argv[0]
  

def usage(code, msg=''):
    """Print usage message and sys.exit(code)."""
    if msg:
        print >> sys.stderr, msg
        print >> sys.stderr
    print >> sys.stderr, __doc__
    sys.exit(code)


def main():
    """Main program; parse options and go."""
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'hd:p:o:a:A:')
    except getopt.error, msg:
        usage(2, msg)

    if len(args) != 1:
        usage(2, "socket not specified")

    # get the server up before initializing spambayes, so that
    # we haven't wasted time if we later find we can't start the server
    try:
        server = BNServer(args[0], BNRequest)
    except socket.error,e:
        if e[0] == errno.EADDRINUSE:
            pass   # in use, no need
        else:
            raise  # a real error
    else:
        try:
            from spambayes import Options, storage
            options = Options.options
        
            for opt, arg in opts:
                if opt == '-h':
                    usage(0)
                elif opt == '-o':
                    options.set_from_cmdline(arg, sys.stderr)
                elif opt == '-a':
                    server.timeout = float(arg)
                elif opt == '-A':
                    server.number = int(arg)
            h = make_HammieFilter()
            h.dbname, h.usedb = storage.database_type(opts)
            server.hammie = h
            server.serve_until_idle()
            h.close()
        finally:
            try:
                os.unlink(args[0])
            except EnvironmentError:
                pass

class NowIdle(Exception):
    pass
        
class BNServer(SocketServer.UnixStreamServer):
    allow_reuse_address = True
    timeout = 10.0
    number = 100

    def serve_until_idle(self):
        try:
            for i in range(self.number):
                self.handle_request()
        except NowIdle:
            pass
    
    def get_request(self):
        r, w, e = select.select([self.socket], [], [], self.timeout)
        if r:
            return self.socket.accept()
        else:
            raise NowIdle()
        
class BNRequest(SocketServer.StreamRequestHandler):
    def handle(self):
        switches = self.rfile.readline()
        body = self.rfile.read()
        try:
            response = self._calc_response(switches, body)
            self.wfile.write('0\n%d\n'%(len(response),))
            self.wfile.write(response)
        except:
            response = traceback.format_exception_only(sys.exc_info()[0],
                                                       sys.exc_info()[1])[0]
            self.wfile.write('1\n%d\n'%(len(response),))
            self.wfile.write(response)
       
    def _calc_response(self, switches, body):
        switches = switches.split()
        actions = []
        opts, args = getopt.getopt(switches, 'fgstGS')
        h = self.server.hammie
        for opt, arg in opts:
            if opt == '-f':
                actions.append(h.filter)
            elif opt == '-g':
                actions.append(h.train_ham)
            elif opt == '-s':
                actions.append(h.train_spam)
            elif opt == '-t':
                actions.append(h.filter_train)
            elif opt == '-G':
                actions.append(h.untrain_ham)
            elif opt == '-S':
                actions.append(h.untrain_spam)
        if actions == []:
            actions = [h.filter]
        from spambayes import mboxutils
        msg = mboxutils.get_message(body)
        for action in actions:
            action(msg)
        return mboxutils.as_string(msg, 1)


def make_HammieFilter():
    # The sb_hammie script has some logic in the HammieFiler class that we need here too.
    # Ideally that should be moved into the spambayes package, but for now lets just
    # abuse sys.path, make assumptions about the directory layout, and import it direct
    # from the sb_filter script.
    from spambayes import Options
    path = os.path.split(Options.__file__)[0]+'/../scripts'
    if path not in sys.path:
        sys.path.append(path)
    from sb_filter import HammieFilter
    return HammieFilter()
                
                
if __name__ == "__main__":
    main()