# No user-serviceable parts below this line
-version = "2.7"
+version = "2.9"
import argparse
import logging
+import logging.handlers
import json
+import os
try: # Python 3
import queue
except ImportError: # Python 2
# same problem - there is little point in reliable delivery to a relay
# that is down or unreliable.
#
-# This code uses only NICK, JOIN, PART, MODE, PRIVMSG, USER, and QUIT.
+# This code uses only NICK, JOIN, PART, MODE, PRIVMSG, USER, and QUIT.
# It is strictly compliant to RFC1459, except for the interpretation and
# use of the DEAF and CHANLIMIT and (obsolete) MAXCHANNELS features.
#
pass
-class InvalidRequest (ValueError):
+class InvalidRequest(ValueError):
"An invalid JSON request"
pass
self.master = master
self.socket = None
- def _wrap_socket(self, socket, target, cafile=None,
+ def _wrap_socket(self, socket, target, certfile=None, cafile=None,
protocol=ssl.PROTOCOL_TLSv1):
try: # Python 3.2 and greater
ssl_context = ssl.SSLContext(protocol)
except AttributeError: # Python < 3.2
self.socket = ssl.wrap_socket(
- socket, cert_reqs=ssl.CERT_REQUIRED,
+ socket, certfile=certfile, cert_reqs=ssl.CERT_REQUIRED,
ssl_version=protocol, ca_certs=cafile)
else:
ssl_context.verify_mode = ssl.CERT_REQUIRED
if n is None:
n = self.nick_trial
if self.nick_needs_number:
- return (self.nick_template % n)
+ return self.nick_template % n
else:
return self.nick_template
def handle_ping(self):
if age < time.time() - CHANNEL_TTL:
ancients.append((connection, chan, age))
if ancients:
- ancients.sort(key=lambda x: x[2])
+ ancients.sort(key=lambda x: x[2])
(found_connection, drop_channel, _drop_age) = ancients[0]
found_connection.part(drop_channel, "scavenged by irkerd")
del found_connection.channels_joined[drop_channel]
m = int(lump[12:])
for pref in "#&+":
cxt.channel_limits[pref] = m
- LOG.info("%s maxchannels is %d" % (connection.server, m))
+ LOG.info("%s maxchannels is %d" % (connection.target, m))
elif lump.startswith("CHANLIMIT=#:"):
limits = lump[10:].split(",")
try:
line = UNICODE_TYPE(line, 'utf-8')
irker.handle(line=line.strip())
+def in_background():
+ "Is this process running in background?"
+ try:
+ return os.getpgrp() != os.tcgetpgrp(1)
+ except OSError:
+ return True
if __name__ == '__main__':
parser = argparse.ArgumentParser(
parser.add_argument(
'-c', '--ca-file', metavar='PATH',
help='file of trusted certificates for SSL/TLS')
+ parser.add_argument(
+ '-e', '--cert-file', metavar='PATH',
+ help='pem file used to authenticate to the server')
parser.add_argument(
'-d', '--log-level', metavar='LEVEL', choices=LOG_LEVELS,
- help='file of trusted certificates for SSL/TLS')
+ help='how much to log to the log file (one of %(choices)s)')
+ parser.add_argument(
+ '-H', '--host', metavar='ADDRESS', default=HOST,
+ help='IP address to listen on')
parser.add_argument(
'-l', '--log-file', metavar='PATH',
help='file for saving captured message traffic')
help='message for --immediate mode')
args = parser.parse_args()
- handler = logging.StreamHandler()
+ if not args.log_file and in_background():
+ handler = logging.handlers.SysLogHandler(address='/dev/log',
+ facility='daemon')
+ else:
+ handler = logging.StreamHandler()
+
LOG.addHandler(handler)
if args.log_level:
log_level = getattr(logging, args.log_level.upper())
nick_needs_number=re.search('%.*d', args.nick),
password=args.password,
cafile=args.ca_file,
+ certfile=args.cert_file,
)
LOG.info("irkerd version %s" % version)
if args.immediate:
raise SystemExit(1)
irker.thread_launch()
try:
- tcpserver = socketserver.TCPServer((HOST, PORT), IrkerTCPHandler)
- udpserver = socketserver.UDPServer((HOST, PORT), IrkerUDPHandler)
+ tcpserver = socketserver.TCPServer((args.host, PORT), IrkerTCPHandler)
+ udpserver = socketserver.UDPServer((args.host, PORT), IrkerUDPHandler)
for server in [tcpserver, udpserver]:
server = threading.Thread(target=server.serve_forever)
server.setDaemon(True)