1 """RPC Client module."""
10 # Default verbosity (0 = silent, 1 = print connections, 2 = print requests too)
16 """RPC Client class. No need to derive a class -- it's fully generic."""
18 def __init__(self
, address
, verbose
= VERBOSE
):
19 self
._pre
_init
(address
, verbose
)
22 def _pre_init(self
, address
, verbose
= VERBOSE
):
23 if type(address
) == type(0):
24 address
= ('', address
)
25 self
._address
= address
26 self
._verbose
= verbose
27 if self
._verbose
: print "Connecting to %s ..." % repr(address
)
28 self
._socket
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
29 self
._socket
.connect(address
)
30 if self
._verbose
: print "Connected."
31 self
._lastid
= 0 # Last id for which a reply has been received
32 self
._nextid
= 1 # Id of next request
33 self
._replies
= {} # Unprocessed replies
34 self
._rf
= self
._socket
.makefile('r')
35 self
._wf
= self
._socket
.makefile('w')
38 self
._methods
= self
._call
('.methods')
44 if self
._rf
: self
._rf
.close()
46 if self
._wf
: self
._wf
.close()
48 if self
._socket
: self
._socket
.close()
51 def __getattr__(self
, name
):
52 if name
in self
._methods
:
53 method
= _stub(self
, name
)
54 setattr(self
, name
, method
) # XXX circular reference
56 raise AttributeError, name
58 def _setverbose(self
, verbose
):
59 self
._verbose
= verbose
61 def _call(self
, name
, *args
):
62 return self
._vcall
(name
, args
)
64 def _vcall(self
, name
, args
):
65 return self
._recv
(self
._vsend
(name
, args
))
67 def _send(self
, name
, *args
):
68 return self
._vsend
(name
, args
)
70 def _send_noreply(self
, name
, *args
):
71 return self
._vsend
(name
, args
, 0)
73 def _vsend_noreply(self
, name
, args
):
74 return self
._vsend
(name
, args
, 0)
76 def _vsend(self
, name
, args
, wantreply
= 1):
79 if not wantreply
: id = -id
80 request
= (name
, args
, id)
81 if self
._verbose
> 1: print "sending request: %s" % repr(request
)
82 wp
= pickle
.Pickler(self
._wf
)
87 exception
, value
, rid
= self
._vrecv
(id)
89 raise RuntimeError, "request/reply id mismatch: %d/%d" % (id, rid
)
93 if hasattr(__builtin__
, exception
):
94 x
= getattr(__builtin__
, exception
)
95 elif exception
in ('posix.error', 'mac.error'):
99 raise exception
, value
101 def _vrecv(self
, id):
103 if self
._replies
.has_key(id):
104 if self
._verbose
> 1: print "retrieving previous reply, id = %d" % id
105 reply
= self
._replies
[id]
106 del self
._replies
[id]
110 if self
._verbose
> 1: print "waiting for reply, id = %d" % id
111 rp
= pickle
.Unpickler(self
._rf
)
114 if self
._verbose
> 1: print "got reply: %s" % repr(reply
)
118 if self
._verbose
> 1: print "got it"
120 self
._replies
[rid
] = reply
122 if self
._verbose
> 1: print "got higher id, assume all ok"
123 return (None, None, id)
129 from security
import Security
132 class SecureClient(Client
, Security
):
134 def __init__(self
, *args
):
136 apply(self
._pre
_init
, args
)
137 Security
.__init
__(self
)
139 line
= self
._rf
.readline()
140 challenge
= string
.atoi(string
.strip(line
))
141 response
= self
._encode
_challenge
(challenge
)
142 line
= `
long(response
)`
143 if line
[-1] in 'Ll': line
= line
[:-1]
144 self
._wf
.write(line
+ '\n')
150 """Helper class for Client -- each instance serves as a method of the client."""
152 def __init__(self
, client
, name
):
153 self
._client
= client
156 def __call__(self
, *args
):
157 return self
._client
._vcall
(self
._name
, args
)