# mars_dosutils

DOS client-side utilities for **mars_nwe** and compatible NetWare-style NCP environments.

This repository contains the source for a small DOS utility suite built around a **single multi-call executable**, `net.exe`. The program can be used either as:

- `net <command> [args...]`, or
- a renamed executable such as `login.exe`, `map.exe`, `flag.exe`, `flagdir.exe`, `rights.exe`, `grant.exe`, `revoke.exe`, `remove.exe`, `capture.exe`, or `logout.exe`.

The command dispatcher lives in `net.c`, and the install rules deploy the same binary under multiple command names in `SYS:PUBLIC` and selected names in `SYS:LOGIN`.

## Current status

The tree is a modernization of the historical mars_nwe DOS utilities. It still
keeps the original Borland-era style and APIs where useful, but now also has an
Open Watcom/CMake build path and working DOS Client32 support for the
Novell-compatible comparison tests.

Recently validated with byte-for-byte Novell comparison tests or equivalent
readback tests:

- `CREATOR` metadata/xattr readback, including readable attribute and rights-mask output
- `FLAG` file attribute display and modification, including high NetWare bits such as DI/RI
- `FLAGDIR` directory attribute display and modification
- `GRANT` trustee assignment matrix and normal-user rights readback
- `NDIR` directory listing, filters, `/DATES`, `/RIGHTS`, `/SUB`, DI/RI display and user-context readback
- `REMOVE` trustee deletion matrix and normal-user rights readback
- `REVOKE` trustee-right removal matrix and normal-user rights readback
- `RIGHTS` effective-rights display
- `SLIST` server listing while logged in and while logged out from `SYS:LOGIN`
- `WHOAMI` option/output comparison
- maintainer baseline for `LOGIN`/`LOGOUT`

The DOS test suite is documented in [`test/README.md`](test/README.md).  Each
feature directory also contains its own README with run instructions and result
layout.

Still to validate or continue:

- full `PUBLIC\MAP` comparison against Novell `MAP` beyond the current MAP baseline/semantics test
- DOSX/VLM/NETX fallback behavior where relevant
- OS/2 requester/tool behavior
- additional Novell-like utilities such as `PURGE` and `SALVAGE`
- further MARS-NWE server-side NCP endpoint coverage where newer tests expose gaps

## Features

- Login and logout against an NCP server
- Password change support
- DOS drive mapping and unmapping
- Search-path management (`PATH`, `PATHINS`, `PATHDEL`)
- Printer capture and release (`CAPTURE`, `ENDCAP`)
- Scripted session setup through command files
- External program execution via `SPAWN` and `EXEC`
- Server listing through `SLIST`
- Directory listing through `NDIR`
- File attribute management through `FLAG`
- Directory attribute management through `FLAGDIR`
- Effective rights display through `RIGHTS`
- Trustee rights assignment through `GRANT`
- Trustee rights removal through `REVOKE`
- Trustee assignment deletion through `REMOVE`
- Optional mars_nwe debug control hooks
- Developer diagnostics through `TESTS`

## Available commands

The current command dispatcher includes these built-ins:

- `LOGIN`
- `LOGOUT`
- `PASSWD`
- `PROFILE`
- `SPAWN`
- `EXEC`
- `MAP`
- `MAPDEL`
- `PATH`
- `PATHINS`
- `PATHDEL`
- `CAPTURE`
- `ENDCAP`
- `SLIST`
- `NDIR`
- `FLAG`
- `FLAGDIR`
- `RIGHTS`
- `GRANT`
- `REVOKE`
- `REMOVE`
- `DEBUG`
- `ECHO`
- `CD`
- `TESTS` developer/testing only

The CMake install rules also install the multi-call `net.exe` under several of those command names.

## How it works

The program resolves the command from either:

1. the executable name itself, or
2. the first command-line argument.

That means all of the following styles are valid:

```text
NET LOGIN alice secret
NET MAP F:=SYS:
NET FLAG LOGIN.EXE
LOGIN.EXE alice secret
MAP.EXE F:=SYS:
FLAG.EXE LOGIN.EXE A
CAPTURE.EXE LPT1 Q1
```

## NCP requester and API layers

The modern NCP support is split into small layers so protocol code and
requester transport code stay separate:

- `ncpapi.c` / `ncpapi.h` contain the named `ncpXX_YY_*` protocol API wrappers.
- `ncpcall.c` contains lower-level requester and Client32 transport helpers.
- `ncp.asm` / `ncp.h` provide the INT 21h `Net_Call` and Client32 requester entry points.
- `ipx.asm` / `ipx.h` provide the remaining IPX socket and far-memory assembly glue.

The validated Client32 sequence is:

```text
ncp_mapvar_request(4,0)
  -> obtains the active connection reference

ncp_openref_request()
  -> opens that reference and returns a Client32 handle

ncp_raw_request()
  -> sends NCP 87 requests through COMPATNcpRequestReply
```

This path is currently used by:

- `FLAG`
- `FLAGDIR`
- `RIGHTS`
- `GRANT`
- `REVOKE`
- `REMOVE`

The old `Net_Call` / INT 21h requester path is kept as a fallback where appropriate, but Client32-backed raw NCP requests are now preferred for the validated FLAG-family and trustee operations.

## Command reference

### `LOGIN`

Authenticate to an NCP server as a user.

```text
LOGIN [-u] [user | user password]
```

- `-u` forces the older unencrypted login path.
- If no username is provided, the tool prompts interactively.
- If no password is provided, it prompts for one after the username.
- Successful login clears and rebuilds NetWare search-path state before running a local post-login script named `login` from the executable directory.

### `LOGOUT`

Log out from the current NCP session.

The implementation also removes configured network search paths before performing logout.

### `PASSWD`

Change a user password.

```text
PASSWD [user]
```

If no username is supplied, the tool attempts to resolve the currently logged-in user. The password-change code prefers the encrypted/keyed flow where available and keeps older unencrypted calls as fallback.

### `PROFILE`

Execute a command script.

```text
PROFILE <filename>
```

The command reader parses non-empty lines, ignores `#` comments, uppercases the command token, and dispatches it through the same internal command table used for direct invocation. `ECHO` is treated specially so the rest of the line is preserved as a single string.

### `SPAWN`

Run an external program and wait for it to finish.

### `EXEC`

Execute an external program using overlay-style execution.

Both commands share the same implementation and differ only in whether they use `spawnvp(..., P_WAIT, ...)` or `execvp(...)`.

### `MAP`

List current drive mappings or map a DOS drive letter to a network path.

```text
MAP [d:[=[path]]]
```

Examples:

```text
MAP
MAP F:=SYS:
MAP H:=HOME:
```

The implementation lists active mappings, distinguishes local vs. redirected drives, and uses DOS-style drive letters.

### `MAPDEL`

Remove an existing drive mapping.

```text
MAPDEL d:
```

Example:

```text
MAPDEL F:
```

### `PATH`

List or set a search-path entry.

```text
PATH sn:[=[path]]
```

Where `sn` is `s1` through `s16`.

### `PATHINS`

Insert a search-path entry instead of overwriting one.

```text
PATHINS sn:[=[path]]
```

### `PATHDEL`

Delete a search-path entry.

```text
PATHDEL sn:
```

### `CAPTURE`

List printer captures or redirect a local printer device to a queue.

Typical usage:

```text
CAPTURE [device [queue]]
```

Examples:

```text
CAPTURE
CAPTURE LPT1 Q1
CAPTURE PRN Q1
```

`PRN` is normalized to `LPT1` internally. The command can also display existing captures.

### `ENDCAP`

Cancel a printer redirection.

Typical usage:

```text
ENDCAP device
```

Example:

```text
ENDCAP LPT1
```

### `SLIST`

List known NetWare file servers.

Typical usage:

```text
SLIST [server] [/Continue]
```

The current `slist.c` implementation scans bindery file server objects and prints known servers.

### `FLAG`

Display or modify NetWare DOS file attributes.

Typical usage:

```text
FLAG file [option...]
```

Examples:

```text
FLAG LOGIN.EXE
FLAG LOGIN.EXE A
FLAG LOGIN.EXE -A
FLAG LOGIN.EXE P T DI RI CI RA WA
FLAG LOGIN.EXE N
FLAG LOGIN.EXE ALL
FLAG LOGIN.EXE RO
FLAG LOGIN.EXE RW
```

Supported attributes and aliases include:

- `RO`
- `RW`
- `S`
- `A`
- `H`
- `SY`, `SYS`, `SYSTEM`
- `T`
- `P`
- `RA`
- `WA`
- `CI`
- `DI`
- `RI`
- `ALL`
- `N` / `NORMAL`

The output is intentionally close to Novell FLAG formatting:

```text
Ro/Rw S/- A/- - H/- Sy/-- T/- P/- Ra/-- Wa/-- CI/-- DI/-- RI/--
```

The Client32 path handles both low and high NetWare attribute bits. High bits such as `P`, `DI`, `RI`, `CI`, `RA`, and `WA` must be handled as 32-bit values in 16-bit DOS builds.

### `FLAGDIR`

Display or modify NetWare directory attributes.

Typical usage:

```text
FLAGDIR [path [option...]]
```

Supported 386-style options:

- `Normal`
- `System`
- `Hidden`
- `DeleteInhibit`
- `Purge`
- `RenameInhibit`

Examples:

```text
FLAGDIR UDIR
FLAGDIR UDIR SYSTEM
FLAGDIR UDIR HIDDEN
FLAGDIR UDIR DELETEINHIBIT
FLAGDIR UDIR PURGE
FLAGDIR UDIR RENAMEINHIBIT
FLAGDIR UDIR NORMAL
```

For simple mapped paths, the display is kept close to Novell FLAGDIR style:

```text
MARS/SYS:UDIR
        UDIR        System Hidden DeleteInhibit Purge RenameInhibit
```

`Private` is intentionally rejected for the current NetWare 386-style path.


### `RIGHTS`

Display effective NetWare rights for a file or directory.

Typical usage:

```text
RIGHTS [path]
```

Supported:

- directory paths
- file paths
- Novell-like display of the effective rights mask

Rights are shown in the traditional order:

```text
S R W C E M F A
Supervisor, Read, Write, Create, Erase, Modify, File scan, Access Control
```


### `GRANT`

Assign explicit trustee rights to a user or group.

Typical usage:

```text
GRANT rightslist* [FOR path] TO [USER | GROUP] name [options]
Options:  /SubDirectories | /Files
```

Examples:

```text
GRANT R W C FOR UDIR TO USER MARIO
GRANT ALL FOR UDIR TO GROUP EVERYONE /SUBDIRECTORIES
GRANT R F FOR UDIR\*.TST TO USER MARIO /FILES
```

Supported 386-style rights:

- `ALL`
- `N` / `NONE`
- `S` / `SUPERVISOR`
- `R` / `READ`
- `W` / `WRITE`
- `C` / `CREATE`
- `E` / `ERASE`
- `M` / `MODIFY`
- `F` / `FILESCAN`
- `A` / `ACCESS CONTROL`

For Novell compatibility, `ALL` grants the normal trustee rights (`RWCEMFA`) and does not imply Supervisor; use `S` explicitly when Supervisor rights are intended.

### `REVOKE`

Remove selected rights from an explicit trustee assignment.

Typical usage:

```text
REVOKE rightslist* [FOR path] FROM [USER|GROUP] name [options]
Options:  /SubDirectories | /Files
```

Examples:

```text
REVOKE W M FOR UDIR FROM USER MARIO
REVOKE R W FOR UDIR\*.TST FROM GROUP EVERYONE /FILES
REVOKE W C FOR UDIR FROM USER MARIO /SUBDIRECTORIES
```

`REVOKE` scans the explicit trustee assignment first, subtracts the requested rights, and deletes the trustee entry when no rights remain. Missing trustee entries are reported in Novell style:

```text
No trustee for the specified directory.
No trustee for the specified file.
```

### `REMOVE`

Delete an explicit trustee assignment for a user or group.

Typical usage:

```text
REMOVE [USER | GROUP] name [FROM path] [option]
Options:  /Subdirs | /Files
```

Examples:

```text
REMOVE USER MARIO FROM UDIR
REMOVE GROUP EVERYONE FROM UDIR /SUBDIRS
REMOVE USER MARIO FROM UDIR\*.TST /FILES
```

If `USER` or `GROUP` is omitted, the tool tries to resolve the name as a user first and then as a group. Successful multi-object operations print Novell-style summaries such as:

```text
Trustee "MARIO" removed from 4 directories.
Trustee "MARIO" removed from 2 files.
```



### `NDIR`

List files and directories in a NetWare-style format.

Typical usage:

```text
NDIR [path] [/option...]
```

The implementation supports basic DOS namespace listings, wildcards,
paging, first rights and dates displays, and these options:

- `/FO` or `FO` for files only
- `/DO` or `DO` for directories only
- `/CONTINUOUS`, `/CONTINUE`, or `/C` for continuous output
- `/RIGHTS` for a first effective-rights display
- `/DATES` for Novell-style date columns with current DOS timestamp data
- `/SUB` or `/SUBDIRECTORIES` for recursive directory listings
- `/SHORT` or `/BRIEF` for compact output, useful with `/SUB`
- `/HELP` for Novell-style usage text

Examples:

```text
NDIR
NDIR *.EXE
NDIR PUBLIC\*.EXE
NDIR PUBLIC /DO
NDIR PUBLIC\*.EXE /FO /CONTINUOUS
NDIR PUBLIC /RIGHTS
NDIR PUBLIC /DATES
NDIR PUBLIC /SUB
NDIR PUBLIC /SUB /SHORT
NDIR PUBLIC /DO
```

The first version intentionally focuses on the common listing path.  More
advanced Novell NDIR features such as sorting and restrictions are accepted
only as future compatibility points or will be implemented in later revisions.  The `/RIGHTS` display uses NCP87 information for inherited rights and
Client32 effective-rights calls for effective rights.  The `/DATES` display
uses NCP87 DOS info fields when available and falls back to DOS findfirst
timestamps otherwise.


### `DEBUG`

Set mars_nwe debug levels for selected server-side modules.

```text
DEBUG NCPSERV|NWCONN|NWBIND level
```

- `level` must be between `0` and `99`.
- This requires the matching mars_nwe server-side debug call to be enabled.

### `ECHO`

Print a string, mainly for use inside profile/login scripts.

### `CD`

Change the current DOS directory. It also adjusts the active drive if a drive-qualified path is supplied.

### `TESTS`

Internal developer test routines. Not intended as a regular end-user command.

The currently useful Client32 test is:

```text
TESTS NCP87C32ATTR
```

It verifies the working Client32 NCP87 attribute path.

## Login script workflow

A particularly important feature is the automatic execution of a file named `login` located beside the executable after a successful login.

Example:

```text
map     f:=SYS:
map     h:=home:
map     z:=SYS:PUBLIC
path    s16:=z:.
capture lpt1 q1
profile h:\profile
```

This makes the tool suite useful not just for authentication, but for setting up a full DOS network session: drive mappings, search paths, printer capture, and then a user-specific profile script.

## Building

### Historical DOS build

The included `makefile.bcc` is the primary historical build file and targets Borland C / Borland tools on DOS.

Key settings from the makefile:

- compiler: `bcc`
- linker: `bcc`
- assembler: `tasm`
- memory model: `-ml`
- define: `-Dmsdos`
- output: `net.exe`

The historical object list includes the original C sources plus `kern.asm`.

### CMake / Open Watcom maintainer build

The modern CMake build can rebuild `net.exe` with Open Watcom v2 on Linux.

Configure with:

```bash
cmake -S . -B build -DMARS_NWE_BUILD_DOSUTILS=ON
cmake --build build
```

The CMake build:

- assembles `ipx.asm` and `ncp.asm` with `wasm`
- compiles each C file to a binary-directory `.obj`
- links `net.exe` from those binary-directory objects
- keeps `.obj`/`.o` intermediate files out of the source directory

If old object files were produced in the source tree by an earlier build, remove them once:

```bash
cd dosutils
rm -f *.o *.obj
```

### Default install behavior

When `MARS_NWE_BUILD_DOSUTILS` is disabled, CMake installs a prebuilt `net.exe` from the source tree.

That keeps the normal mars_nwe build independent from Open Watcom. Maintainers can enable the Open Watcom build only when they want to regenerate the DOS binary.

## Installation layout

The install rules deploy the same binary multiple times into `SYS/public`, including:

- `net.exe`
- `login.exe`
- `profile.exe`
- `spawn.exe`
- `passwd.exe`
- `path.exe`
- `pathins.exe`
- `pathdel.exe`
- `map.exe`
- `mapdel.exe`
- `logout.exe`
- `slist.exe`
- `ndir.exe`
- `flag.exe`
- `flagdir.exe`
- `rights.exe`
- `grant.exe`
- `revoke.exe`
- `remove.exe`
- `capture.exe`
- `endcap.exe`

They also install selected copies such as `login.exe`, `map.exe`, and `slist.exe` into `SYS/login` where appropriate.

## Development notes

- `ipx.asm`/`ipx.h` provide the split 16-bit Open Watcom IPX and far-memory assembly glue.
- `ncp.asm`/`ncp.h` provide the split 16-bit Open Watcom requester assembly entry points.
- `ncpcall.c` contains low-level NCP requester/transport helpers.
- `ncpapi.c`/`ncpapi.h` contain reusable `ncpXX_YY_*` protocol API wrappers for DOS tools.
- `trustee.c` and `trustee.h` contain shared Rights/Trustee code for `GRANT`, `REVOKE`, and `REMOVE`.
- `tools.c` contains shared command/frontend helpers so future smaller multicall binaries can reuse common parsing and path code.
- The verified Client32 path uses NCP 87 subfunction 6 for obtaining DOS information, subfunction 7 for modifying DOS information, subfunction 29 for effective rights, and trustee scan/add/delete calls for the trustee tools.
- For modify operations, use the modify information mask `DM_ATTRIBUTES` (`0x00000002`) rather than the read-side `RIM_ATTRIBUTES` mask.
- High NetWare attributes must be stored and displayed as 32-bit values even in 16-bit DOS builds.

## Project status and limitations

This is legacy DOS networking code from the mid-1990s, and a few caveats are worth keeping in mind:

- The code is tightly coupled to DOS, IPX/NCP behavior, and mars_nwe/NetWare requester semantics.
- Client32 support has been validated for the FLAG-family and trustee/right tools, but not yet generalized to every command.
- DOSX/VLM/NETX fallback testing is still pending.
- `FLAGDIR` currently focuses on the NetWare 386-style attributes and simple mapped directory paths.
- OS/2 requester behavior is still future work.
- Some authentication and password-change paths still keep older calls as compatibility fallbacks.
- `NCOPY` is still built so it stays compile-tested, but it is intentionally not registered in the `NET` multicall dispatcher while the NCP87/OpenCreate -> NCP74 server-side copy path remains under investigation.

## Historical metadata

From the included project metadata:

- project: `mars_dosutils`
- version: `0.10`
- entered: `21-May-96`
- keywords: `mars_nwe`, `dos`, `dosemu`
- platforms: `DOS`, `DOSEMU`
- author/maintainer: Martin Stover

## License

The source tree includes a root-level `COPYING` file with the GPL-2 license text. Source files carry GPL-2-or-later headers and preserve the original Martin Stover attribution for the historical mars_nwe utility code, with current maintenance attribution where appropriate.


Debug/test helpers:

```
TESTS EFFRIGHT path
```

Prints the effective-rights values returned by several Client32/NCP paths for comparison with Novell RIGHTS.

`TESTS EFFRIGHT path` also prints exploratory old NCP22 effective-rights call variants for comparing with Novell RIGHTS.

`TESTS EFFRIGHT path` additionally tests NCP22 subfunction 50 object effective rights using the current login object id.
