Files
mars-dosutils/net.c
Mario Fetka 091dff6764 net: document multicall command dispatch
Add comments to net.c describing the NET multicall dispatch table and helper
flow.

Document how commands are resolved through NET <command> and renamed/stub-style
argv[0] invocation, how the mode field is used by shared handlers, and why
NCOPY is currently not registered in the dispatcher.

No behavior change.
2026-05-29 10:32:40 +02:00

225 lines
7.7 KiB
C

/*
* mars-nwe-dosutils - NetWare/DOS utility tools.
*
* Copyright (C) 2026 Mario Fetka
* Copyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* Purpose: NET multicall front-end and command dispatcher for the DOS utility collection.
* Depends on: net.h plus command modules such as login.c, map.c, flag.c, ndir.c, trustee.c, tools.c and netcall.c.
*/
#define VERS_DATE "21-May-96"
#include "net.h"
char *funcname=NULL;
char prgpath[65];
typedef int (*NET_FUNC)(int argc, char *argv[], int mode);
/*
* net_functions
*
* Purpose:
* Maps NET subcommands and stand-alone multicall executable names to their
* implementation function. The same binary can be invoked either as NET
* with the command name in argv[1], or through a renamed/stub executable
* where argv[0] already contains the command name.
*
* Fields:
* name - uppercase command or alias name used for dispatch.
* description - short text shown by the built-in usage listing.
* func - command implementation entry point.
* mode - small command-specific selector passed to shared handlers.
*
* Notes:
* NCOPY is intentionally kept out of this table while the NCP74
* server-side copy/open-handle path is still under investigation. Keeping
* ncopy.c in the build makes it compile-tested, but removing the table entry
* prevents accidental execution through NET/Multicall dispatch.
*/
static struct s_net_functions {
char *name;
char *description;
NET_FUNC func;
int mode;
} net_functions[] = {
{"SPAWN", "spawn program(command file)" , func_exec , 0},
{"EXEC", "execute program(command file)", func_exec , 1},
{"ECHO", "echoes string (command file)" , func_echo , 0},
{"CD", "change directory (command file)" , func_cwd , 0},
{"LOGIN", "login to server as user" , func_login , 0},
{"PROFILE","read command file" , func_profile, 0},
{"CAPTURE","list and redirect printers" , func_capture, 0},
{"ENDCAP", "cancel redirect printers" , func_capture, 1},
{"MAP", "list maps and map drives" , func_map , 0},
{"MAPDEL", "removes maps" , func_map , 1},
{"PATH", "list and set search path" , func_path , 0},
{"PATHDEL","removes search path" , func_path , 1},
{"PATHINS","insert search path" , func_path , 2},
{"LOGOUT", "logout from server", func_logout , 0},
{"FLAG", "display or modify file attributes", func_flag , 0},
{"FLAGDIR","display or modify directory attributes",func_flagdir, 0},
{"GRANT", "grant trustee rights", func_grant , 0},
{"REVOKE", "revoke trustee rights", func_revoke , 0},
{"REMOVE", "remove trustee", func_remove , 0},
{"NDIR", "list directory contents", func_ndir , 0},
{"RIGHTS", "display effective file/directory rights",func_rights, 0},
{"CREATOR","display or set creator/modifier/archive ids",func_creator,0},
{"SLIST", "list servers", func_slist , 0},
{"WHOAMI", "show current NetWare user", func_whoami , 0},
#if 0 /* NCOPY disabled: unsafe/open server-side-copy work-in-progress. */
{"NCOPY", "copy files", func_ncopy , 0},
#endif
{"PASSWD", "change password", func_passwd , 0},
#if 1
{"TESTS", "only testroutines!", func_tests , 0},
#endif
{"DEBUG", "set debug level, for mars_nwe only !", func_debug , 0}
};
#define MAX_FUNCS (sizeof(net_functions) / sizeof(struct s_net_functions))
/*
* get_entry_nr
*
* Purpose:
* Resolves a DOS program path or command token to an entry in the NET
* dispatch table. The basename is extracted, an optional extension is
* removed, and the result is uppercased before it is compared with the
* registered command names.
*
* Returns:
* The net_functions[] index on match, or -1 if the token is not registered.
*/
static int get_entry_nr(char *fstr)
{
int entry = MAX_FUNCS;
char buff[200];
char funcn[100];
char *pp;
strmaxcpy(buff, fstr, sizeof(buff)-1);
korrpath(buff);
get_path_fn(buff, NULL, funcn);
pp=strrchr(funcn, '.');
if (NULL != pp) *pp = '\0';
upstr(funcn);
while (entry--) {
if (!strcmp(funcn, net_functions[entry].name)) return(entry);
}
return(-1);
}
/*
* call_func_entry
*
* Purpose:
* Attempts to dispatch argv[0] to a registered NET command. This supports
* both stand-alone multicall-style invocations and the second pass from
* main(), where argv is shifted so that NET subcommands are dispatched as if
* they were executable names.
*
* Notes:
* Most commands require IPX/requester initialization before they run. MAP is
* allowed to run without a successful ipx_init() so it can report existing
* mapping state and requester-related errors in the traditional utility
* style.
*
* Returns:
* The command result, or -0xff when no matching command was found.
*/
int call_func_entry(int argc, char *argv[])
{
int funcmode;
int result = -1;
NET_FUNC func = NULL;
int entry = get_entry_nr(argv[0]);
if (entry > -1) {
func = net_functions[entry].func;
funcmode = net_functions[entry].mode;
funcname = net_functions[entry].name;
}
if (NULL != func) {
if (ipx_init() || func == func_map) {
result = (*func)(argc, argv, funcmode);
} else {
fprintf(stderr, "Cannot init IPX\n");
}
} else result = -0xff;
return(result);
}
/*
* get_path
*
* Purpose:
* Stores the directory part of argv[0] in the global prgpath buffer. Some
* command handlers use this to locate companion files or command scripts
* relative to the NET executable.
*/
static void get_path(char *path)
{
char buf[100];
strmaxcpy(buf, path, sizeof(buf)-1);
korrpath(buf);
get_path_fn(buf, prgpath, NULL);
}
/*
* main
*
* Purpose:
* NET multicall entry point. First try to dispatch by argv[0], which handles
* renamed/stub executables such as FLAG.EXE or NDIR.EXE. If that fails, try
* again with argv shifted by one so "NET FLAG ..." and similar command
* forms work through the same dispatch table.
*
* Returns:
* The selected command's return code. If no command matches, print the
* built-in usage list and return the not-found result.
*/
int main(int argc, char *argv[])
{
int result = -0xff;
get_path(argv[0]);
result = call_func_entry(argc, argv);
if (result == -0xff)
result = call_func_entry(argc-1, argv+1);
if (result == -0xff) {
int k= MAX_FUNCS;
char progname[256];
strmaxcpy(progname, argv[0], sizeof(progname)-1);
upstr(progname);
fprintf(stderr, "\n"
"* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *\n"
" Version: %s\n\n", VERS_DATE);
fprintf(stderr, "Usage:\t%s func ... \nfuncs:", progname);
while (k--) {
if (net_functions[k].func) {
fprintf(stderr, "\t%s\t: %s\n",
net_functions[k].name, net_functions[k].description);
}
}
}
return(result);
}