#! /usr/bin/env python import os import re import select import socket import string import sys import tempfile import time import logging from lib.server import VERSION from lib.server import Server from lib.peer import Peer from datetime import datetime from optparse import OptionParser def main(argv): op = OptionParser( version=VERSION, description="Blatta is an implementation of a Pest network station.") op.add_option( "-a", "--address-table-path", help="Import address table from specified file") op.add_option( "-b", "--db-path", help="Specify path to settings database file") op.add_option( "-c", "--config-file-path", metavar="X", help="load the configfile from X") op.add_option( "-n", "--channel-name", metavar="X", help="specify the channel name for this Pest network") op.add_option( "-d", "--daemon", action="store_true", help="fork and become a daemon") op.add_option( "--log-level", help="specify priority level for logging: info or debug") op.add_option( "--listen", metavar="X", help="listen on specific IP address X") op.add_option( "--logdir", metavar="X", help="store channel log in directory X") op.add_option( "--motd", metavar="X", help="display file X as message of the day") op.add_option( "-p", "--password", metavar="X", help="require connection password X; default: no password") op.add_option( "--irc-ports", metavar="X", help="listen on ports X for irc client connections (a list separated by comma or whitespace);" " default: 6667") op.add_option( "--udp-port", metavar="X", help="listen for UDP packets on X;" " default: 7778") op.add_option( "--statedir", metavar="X", help="save persistent channel state (topic) in directory X") if os.name == "posix": op.add_option( "--chroot", metavar="X", help="change filesystem root to directory X after startup" " (requires root)") op.add_option( "--setuid", metavar="U[:G]", help="change process user (and optionally group) after startup" " (requires root)") (options, args) = op.parse_args(argv[1:]) if options.channel_name is None: options.channel_name = "#pest" log_format = "%(levelname)s %(asctime)s: %(message)s" if options.log_level == 'debug': logging.basicConfig(level=logging.DEBUG, format=log_format, stream=sys.stdout) else: logging.basicConfig(level=logging.INFO, format=log_format, stream=sys.stdout) if options.irc_ports is None: options.irc_ports = "6697" if options.udp_port is None: options.udp_port = 7778 else: options.udp_port = int(options.udp_port) if options.db_path is None: options.db_path = "blatta.db" if options.config_file_path is None: options.config_file_path = "config.py" if options.chroot: if os.getuid() != 0: op.error("Must be root to use --chroot") if options.setuid: from pwd import getpwnam from grp import getgrnam if os.getuid() != 0: op.error("Must be root to use --setuid") matches = options.setuid.split(":") if len(matches) == 2: options.setuid = (getpwnam(matches[0]).pw_uid, getgrnam(matches[1]).gr_gid) elif len(matches) == 1: options.setuid = (getpwnam(matches[0]).pw_uid, getpwnam(matches[0]).pw_gid) else: op.error("Specify a user, or user and group separated by a colon," " e.g. --setuid daemon, --setuid nobody:nobody") if (os.getuid() == 0 or os.getgid() == 0) and not options.setuid: op.error("Running this service as root is not recommended. Use the" " --setuid option to switch to an unprivileged account after" " startup. If you really intend to run as root, use" " \"--setuid root\".") irc_ports = [] for port in re.split(r"[,\s]+", options.irc_ports): try: irc_ports.append(int(port)) except ValueError: op.error("bad port: %r" % port) options.irc_ports = irc_ports server = Server(options) if options.daemon: server.daemonize() try: server.start() except KeyboardInterrupt: logging.error("Interrupted.") main(sys.argv)