genesis 1 #! /usr/bin/env python
genesis 2
genesis 3 import os
genesis 4 import re
genesis 5 import select
genesis 6 import socket
genesis 7 import string
genesis 8 import sys
genesis 9 import tempfile
genesis 10 import time
9987-embargoing 11 import logging
genesis 12 from lib.server import VERSION
genesis 13 from lib.server import Server
genesis 14 from lib.peer import Peer
genesis 15 from datetime import datetime
genesis 16 from optparse import OptionParser
genesis 17
genesis 18
genesis 19 def main(argv):
genesis 20 op = OptionParser(
genesis 21 version=VERSION,
9991-improved-log... 22 description="Blatta is an implementation of a Pest network station.")
genesis 23 op.add_option(
genesis 24 "-a", "--address-table-path",
genesis 25 help="Import address table from specified file")
genesis 26 op.add_option(
genesis 27 "-b", "--db-path",
genesis 28 help="Specify path to settings database file")
genesis 29 op.add_option(
genesis 30 "-c", "--config-file-path",
genesis 31 metavar="X",
genesis 32 help="load the configfile from X")
genesis 33 op.add_option(
9989-show-wot-nicks 34 "-n", "--channel-name",
9989-show-wot-nicks 35 metavar="X",
9989-show-wot-nicks 36 help="specify the channel name for this Pest network")
9989-show-wot-nicks 37 op.add_option(
genesis 38 "-d", "--daemon",
genesis 39 action="store_true",
genesis 40 help="fork and become a daemon")
genesis 41 op.add_option(
9985-single-thread 42 "--log-level",
9985-single-thread 43 help="specify priority level for logging: info or debug")
genesis 44 op.add_option(
genesis 45 "--listen",
genesis 46 metavar="X",
genesis 47 help="listen on specific IP address X")
genesis 48 op.add_option(
genesis 49 "--logdir",
genesis 50 metavar="X",
genesis 51 help="store channel log in directory X")
genesis 52 op.add_option(
genesis 53 "--motd",
genesis 54 metavar="X",
genesis 55 help="display file X as message of the day")
genesis 56 op.add_option(
genesis 57 "-p", "--password",
genesis 58 metavar="X",
genesis 59 help="require connection password X; default: no password")
genesis 60 op.add_option(
9991-improved-log... 61 "--irc-ports",
genesis 62 metavar="X",
9991-improved-log... 63 help="listen on ports X for irc client connections (a list separated by comma or whitespace);"
9991-improved-log... 64 " default: 6667")
genesis 65 op.add_option(
genesis 66 "--udp-port",
genesis 67 metavar="X",
genesis 68 help="listen for UDP packets on X;"
genesis 69 " default: 7778")
genesis 70 op.add_option(
genesis 71 "--statedir",
genesis 72 metavar="X",
9985-single-thread 73 help="save persistent channel state (topic) in directory X")
genesis 74 if os.name == "posix":
genesis 75 op.add_option(
genesis 76 "--chroot",
genesis 77 metavar="X",
genesis 78 help="change filesystem root to directory X after startup"
genesis 79 " (requires root)")
genesis 80 op.add_option(
genesis 81 "--setuid",
genesis 82 metavar="U[:G]",
genesis 83 help="change process user (and optionally group) after startup"
genesis 84 " (requires root)")
genesis 85
genesis 86 (options, args) = op.parse_args(argv[1:])
9989-show-wot-nicks 87 if options.channel_name is None:
9989-show-wot-nicks 88 options.channel_name = "#pest"
9987-embargoing 89 log_format = "%(levelname)s %(asctime)s: %(message)s"
9985-single-thread 90 if options.log_level == 'debug':
9987-embargoing 91 logging.basicConfig(level=logging.DEBUG, format=log_format, stream=sys.stdout)
9987-embargoing 92 else:
9987-embargoing 93 logging.basicConfig(level=logging.INFO, format=log_format, stream=sys.stdout)
9991-improved-log... 94 if options.irc_ports is None:
9991-improved-log... 95 options.irc_ports = "6697"
genesis 96 if options.udp_port is None:
genesis 97 options.udp_port = 7778
genesis 98 else:
genesis 99 options.udp_port = int(options.udp_port)
genesis 100 if options.db_path is None:
9991-improved-log... 101 options.db_path = "blatta.db"
genesis 102 if options.config_file_path is None:
genesis 103 options.config_file_path = "config.py"
genesis 104 if options.chroot:
genesis 105 if os.getuid() != 0:
genesis 106 op.error("Must be root to use --chroot")
genesis 107 if options.setuid:
genesis 108 from pwd import getpwnam
genesis 109 from grp import getgrnam
genesis 110 if os.getuid() != 0:
genesis 111 op.error("Must be root to use --setuid")
genesis 112 matches = options.setuid.split(":")
genesis 113 if len(matches) == 2:
genesis 114 options.setuid = (getpwnam(matches[0]).pw_uid,
genesis 115 getgrnam(matches[1]).gr_gid)
genesis 116 elif len(matches) == 1:
genesis 117 options.setuid = (getpwnam(matches[0]).pw_uid,
genesis 118 getpwnam(matches[0]).pw_gid)
genesis 119 else:
genesis 120 op.error("Specify a user, or user and group separated by a colon,"
genesis 121 " e.g. --setuid daemon, --setuid nobody:nobody")
genesis 122 if (os.getuid() == 0 or os.getgid() == 0) and not options.setuid:
genesis 123 op.error("Running this service as root is not recommended. Use the"
genesis 124 " --setuid option to switch to an unprivileged account after"
genesis 125 " startup. If you really intend to run as root, use"
genesis 126 " \"--setuid root\".")
genesis 127
9991-improved-log... 128 irc_ports = []
9991-improved-log... 129 for port in re.split(r"[,\s]+", options.irc_ports):
genesis 130 try:
9991-improved-log... 131 irc_ports.append(int(port))
genesis 132 except ValueError:
genesis 133 op.error("bad port: %r" % port)
9991-improved-log... 134 options.irc_ports = irc_ports
genesis 135 server = Server(options)
genesis 136 if options.daemon:
genesis 137 server.daemonize()
genesis 138 try:
genesis 139 server.start()
genesis 140 except KeyboardInterrupt:
9987-embargoing 141 logging.error("Interrupted.")
genesis 142
genesis 143 main(sys.argv)