|
1 | 1 | # Implement (a subset of) Sun RPC, version 2 -- RFC1057. |
2 | 2 |
|
| 3 | +# XXX There should be separate exceptions for the various reasons why |
| 4 | +# XXX an RPC can fail, rather than using RuntimeError for everything |
| 5 | + |
| 6 | +# XXX The UDP version of the protocol resends requests when it does |
| 7 | +# XXX not receive a timely reply -- use only for idempotent calls! |
| 8 | + |
3 | 9 | import xdr |
4 | 10 | import socket |
5 | 11 | import os |
@@ -80,24 +86,32 @@ def unpack_replyheader(self): |
80 | 86 | xid = self.unpack_uint() |
81 | 87 | mtype = self.unpack_enum() |
82 | 88 | if mtype <> REPLY: |
83 | | - raise RuntimeError, 'no REPLY but ' + str(mtype) |
| 89 | + raise RuntimeError, 'no REPLY but ' + `mtype` |
84 | 90 | stat = self.unpack_enum() |
| 91 | + if stat == MSG_DENIED: |
| 92 | + stat = self.unpack_enum() |
| 93 | + if stat == RPC_MISMATCH: |
| 94 | + low = self.unpack_uint() |
| 95 | + high = self.unpack_uint() |
| 96 | + raise RuntimeError, \ |
| 97 | + 'MSG_DENIED: RPC_MISMATCH: ' + `low, high` |
| 98 | + if stat == AUTH_ERROR: |
| 99 | + stat = self.unpack_uint() |
| 100 | + raise RuntimeError, \ |
| 101 | + 'MSG_DENIED: AUTH_ERROR: ' + `stat` |
| 102 | + raise RuntimeError, 'MSG_DENIED: ' + `stat` |
85 | 103 | if stat <> MSG_ACCEPTED: |
86 | | - if stat == MSG_DENIED: |
87 | | - stat = self.unpack_enum() |
88 | | - if stat == RPC_MISMATCH: |
89 | | - low = self.unpack_uint() |
90 | | - high = self.unpack_uint() |
91 | | - raise 'RPC_MISMATCH', (low, high) |
92 | | - if stat == AUTH_ERROR: |
93 | | - stat = self.unpack_uint() |
94 | | - raise 'AUTH_ERROR', str(stat) |
95 | | - raise 'MSG_REJECTED', str(stat) |
96 | | - raise RuntimeError, 'no MSG_ACCEPTED but ' + str(stat) |
| 104 | + raise RuntimeError, \ |
| 105 | + 'Neither MSG_DENIED nor MSG_ACCEPTED: ' + `stat` |
97 | 106 | verf = self.unpack_auth() |
98 | 107 | stat = self.unpack_enum() |
| 108 | + if stat == PROG_MISMATCH: |
| 109 | + low = self.unpack_uint() |
| 110 | + high = self.unpack_uint() |
| 111 | + raise RuntimeError, \ |
| 112 | + 'call failed: PROG_MISMATCH: ' + `low, high` |
99 | 113 | if stat <> SUCCESS: |
100 | | - raise RuntimeError, 'no SUCCESS but ' + str(stat) |
| 114 | + raise RuntimeError, 'call failed: ' + `stat` |
101 | 115 | return xid, verf |
102 | 116 | # Caller must get procedure-specific part of reply |
103 | 117 |
|
@@ -229,7 +243,6 @@ def end_call(self): |
229 | 243 |
|
230 | 244 |
|
231 | 245 | # Raw UDP-based client |
232 | | -# XXX This class does not recover from missed/duplicated packets! |
233 | 246 |
|
234 | 247 | class RawUDPClient(Client): |
235 | 248 |
|
|
0 commit comments