[28898] in Source-Commits
python-discuss commit: Add local client mode
daemon@ATHENA.MIT.EDU (Alex Dehnert)
Fri Feb 21 23:13:49 2025
Date: Fri, 21 Feb 2025 23:13:32 -0500
From: "Alex Dehnert" <adehnert@mit.edu>
Message-Id: <202502220413.51M4DWSt027644@drugstore.mit.edu>
To: source-commits@mit.edu
MIME-Version: 1.0
Content-Type: text/plain
https://github.com/mit-athena/python-discuss/commit/b6191986ae08fb2553d1b76903a269cb22f63ae8
commit b6191986ae08fb2553d1b76903a269cb22f63ae8
Author: Alex Dehnert <adehnert@mit.edu>
Date: Sun Feb 23 21:17:24 2014 -0500
Add local client mode
The normal discuss clients will run disserve when connecting to a local discuss
server, which is potentially handy for utilities running on the discuss server
that don't have convenient access to a keytab. This adds support for that mode
of operation to pydiscuss as well.
discuss/client.py | 2 +-
discuss/rpc.py | 21 +++++++++++++++++++++
2 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/discuss/client.py b/discuss/client.py
index ed2077e..28aa87c 100644
--- a/discuss/client.py
+++ b/discuss/client.py
@@ -43,7 +43,7 @@ def autoreconnects(f):
class Client(object):
"""Discuss client."""
- def __init__(self, server, port = 2100, auth = True, timeout = None):
+ def __init__(self, server, port = 2100, auth = True, timeout = None, RPCClient=RPCClient):
self.rpc = RPCClient(server, port, auth, timeout)
if auth and self.who_am_i().startswith("???@"):
raise ProtocolError("Authentication to server failed")
diff --git a/discuss/rpc.py b/discuss/rpc.py
index 7c1532f..49dda7d 100644
--- a/discuss/rpc.py
+++ b/discuss/rpc.py
@@ -42,8 +42,10 @@
#
import errno
+import fcntl
import socket
from struct import pack, unpack, calcsize
+import subprocess
from functools import partial
from . import constants
@@ -314,3 +316,22 @@ class RPCClient(object):
raise ProtocolError("Transport-level error")
return reply
+class RPCLocalClient(RPCClient):
+ # Args are for compatibility with the remote RPC; most aren't used
+ def __init__(self, server, port, auth, timeout):
+ # Used as the id field on meeting objects, so copy it in
+ self.server = server
+ # port 2100 is the default port -> use the binary
+ if port == 2100:
+ port = '/usr/sbin/disserve'
+ self.cmd = port
+
+ self.connect()
+ self.make_wrapper()
+
+ def connect(self):
+ pair = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
+ subprocess.Popen([self.cmd], stdin=pair[1], close_fds=True)
+ pair[1].close()
+ fcntl.fcntl(pair[0].fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
+ self.socket = pair[0]