/* * 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 . */ /* * 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); }