2
# tio.py - I/O functions
4
# Copyright (C) 2010, 2011 Arthur de Jong
6
# This library is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU Lesser General Public
8
# License as published by the Free Software Foundation; either
9
# version 2.1 of the License, or (at your option) any later version.
11
# This library is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
# Lesser General Public License for more details.
16
# You should have received a copy of the GNU Lesser General Public
17
# License along with this library; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26
# definition for reading and writing INT32 values
27
_int32 = struct.Struct('i')
29
# FIXME: use something from config.py to determine the correct size
30
_uid_t = struct.Struct('i')
32
# FIXME: use something from config.py to determine the correct size
33
_gid_t = struct.Struct('i')
35
# FIXME: use something from config.py to determine the correct size
36
_struct_timeval = struct.Struct('ll')
38
class TIOStreamError(Exception):
41
class TIOStream(object):
42
"""File-like object that allows reading and writing nslcd-protocol
45
def __init__(self, conn):
47
conn.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, _struct_timeval.pack(0, 500000))
48
conn.setsockopt(socket.SOL_SOCKET, socket.SO_SNDTIMEO, _struct_timeval.pack(60, 0))
49
self.fp = os.fdopen(conn.fileno(), 'w+b', 1024*1024)
52
return self.fp.read(size)
55
return _int32.unpack(self.read(_int32.size))[0]
58
return _uid_t.unpack(self.read(_uid_t.size))[0]
61
return _gid_t.unpack(self.read(_gid_t.size))[0]
63
def read_string(self, maxsize=None):
64
len = self.read_int32()
65
if maxsize and len >= maxsize:
66
raise TIOStreamError()
69
def read_address(self):
70
"""Read an address (usually IPv4 or IPv6) from the stream and return
71
the address as a string representation."""
72
af = self.read_int32()
73
return socket.inet_ntop(af, self.read_string(maxsize=64))
75
def write(self, value):
78
def write_int32(self, value):
79
self.write(_int32.pack(value))
81
def write_uid_t(self, value):
82
self.write(_uid_t.pack(value))
84
def write_gid_t(self, value):
85
self.write(_gid_t.pack(value))
87
def write_string(self, value):
88
self.write_int32(len(value))
91
def write_stringlist(self, value):
93
self.write_int32(len(lst))
95
self.write_string(string)
98
def _to_address(value):
101
return socket.AF_INET, socket.inet_pton(socket.AF_INET, value)
103
pass # try the next one
105
return socket.AF_INET6, socket.inet_pton(socket.AF_INET6, value)
107
def write_address(self, value):
108
"""Write an address (usually IPv4 or IPv6) in a string representation
110
# first try to make it into an IPv6 address
111
af, address = TIOStream._to_address(value)
113
self.write_string(address)