~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/runner/inetdtap.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-17 14:52:35 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20070117145235-btmig6qfmqfen0om
Tags: 2.5.0-0ubuntu1
New upstream version, compatible with python2.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
 
2
# See LICENSE for details.
 
3
 
 
4
 
5
 
 
6
"""Twisted inetd TAP support
 
7
 
 
8
Stability: semi-stable
 
9
 
 
10
Maintainer: U{Andrew Bennetts<mailto:spiv@twistedmatrix.com>}
 
11
 
 
12
Future Plans: more configurability.
 
13
"""
 
14
 
 
15
import os, pwd, grp, socket
 
16
 
 
17
from twisted.runner import inetd, inetdconf
 
18
from twisted.python import log, usage
 
19
from twisted.internet.protocol import ServerFactory
 
20
from twisted.application import internet, service as appservice
 
21
 
 
22
try:
 
23
    import portmap
 
24
    rpcOk = 1
 
25
except ImportError:
 
26
    rpcOk = 0
 
27
 
 
28
 
 
29
# Protocol map
 
30
protocolDict = {'tcp': socket.IPPROTO_TCP, 'udp': socket.IPPROTO_UDP}
 
31
 
 
32
 
 
33
class Options(usage.Options):
 
34
 
 
35
    optParameters = [
 
36
        ['rpc', 'r', '/etc/rpc', 'RPC procedure table file'],
 
37
        ['file', 'f', '/etc/inetd.conf', 'Service configuration file']
 
38
    ]
 
39
 
 
40
    optFlags = [['nointernal', 'i', "Don't run internal services"]]
 
41
    zsh_actions = {"file" : "_files -g '*.conf'"}
 
42
 
 
43
class RPCServer(internet.TCPServer):
 
44
 
 
45
    def __init__(self, rpcVersions, rpcConf, proto, service):
 
46
        internet.TCPServer.__init__(0, ServerFactory())
 
47
        self.rpcConf = rpcConf
 
48
        self.proto = proto
 
49
        self.service = service
 
50
 
 
51
    def startService(self):
 
52
        internet.TCPServer.startService(self)
 
53
        import portmap
 
54
        portNo = self._port.getHost()[2]
 
55
        service = self.service
 
56
        for version in rpcVersions:
 
57
            portmap.set(self.rpcConf.services[name], version, self.proto,
 
58
                        portNo)
 
59
            inetd.forkPassingFD(service.program, service.programArgs,
 
60
                                os.environ, service.user, service.group, p)
 
61
 
 
62
def makeService(config):
 
63
    s = appservice.MultiService()
 
64
    conf = inetdconf.InetdConf()
 
65
    conf.parseFile(open(config['file']))
 
66
 
 
67
    rpcConf = inetdconf.RPCServicesConf()
 
68
    try:
 
69
        rpcConf.parseFile(open(config['rpc']))
 
70
    except:
 
71
        # We'll survive even if we can't read /etc/rpc
 
72
        log.deferr()
 
73
    
 
74
    for service in conf.services:
 
75
        rpc = service.protocol.startswith('rpc/')
 
76
        protocol = service.protocol
 
77
 
 
78
        if rpc and not rpcOk:
 
79
            log.msg('Skipping rpc service due to lack of rpc support')
 
80
            continue
 
81
 
 
82
        if rpc:
 
83
            # RPC has extra options, so extract that
 
84
            protocol = protocol[4:]     # trim 'rpc/'
 
85
            if not protocolDict.has_key(protocol):
 
86
                log.msg('Bad protocol: ' + protocol)
 
87
                continue
 
88
            
 
89
            try:
 
90
                name, rpcVersions = service.name.split('/')
 
91
            except ValueError:
 
92
                log.msg('Bad RPC service/version: ' + service.name)
 
93
                continue
 
94
 
 
95
            if not rpcConf.services.has_key(name):
 
96
                log.msg('Unknown RPC service: ' + repr(service.name))
 
97
                continue
 
98
 
 
99
            try:
 
100
                if '-' in rpcVersions:
 
101
                    start, end = map(int, rpcVersions.split('-'))
 
102
                    rpcVersions = range(start, end+1)
 
103
                else:
 
104
                    rpcVersions = [int(rpcVersions)]
 
105
            except ValueError:
 
106
                log.msg('Bad RPC versions: ' + str(rpcVersions))
 
107
                continue
 
108
            
 
109
        if (protocol, service.socketType) not in [('tcp', 'stream'),
 
110
                                                  ('udp', 'dgram')]:
 
111
            log.msg('Skipping unsupported type/protocol: %s/%s'
 
112
                    % (service.socketType, service.protocol))
 
113
            continue
 
114
 
 
115
        # Convert the username into a uid (if necessary)
 
116
        try:
 
117
            service.user = int(service.user)
 
118
        except ValueError:
 
119
            try:
 
120
                service.user = pwd.getpwnam(service.user)[2]
 
121
            except KeyError:
 
122
                log.msg('Unknown user: ' + service.user)
 
123
                continue
 
124
 
 
125
        # Convert the group name into a gid (if necessary)
 
126
        if service.group is None:
 
127
            # If no group was specified, use the user's primary group
 
128
            service.group = pwd.getpwuid(service.user)[3]
 
129
        else:
 
130
            try:
 
131
                service.group = int(service.group)
 
132
            except ValueError:
 
133
                try:
 
134
                    service.group = grp.getgrnam(service.group)[2]
 
135
                except KeyError:
 
136
                    log.msg('Unknown group: ' + service.group)
 
137
                    continue
 
138
 
 
139
        if service.program == 'internal':
 
140
            if config['nointernal']:
 
141
                continue
 
142
 
 
143
            # Internal services can use a standard ServerFactory
 
144
            if not inetd.internalProtocols.has_key(service.name):
 
145
                log.msg('Unknown internal service: ' + service.name)
 
146
                continue
 
147
            factory = ServerFactory()
 
148
            factory.protocol = inetd.internalProtocols[service.name]
 
149
        elif rpc:
 
150
            i = RPCServer(rpcVersions, rpcConf, proto, service)
 
151
            i.setServiceParent(s)
 
152
            continue
 
153
        else:
 
154
            # Non-internal non-rpc services use InetdFactory
 
155
            factory = inetd.InetdFactory(service)
 
156
 
 
157
        if protocol == 'tcp':
 
158
            internet.TCPServer(service.port, factory).setServiceParent(s)
 
159
        elif protocol == 'udp':
 
160
            raise RuntimeError("not supporting UDP")
 
161
    return s