docs: prune history and orphans from party's comments

Rationale stays; what goes is narration of past revisions (git log
has it), a 'Library mode' section heading with no code under it, a
helper description left above cmd_role after the helper was folded in,
a claim that cmd_close trusts the roster's SOCKET (it never reads it),
and pointers to a README section that is named Security. The FS perms
platform list gains DragonFly.
This commit is contained in:
veg 2026-09-21 09:48:02 +00:00
parent 8661d2968e
commit 120fed8cb4

63
party
View file

@ -83,13 +83,6 @@ Info:
EOF EOF
} }
# Library mode
# ============
# Sourced from tests with __PARTY_LIB_ONLY=1 to expose helpers without
# triggering dispatch. The marker MUST be checked before the dispatch
# block at the bottom of the file.
# Helpers # Helpers
# ======= # =======
@ -104,9 +97,7 @@ EOF
validate_party_name() { validate_party_name() {
name="$1" name="$1"
# Length cap: 63 keeps the full socket path comfortably below the # Length cap: 63 keeps the full socket path comfortably below the
# 108-char sun_path limit for typical USERs. Runs before the empty/ # 108-char sun_path limit for typical USERs.
# shape checks below; an empty name has length 0, so it always
# passes this check and falls through to the '' case there.
if [ "${#name}" -gt 63 ]; then if [ "${#name}" -gt 63 ]; then
echo "party: name '$name' too long (max 63 chars)" >&2 echo "party: name '$name' too long (max 63 chars)" >&2
return 2 return 2
@ -287,9 +278,6 @@ roster_read() {
# validate_party_name rejects them (dots are banned: tmux rewrites # validate_party_name rejects them (dots are banned: tmux rewrites
# them in session names). Run the canonical validator so the # them in session names). Run the canonical validator so the
# invariant cmd_host enforces on write is also checked on read. # invariant cmd_host enforces on write is also checked on read.
# Side effect: pre-existing dotted-party dirs from older builds
# become undiscoverable, which is the pre-release migration policy
# (README §Status).
validate_party_name "$RR_PARTY_NAME" 2>/dev/null || return 1 validate_party_name "$RR_PARTY_NAME" 2>/dev/null || return 1
# Both the dir and its sock must be owned by the user named in the # Both the dir and its sock must be owned by the user named in the
@ -324,9 +312,8 @@ roster_read() {
'' | \#*) ;; '' | \#*) ;;
esac esac
done < "$rec" done < "$rec"
# A roster written before --group existed (or otherwise missing # No GROUP= in the record: assume the default, so callers can use
# GROUP=) gates on the default group; callers can rely on RR_GROUP # RR_GROUP unconditionally.
# always naming the party's actual perimeter.
[ -n "$RR_GROUP" ] || RR_GROUP=$TMUX_PARTY_GROUP [ -n "$RR_GROUP" ] || RR_GROUP=$TMUX_PARTY_GROUP
return 0 return 0
} }
@ -379,15 +366,11 @@ roster_list() {
# list-clients` exits 0 only against a real tmux server bound to that # list-clients` exits 0 only against a real tmux server bound to that
# exact socket path, which rules out stale roster pointers, AF_UNIX # exact socket path, which rules out stale roster pointers, AF_UNIX
# impostors (a same-group user planting a hand-rolled listener via # impostors (a same-group user planting a hand-rolled listener via
# `nc -lU`), and PID-reuse leftovers in one shot. Earlier revisions had # `nc -lU`), and PID-reuse leftovers in one shot. Do not add a
# a separate is_party_alive() that also format-checked the roster's # `kill -0 $SERVER_PID` pre-filter: per POSIX, kill(2) signal 0 may
# SERVER_PID, a vestige of a `kill -0` pre-filter that broke cross-user # return EPERM when the caller lacks send-permission, and illumos, the
# discovery on every non-Linux POSIX target: per POSIX, kill(2) signal # BSDs, and macOS honor that, which breaks cross-user discovery
# 0 may return EPERM when the caller lacks send-permission, and # everywhere but Linux (and LX zones). SERVER_PID is display-only.
# illumos, all the BSDs, and macOS honor that. Linux (and LX-branded
# zones) return 0 for "exists, even if not signalable", which is why
# the bug hid in the test matrix until a native illumos run surfaced
# it. SERVER_PID stays in the roster as display-only metadata.
party_conn_state() { party_conn_state() {
_cs_err=$("$PARTY_TMUX" -S "$1" list-clients 2>&1 >/dev/null) \ _cs_err=$("$PARTY_TMUX" -S "$1" list-clients 2>&1 >/dev/null) \
&& _cs_rc=0 || _cs_rc=$? && _cs_rc=0 || _cs_rc=$?
@ -403,9 +386,7 @@ party_conn_state() {
# Guest sessions # Guest sessions
# -------------- # --------------
# Print the caller's guest session name for a given user: the fixed # Print the guest session name of user $1.
# session __party_guest_<user> that join/leave/status/role/kick/detach
# all target.
guest_session_name() { guest_session_name() {
printf '__party_guest_%s\n' "$1" printf '__party_guest_%s\n' "$1"
} }
@ -419,7 +400,7 @@ guest_session_name() {
# __party_guest_$USER (and even group it to the party), so on a shared # __party_guest_$USER (and even group it to the party), so on a shared
# server no session name is unforgeable. We trust invitees by design, # server no session name is unforgeable. We trust invitees by design,
# that's the whole model. A read-only invitee (-r) can't create # that's the whole model. A read-only invitee (-r) can't create
# sessions, so it's not exposed. See README §Trust model. # sessions, so it's not exposed. See README §Security.
ensure_guest_session() { ensure_guest_session() {
_eg_sock="$1" _eg_host_sess="$2" _eg_sock="$1" _eg_host_sess="$2"
guest=$(guest_session_name "$USER") guest=$(guest_session_name "$USER")
@ -441,7 +422,7 @@ caller_present_on() {
# #
# The OS group is the perimeter, tmux's server-access allowlist is the # The OS group is the perimeter, tmux's server-access allowlist is the
# per-user filter. Both are universal across the supported platforms # per-user filter. Both are universal across the supported platforms
# (Linux, FreeBSD, NetBSD, OpenBSD, illumos, Solaris, macOS), so the # (Linux, FreeBSD, DragonFly, NetBSD, OpenBSD, illumos, Solaris, macOS), so the
# mechanism is one liner: chgrp + chmod. No ACL syscalls invoked. # mechanism is one liner: chgrp + chmod. No ACL syscalls invoked.
# #
# ACL-shadowing on filesystems with NFSv4-style extended ACLs (macOS # ACL-shadowing on filesystems with NFSv4-style extended ACLs (macOS
@ -470,7 +451,7 @@ caller_present_on() {
# ACLs that chmod 0750 can't override, document it in your deployment # ACLs that chmod 0750 can't override, document it in your deployment
# notes, server-access still keeps strangers out, but advertised # notes, server-access still keeps strangers out, but advertised
# group members may need ACL-level access to traverse PARTY_SOCKET_DIR. # group members may need ACL-level access to traverse PARTY_SOCKET_DIR.
# See README §Trust model for the user-facing version of this caveat. # See README §Security for the user-facing version of this caveat.
# WONTFIX, by design. # WONTFIX, by design.
apply_party_perms_file() { apply_party_perms_file() {
@ -923,9 +904,7 @@ EOF
trap - EXIT INT TERM HUP trap - EXIT INT TERM HUP
# Roster: chgrp only. roster_write already left mode 0640 (g+r, no g+w). # Roster: chgrp only. roster_write already left mode 0640 (g+r, no g+w).
# Guests read records to discover/join; only the host writes them. Keeping # Guests read records to discover/join; only the host writes them.
# them non-group-writable means a tampered SOCKET=... can't redirect
# cmd_close's destructive cleanup at peer-supplied paths.
chgrp "$TMUX_PARTY_GROUP" "$rec" chgrp "$TMUX_PARTY_GROUP" "$rec"
if [ -z "${TMUX:-}" ] && [ -t 1 ]; then if [ -z "${TMUX:-}" ] && [ -t 1 ]; then
@ -1309,9 +1288,8 @@ EOF
echo "$PARTY_TMUX -S $RR_SOCKET $*" echo "$PARTY_TMUX -S $RR_SOCKET $*"
return 0 return 0
fi fi
# exec with discrete, quoted args: the old flat-string + unquoted # exec with discrete, quoted args: a flat command string would
# `exec $attach_cmd` word-split on any whitespace in PARTY_TMUX or # word-split on whitespace in PARTY_TMUX or the socket path.
# the socket path.
exec "$PARTY_TMUX" -S "$RR_SOCKET" "$@" exec "$PARTY_TMUX" -S "$RR_SOCKET" "$@"
} }
@ -1586,9 +1564,9 @@ cmd_list() {
"$RR_HOST_USER" "$RR_PARTY_NAME" "$attendees" "$group_tag") "$RR_HOST_USER" "$RR_PARTY_NAME" "$attendees" "$group_tag")
else else
# Live server, connection refused: we can't count attendees # Live server, connection refused: we can't count attendees
# (list-clients is behind the auth gate: its empty stdout # (list-clients is behind the auth gate and would answer
# used to render here as a bogus "0 attendee(s)"), but the # with empty stdout, a bogus "0 attendee(s)"), but the party
# party is real and the caller can ask for an invite. # is real and the caller can ask for an invite.
line=$(printf '%-12s %-30s invite-only (ask %s)%s' \ line=$(printf '%-12s %-30s invite-only (ask %s)%s' \
"$RR_HOST_USER" "$RR_PARTY_NAME" "$RR_HOST_USER" "$group_tag") "$RR_HOST_USER" "$RR_PARTY_NAME" "$RR_HOST_USER" "$group_tag")
fi fi
@ -1704,8 +1682,6 @@ cmd_status() {
if [ -n "$joined" ]; then echo "joined: $joined"; fi if [ -n "$joined" ]; then echo "joined: $joined"; fi
} }
# Locate the party socket where the calling user has at least one
# attached client. Sets RR_* on success. Used by cmd_role.
cmd_role() { cmd_role() {
sub="${1:-}" sub="${1:-}"
case "$sub" in case "$sub" in
@ -1818,6 +1794,9 @@ dispatch() {
# Entrypoint # Entrypoint
# ========== # ==========
# Tests source this file with __PARTY_LIB_ONLY=1 to reach the helpers
# without triggering dispatch.
if [ "${__PARTY_LIB_ONLY:-0}" != "1" ]; then if [ "${__PARTY_LIB_ONLY:-0}" != "1" ]; then
dispatch "$@" dispatch "$@"
fi fi