From a24cc2d3efbe1d61efabc25be67b8a85b43ae2c9 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Mon, 1 Jun 2026 22:23:14 +0000 Subject: [PATCH] docs: track nwbind endpoint handoffs --- AI.md | 3 ++- TODO.md | 7 +++++++ src/nwbind.c | 19 +++++++++++++++++++ src/nwconn.c | 28 ++++++++++++++++++++++++++-- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/AI.md b/AI.md index d9e3218..0868aa3 100644 --- a/AI.md +++ b/AI.md @@ -31,7 +31,8 @@ use, the current project status that the user pasted into the chat. - The current endpoint documentation/audit pass is scoped to compatibility NCPs through NetWare 3.x by default, including NetWare 1.x/2.x legacy calls where they are documented. Bucket endpoints by the oldest NetWare generation that documents them: put 1.x/2.x legacy calls in their own sections, keep the remaining through-3.x compatibility calls in the 3.x/default section, and put endpoints introduced in NetWare 4.x or later in a separate planning/stub section. - NetWare 4.x/OES/MOAB-only endpoints are not part of the default implementation target. Already implemented compatibility code must not be removed or wrapped just because it is 4.x-era; only new, not-yet-implemented 4.x stubs should be placed behind `#if MARS_NWE_4`. `MARS_NWE_4` is currently hard-disabled in `include/config.h.cmake` and should stay `0` unless the user explicitly asks to start that work. -- When a `0x2222` group is forwarded out of `nwconn.c`, document both layers: `nwconn.c` should explain the group handoff/header, and the destination file (for example `nwbind.c`) should document concrete subfunction request/reply layouts. +- When a `0x2222` group or subfunction is forwarded out of `nwconn.c`, follow the handoff before declaring the endpoint documented. `nwconn.c` should document the handoff and the exact header/payload bytes that are preserved or rewritten before forwarding; the destination file (for example `nwbind.c`) must document the concrete subfunction request/reply layout at the real handler. Do not stop at a comment such as `nwbind must do prehandling`, `nwbind must do the rest`, or `handled by nwbind`. +- For forwarded paths, document any nwconn-side payload mutation as part of the audit. Examples in the current tree include queue create path expansion, queue job file-handle insertion, quota bindery prehandling, and semaphore/message group forwarding. If a forwarded subfunction is not audited yet, record it as a target-file follow-up rather than only documenting the nwconn dispatcher. - For documentation-only endpoint patches, do not change parser offsets, byte order, reply layout, or completion behavior. Always compare the code parser/reply layout against the applicable SDK/WebSDK/PDF request format and, when available, the uploaded SDK include prototypes. If the code differs from the SDK layout, document the concrete difference inline and mirror it in `TODO.md` for later testing. If it matches, say so in the patch summary so the audit trail is clear. - When an SDK/WebSDK/PDF endpoint number is written in decimal notation, convert it carefully to the wire `case` value before adding inline documentation. Example: Directory Services `0x2222/22/12` in the PDF means SubFunctionCode decimal 12, i.e. wire `case 0x0c`; it is not the existing `case 0x12` / decimal 18 Allocate Permanent Directory Handle. Place disabled stubs directly at the correct numeric slot inside the dispatcher, never appended at the end of the function. - In `TODO.md` and endpoint summaries, avoid ambiguous mixed notation for grouped subfunctions. Write SDK/PDF numbers as decimal and include the wire byte explicitly when it differs or could be confused, for example `SDK 22/18 / wire 0x12` or `SDK 22/12 / wire 0x0c`. Do not write `22/12` for a wire `case 0x12` unless the SDK number is actually decimal 12. diff --git a/TODO.md b/TODO.md index b01139b..91f4ea1 100644 --- a/TODO.md +++ b/TODO.md @@ -88,6 +88,13 @@ Follow-up: visible outside the source code. - Do not treat every `return(-1)` in `nwconn.c` as incomplete: many of those paths intentionally forward bindery/global-server work to `nwbind`. +- When an endpoint returns to `nwbind`, keep the audit paired: the dispatcher + comment in `nwconn.c` should name the handoff, and the concrete parser in + `nwbind.c` should carry the request/reply layout. This was rechecked for + the currently documented forwarded paths: message group `0x2222/21`, quota + prehandling in Directory Services `0x2222/22`, File Server Environment + `0x2222/23`, End of Job `0x2222/24`, Logout `0x2222/25`, and Semaphore + `0x2222/32`. ### NCP endpoint layout audit (version-bucketed compatibility) diff --git a/src/nwbind.c b/src/nwbind.c index faec892..b463d61 100644 --- a/src/nwbind.c +++ b/src/nwbind.c @@ -802,6 +802,16 @@ static void handle_fxx(int gelen, int func) default : completition=0xfb; /* not handled */ } } else if (0x17 == func) { /* Fileserver Enviro */ + /* + * NCP 0x2222/23 File Server Environment forwarded from nwconn.c. + * handle_fxx() consumes the standard grouped header before this switch: + * requestdata[0..1] SubFuncStrucLen + * requestdata[2] SubFunctionCode + * rdata payload after SubFunctionCode + * Several queue subfunctions are preprocessed by nwconn before they reach + * this handler, so endpoint audits must include both the nwconn mutation + * and the final nwbind parser below. + */ switch (ufunc) { case 0x01 : { /* Change User Password OLD */ completition=0xff; @@ -2067,14 +2077,23 @@ static void handle_fxx(int gelen, int func) break; } /* switch */ } else if (func == 0x18) { /* End of Job */ + /* Forwarded direct NCP 0x2222/24 cleanup after nwconn releases local handles. */ if (!(entry8_flags&0x200)) /* pcz: 14-Apr-00 */ nw_close_connection_jobs(act_connection, ncprequest->task); /* close print jobs */ } else if (func == 0x19) { /* logout */ + /* Forwarded direct NCP 0x2222/25 logout cleanup after nwconn resets connection state. */ nw_close_connection_jobs(act_connection, -1); /* close all print jobs */ write_utmp(0, act_connection, act_c->pid_nwconn, &(act_c->client_adr), NULL); act_c->object_id = 0; /* not LOGIN */ act_c->id_flags = 0; /* no flags */ } else if (0x20 == func) { /* Semaphore */ + /* + * NCP 0x2222/32 Semaphore forwarded from nwconn.c. + * This group is parsed differently from 0x15/0x16/0x17: + * ufunc = requestdata[0] + * rdata = requestdata + 1 + * handle_func_0x20() owns the concrete semaphore subfunction layouts. + */ int result = handle_func_0x20(act_c, rdata, ufunc, responsedata); if (result > -1) data_len = result; else completition=(uint8)-result; diff --git a/src/nwconn.c b/src/nwconn.c index 588cf78..e49ba4f 100644 --- a/src/nwconn.c +++ b/src/nwconn.c @@ -5182,8 +5182,11 @@ static int handle_ncp_serv(void) * This block only documents the file-information subfunctions * handled locally here. Several login, bindery, queue, and * management subfunctions in this group are intentionally forwarded - * to nwbind or to existing queue prehandlers and should be audited - * in the target file when their turn comes. + * to nwbind or to existing queue prehandlers. When auditing one of + * those calls, follow the return(-1)/return(-2) path into + * src/nwbind.c and document the concrete request/reply layout at the + * real handler too; some queue paths are also rewritten here before + * forwarding. */ /* uint8 len = *(requestdata+1); */ uint8 ufunc = *(requestdata+2); @@ -5531,6 +5534,13 @@ static int handle_ncp_serv(void) break; case 0x18 : /* End of Job */ + /* + * Direct NCP 0x2222/24 End of Job has no nested payload. + * nwconn releases local file/task handles first, then + * forwards to nwbind so the bindery/queue side can close + * print jobs for this task. Document further behavior in + * nwbind.c if this endpoint is audited later. + */ if (!(entry8_flags&0x200)) /* pcz: 14-Apr-00 */ free_connection_task_jobs(ncprequest->task); nw_free_handles(ncprequest->task); @@ -5538,6 +5548,12 @@ static int handle_ncp_serv(void) break; case 0x19 : /* logout, some of this call is handled in ncpserv. */ + /* + * Direct NCP 0x2222/25 Logout has no nested payload. The + * connection state is cleared here and nwbind performs the + * remaining bindery/queue logout cleanup, so endpoint docs + * must cover both sides when this call is audited. + */ free_queue_jobs(); nw_free_handles(-1); set_nw_user(-1, -1, @@ -5683,6 +5699,14 @@ static int handle_ncp_serv(void) break; case 0x20 : /* Semaphore */ + /* + * Direct NCP 0x2222/32 is the Semaphore group. Unlike the + * 0x15/0x16/0x17 grouped calls, nwbind consumes a one-byte + * semaphore subfunction directly from requestdata[0] and + * passes requestdata[1..] as that subfunction's payload. + * Follow src/nwbind.c handle_fxx(func == 0x20) and + * handle_func_0x20() for concrete endpoint layout docs. + */ return(-1); /* handled by nwbind */ case 0x21 : { /* Negotiate Buffer Size, Packetsize */