op_members = [config.NICK]
aliases = {}
+class Who(object):
+ def __init__(self, mask, is_identified=False):
+ self.mask = mask
+ self.nick = mask.split('!', 1)[0]
+ self.is_identified = is_identified
+
+ def is_op(self):
+ return self.is_identified and self.nick in op_members
+
def readrc_command(who=None, target=None, replyto=None, words=None):
'''Source bot command file (readrc)'''
try:
- f = open(config.RCFILE).readlines()
+ cmd = []
+ for line in open(config.RCFILE):
+ response = do_command(Who(config.NICK, True), config.NICK, config.NICK, line.split())
+ if isinstance(response, list):
+ cmd += response
+ elif response:
+ cmd.append(response)
+ return cmd
except IOError:
return 'PRIVMSG', (replyto, 'unable to open file')
- cmd = []
- for line in f:
- response = do_command(config.NICK, config.NICK, config.NICK, line.split())
- if isinstance(response, list):
- cmd += response
- elif response:
- cmd.append(response)
- return cmd
op_commands['readrc'] = readrc_command
def alias_command(who, _, replyto, words):
def errcode_command(who, _, replyto, words):
'''Look up gPXE error code (errcode 0x12345678)'''
- # errcode 0x12345678
msg = ' '.join(words)
m = ERRCODE_RE.search(msg)
if m:
commands['errcode'] = errcode_command
commands['error'] = errcode_command
+def lspci_command(who, _, replyto, words):
+ '''Look up driver for PCI ID (lspci 10ec:8139)'''
+ ids = []
+ if len(words) == 2:
+ ids = words[1].split(':')
+ elif len(words) == 3:
+ ids = words[1:3]
+ if len(ids) != 2:
+ return 'PRIVMSG', (replyto, 'Invalid arguments')
+
+ try:
+ vendor_id, device_id = [int(s, 16) for s in ids]
+ except ValueError:
+ return 'PRIVMSG', (replyto, 'Invalid arguments')
+ pci_id = '%04x,%04x' % (vendor_id, device_id)
+
+ try:
+ for line in open(config.NICFILE):
+ line = line.rstrip('\r\n')
+ if not line or line.startswith('#'):
+ continue
+ fields = line.split('\t')
+
+ if fields[0] == 'family':
+ driver = fields[1].split('/')[-1]
+ continue
+
+ if fields[1] == pci_id:
+ return 'PRIVMSG', (replyto, driver)
+ except IndexError, e:
+ utils.dbg(str(e))
+ except IOError, e:
+ utils.dbg(str(e))
+ return 'PRIVMSG', (replyto, 'No driver found')
+if config.NICFILE:
+ commands['lspci'] = lspci_command
+else:
+ sys.stderr.write('running without lspci support (NICFILE not given)\n')
+
def help_command(who, _, replyto, msg):
'''List commands (help)'''
def do_help(vocabulary):
output.append(('PRIVMSG', (replyto, '%s %s' % (name.ljust(max_width), cmd.__doc__))))
return output
output = do_help(commands)
- if utils.nick_from_mask(who) in op_members:
+ if who.is_op():
output.extend(do_help(op_commands))
return output
commands['help'] = help_command
'''Control channel logging (log start, log stop, log list)'''
if len(words) < 2:
return
- channel = target
- if len(words) >= 3:
- channel = words[2].startswith('#') and words[2] or target
- if words[1] == 'start':
+
+ # Parse arguments
+ words.pop(0)
+ cmd = words.pop(0)
+ channel = words and words[0].startswith('#') and words.pop(0) or target
+ emails = words and words.pop(0) or ''
+ subject = ' '.join(words)
+
+ if cmd == 'start':
if channel in logs:
return 'PRIVMSG', (replyto, 'Logging %s already started' % channel)
- cmd = []
+ output = []
if channel.startswith('#') and channel != target:
- cmd.append(('CMD', ('JOIN %s' % channel,)))
- name = utils.make_log(channel)
- f = open(name, 'w')
- logs[channel] = (name, f)
- cmd.append(('PRIVMSG', (replyto, 'Start logging %s...' % channel)))
- return cmd
+ output.append(('CMD', ('JOIN %s' % channel,)))
+ filename = utils.make_log(channel)
+ logs[channel] = {
+ 'filename': filename,
+ 'fileobj': open(filename, 'w'),
+ 'emails': emails,
+ 'subject': subject,
+ }
+ output.append(('PRIVMSG', (replyto, 'Start logging %s...' % channel)))
+ return output
- elif words[1] == 'stop':
+ elif cmd == 'stop':
if not channel in logs:
return 'PRIVMSG', (replyto, 'Logging %s not started yet' % channel)
- (name, f) = logs.pop(channel)
- f.close()
-
- to_address = None
- if len(words) >= 3 and words[-1] != channel:
- to_address = words[-1]
- if to_address:
- unrecognized = utils.email_log(to_address, channel, name, aliases)
- cmd = [('PRIVMSG', (replyto, 'Unrecognized user %s' % user)) for user in unrecognized]
- return [('PRIVMSG', (replyto, 'Stop logging %s. Saved log file (%s)' % (channel, name)))] + cmd
-
- elif words[1] == 'list':
- return 'PRIVMSG', (replyto, 'Logging: %s' % ','.join(logs.keys()))
+ log = logs.pop(channel)
+ log['fileobj'].close()
+
+ if not emails:
+ emails = log['emails']
+ if not subject:
+ subject = log['subject']
+ if not subject:
+ subject = 'IRC logs for ' + channel
+
+ unrecognized = utils.email_log(emails, subject, log['filename'], aliases)
+ output = [('PRIVMSG', (replyto, 'Unrecognized alias %s' % user)) for user in unrecognized]
+ output.append(('PRIVMSG', (replyto, 'Stop logging %s. Saved log file (%s)' % (channel, log['filename']))))
+ return output
+
+ elif cmd == 'list':
+ return [('PRIVMSG', (replyto, channel)) for channel in logs.keys()]
op_commands['log'] = log_command
def join_command(who, target, replyto, words):
'''Join a channel (join #etherboot)'''
- index = words.index('join') + 1
- if index < len(words):
- channel = words[index]
- return 'CMD', ('JOIN %s' % (channel.startswith('#') and channel or '#' + channel),)
+ if len(words) != 2:
+ return
+ channel = words[1]
+ return 'CMD', ('JOIN %s' % (channel.startswith('#') and channel or '#' + channel),)
op_commands['join'] = join_command
def part_command(who, target, replyto, words):
'''Leave a channel (part #etherboot)'''
- index = words.index('part') + 1
- if index < len(words):
- channel = words[index]
- return 'CMD', ('PART %s' % (channel.startswith('#') and channel or '#' + channel),)
+ if len(words) != 2:
+ return
+ channel = words[1]
+ return 'CMD', ('PART %s' % (channel.startswith('#') and channel or '#' + channel),)
op_commands['part'] = part_command
def privmsg_command(who, target, replyto, words):
'''Send a chat message (privmsg #etherboot Hello all!)'''
if len(words) < 3:
return
- return ('PRIVMSG', (words[1], ' '.join(words[2:])))
+ return 'PRIVMSG', (words[1], ' '.join(words[2:]))
op_commands['privmsg'] = privmsg_command
def restart_command(who, target, replyto, words):
return
command = words[0].lower()
- if utils.nick_from_mask(who) in op_members and command in op_commands:
+ if who.is_op() and command in op_commands:
return op_commands[command](who, target, replyto, words)
if command in commands:
return commands[command](who, target, replyto, words)